Package org.apache.felix.eventadmin.perftests

Source Code of org.apache.felix.eventadmin.perftests.PerformanceTestIT

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.felix.eventadmin.perftests;

import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.CoreOptions;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.options.AbstractDelegateProvisionOption;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import static org.ops4j.pax.exam.Constants.START_LEVEL_SYSTEM_BUNDLES;
import static org.ops4j.pax.exam.CoreOptions.*;

@RunWith(PaxExam.class)
public class PerformanceTestIT {
    // the name of the system property providing the bundle file to be installed and tested
    private static final String BUNDLE_JAR_SYS_PROP = "project.bundle.file";

    /** The logger. */
    protected static final Logger logger = LoggerFactory.getLogger(PerformanceTestIT.class);
    private static final int RUNS = 5;
    public static final int BATCH_SIZE = 500000;

    @Inject
    protected BundleContext bundleContext;

    /** Event admin reference. */
    private ServiceReference eventAdminReference;

    /** Event admin. */
    private EventAdmin eventAdmin;

    final AtomicLong counter = new AtomicLong();

    Collection<Listener> listeners = new ArrayList<Listener>();

    @Configuration
    public static Option[] configuration() {
        final String bundleFileName = System.getProperty( BUNDLE_JAR_SYS_PROP );
        logger.info("Bundle jar at :"+bundleFileName);
        final File bundleFile = new File( bundleFileName );
        if ( !bundleFile.canRead() ) {
            throw new IllegalArgumentException( "Cannot read from bundle file " + bundleFileName + " specified in the "
                    + BUNDLE_JAR_SYS_PROP + " system property" );
        }
        return options(
                vmOption("-Xms1024m"),
//                vmOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"),
                provision(
                        mavenBundle( "org.ops4j.pax.tinybundles", "tinybundles", "1.0.0" ),
                        mavenBundle("org.apache.sling", "org.apache.sling.commons.log", "2.1.2"),
                        mavenBundle("org.apache.felix", "org.apache.felix.configadmin", "1.2.8"),
                        mavenBundle("org.apache.felix", "org.apache.felix.metatype", "1.0.4"),
                        CoreOptions.bundle(bundleFile.toURI().toString()),
                        mavenBundle("org.ops4j.pax.url", "pax-url-mvn", "1.3.5")
                ),
                // below is instead of normal Pax Exam junitBundles() to deal
                // with build server issue
                new DirectURLJUnitBundlesOption(),
                systemProperty("pax.exam.invoker").value("junit"),
                bundle("link:classpath:META-INF/links/org.ops4j.pax.exam.invoker.junit.link")
        );
    }

    protected EventAdmin loadEventAdmin() {
        if ( eventAdminReference == null || eventAdminReference.getBundle() == null ) {
            eventAdmin = null;
            eventAdminReference = bundleContext.getServiceReference(EventAdmin.class.getName());
        }
        if ( eventAdmin == null && eventAdminReference != null ) {
            eventAdmin = (EventAdmin) bundleContext.getService(eventAdminReference);
        }
        return eventAdmin;
    }

    public void addListener(Listener listener, String... topics) {
        listener.register(bundleContext,topics);
        listeners.add(listener);
    }

    private void removeListener(Listener listener) {
        listener.unregister();
    }


    protected void send(String topic, Dictionary<String, Object> properties, boolean sync) {
        final Event event = new Event(topic, properties);
        if ( sync ) {
            eventAdmin.sendEvent(event);
        } else {
            eventAdmin.postEvent(event);
        }
    }


    @Test
    public void measureThroughputSend() {
        loadEventAdmin();
        addListener(new Listener() {
            @Override
            public void handleEvent(Event event) {
                long calledTimes = counter.incrementAndGet();
                if (calledTimes == BATCH_SIZE ) {
                    synchronized (counter) {
                        counter.notify();
                    }
                }

            }
        }, "topic");

        // Warm-up
        Hashtable<String, Object> properties = new Hashtable<String, Object>();
        for (int i= 0;i < BATCH_SIZE;i++) {
            properties.put("key",i);
            send("topic", properties, false);
        }
        int average =0;
        for (int runs = 0; runs < RUNS;runs ++) {

            final CountDownLatch latch = new CountDownLatch(BATCH_SIZE);
            addListener(new Listener() {
                @Override
                public void handleEvent(Event event) {
                    latch.countDown();
                }
            }, "topic" + runs);

            ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(BATCH_SIZE+1);
            ThreadPoolExecutor executor = new ThreadPoolExecutor(1,
                    1,
                    1000,
                    TimeUnit.MILLISECONDS, workQueue);


            for (int i = 0; i < BATCH_SIZE; i++) {
                final String topicString = "topic"+runs;
                final Hashtable<String,Object> localProperties = new Hashtable<String, Object>();
                localProperties.put(topicString,i);
                workQueue.add(new Runnable() {
                    @Override
                    public void run() {
                        send(topicString, localProperties, true);
                    }
                });
            }

            long startTime = System.nanoTime();
            executor.prestartAllCoreThreads();

            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long endTime = System.nanoTime();
            long milliseconds = (endTime - startTime) / 1000000;
            logger.info("Post Run "+runs+" Elapsed :" + milliseconds);
            average += milliseconds;
        }

        logger.info("Send Avg: "+average / RUNS);
    }

    @Test
    public void measureThroughputPost() {
        loadEventAdmin();
        addListener(new Listener() {
            @Override
            public void handleEvent(Event event) {
                long calledTimes = counter.incrementAndGet();
                if (calledTimes == BATCH_SIZE ) {
                    synchronized (counter) {
                        counter.notify();
                    }
                }

            }
        }, "topic");

        // Warm-up
        Hashtable<String, Object> properties = new Hashtable<String, Object>();
        for (int i= 0;i < BATCH_SIZE;i++) {
            properties.put("key",i);
            send("topic", properties, false);
        }
        int average =0;
        for (int runs = 0; runs < RUNS;runs ++) {

            final CountDownLatch latch = new CountDownLatch(BATCH_SIZE);
            addListener(new Listener() {
                @Override
                public void handleEvent(Event event) {
                    latch.countDown();
                }
            }, "topic" + runs);

            ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(BATCH_SIZE+1);
            ThreadPoolExecutor executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
                    Runtime.getRuntime().availableProcessors(),
                    1000,
                    TimeUnit.MILLISECONDS, workQueue);


            for (int i = 0; i < BATCH_SIZE; i++) {
                final String topicString = "topic"+runs;
                final Hashtable<String,Object> localProperties = new Hashtable<String, Object>();
                localProperties.put(topicString,i);
                workQueue.add(new Runnable() {
                    @Override
                    public void run() {
                        send(topicString, localProperties, false);
                    }
                });
            }

            long startTime = System.nanoTime();
            executor.prestartAllCoreThreads();

            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long endTime = System.nanoTime();
            long milliseconds = (endTime - startTime) / 1000000;
            logger.info("Post Run "+runs+" Elapsed :" + milliseconds);
            average += milliseconds;
        }

        logger.info("Post Avg: "+average / RUNS);
    }

    @After
    public void tearDown() {
        for (Listener listener : listeners) {
            removeListener(listener);
        }
    }



    private static abstract class Listener implements EventHandler {
        private ServiceRegistration registration;

        protected Listener() {
        }

        public void register(BundleContext bundleContext, String...topics) {
            final Dictionary<String, Object> props = new Hashtable<String, Object>();
            if ( topics != null ) {
                props.put("event.topics", topics);
            } else {
                props.put("event.topics", "*");
            }
            this.registration = bundleContext.registerService(EventHandler.class.getName(), this, props);
        }

        public void unregister() {
            registration.unregister();
        }
    }


    private static class DirectURLJUnitBundlesOption
            extends AbstractDelegateProvisionOption<DirectURLJUnitBundlesOption> {

        /**
         * Constructor.
         */
        public DirectURLJUnitBundlesOption(){
            super(
                    bundle("http://repository.springsource.com/ivy/bundles/external/org.junit/com.springsource.org.junit/4.9.0/com.springsource.org.junit-4.9.0.jar")
            );
            noUpdate();
            startLevel(START_LEVEL_SYSTEM_BUNDLES);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public String toString() {
            return String.format("DirectURLJUnitBundlesOption{url=%s}", getURL());
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected DirectURLJUnitBundlesOption itself() {
            return this;
        }

    }
}
TOP

Related Classes of org.apache.felix.eventadmin.perftests.PerformanceTestIT

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.