Package org.apache.jackrabbit.oak.benchmark

Source Code of org.apache.jackrabbit.oak.benchmark.AbstractTest

/*
* 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.jackrabbit.oak.benchmark;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import javax.jcr.Credentials;
import javax.jcr.GuestCredentials;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;

import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
import org.apache.jackrabbit.oak.benchmark.util.Profiler;
import org.apache.jackrabbit.oak.fixture.RepositoryFixture;

/**
* Abstract base class for individual performance benchmarks.
*/
abstract class AbstractTest extends Benchmark {

    /**
     * A random string to guarantee concurrently running tests don't overwrite
     * each others changes (for example in a cluster).
     * <p>
     * The probability of duplicates, for 50 concurrent processes, is less than
     * 1 in 1 million.
     */
    static final String TEST_ID = Integer.toHexString(new Random().nextInt());
   
    private static final Credentials CREDENTIALS = new SimpleCredentials("admin", "admin".toCharArray());

    private static final long WARMUP = TimeUnit.SECONDS.toMillis(Long.getLong("warmup", 5));

    private static final long RUNTIME = TimeUnit.SECONDS.toMillis(Long.getLong("runtime", 60));
   
    private static final boolean PROFILE = Boolean.getBoolean("profile");
   
    private Repository repository;

    private Credentials credentials;

    private List<Session> sessions;

    private List<Thread> threads;

    private volatile boolean running;
   
    private Profiler profiler;

    protected static int getScale(int def) {
        int scale = Integer.getInteger("scale", 0);
        if (scale == 0) {
            scale = def;
        }
        return scale;
    }

    /**
     * Prepares this performance benchmark.
     *
     * @param repository the repository to use
     * @param credentials credentials of a user with write access
     * @throws Exception if the benchmark can not be prepared
     */
    public void setUp(Repository repository, Credentials credentials)
            throws Exception {
        this.repository = repository;
        this.credentials = credentials;
        this.sessions = new LinkedList<Session>();
        this.threads = new LinkedList<Thread>();

        this.running = true;

        beforeSuite();
        if (PROFILE) {
            profiler = new Profiler().startCollecting();
        }
    }

    @Override
    public void run(Iterable<RepositoryFixture> fixtures) {
        System.out.format(
                "# %-26.26s     min     10%%     50%%     90%%     max       N%n",
                toString());
        for (RepositoryFixture fixture : fixtures) {
            try {
                Repository[] cluster = fixture.setUpCluster(1);
                try {
                    // Run the test
                    DescriptiveStatistics statistics = runTest(cluster[0]);
                    if (statistics.getN() > 0) {
                        System.out.format(
                                "%-28.28s  %6.0f  %6.0f  %6.0f  %6.0f  %6.0f  %6d%n",
                                fixture.toString(),
                                statistics.getMin(),
                                statistics.getPercentile(10.0),
                                statistics.getPercentile(50.0),
                                statistics.getPercentile(90.0),
                                statistics.getMax(),
                                statistics.getN());
                    }
                } finally {
                    fixture.tearDownCluster();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private DescriptiveStatistics runTest(Repository repository) throws Exception {
        DescriptiveStatistics statistics = new DescriptiveStatistics();

        setUp(repository, CREDENTIALS);
        try {
           
            // Run a few iterations to warm up the system
            long warmupEnd = System.currentTimeMillis() + WARMUP;
            while (System.currentTimeMillis() < warmupEnd) {
                execute();
            }

            // Run test iterations, and capture the execution times
            long runtimeEnd = System.currentTimeMillis() + RUNTIME;
            while (System.currentTimeMillis() < runtimeEnd) {
                statistics.addValue(execute());
            }
        } finally {
            tearDown();
        }

        return statistics;
    }


    /**
     * Executes a single iteration of this test.
     *
     * @return number of milliseconds spent in this iteration
     * @throws Exception if an error occurs
     */
    public long execute() throws Exception {
        beforeTest();
        try {
            long start = System.currentTimeMillis();
            // System.out.println("execute " + this);
            runTest();
            return System.currentTimeMillis() - start;
        } finally {
            afterTest();
        }
    }
    /**
     * Cleans up after this performance benchmark.
     *
     * @throws Exception if the benchmark can not be cleaned up
     */
    public void tearDown() throws Exception {
        this.running = false;
        for (Thread thread : threads) {
            thread.join();
        }
       
        if (profiler != null) {
            System.out.println(profiler.stopCollecting().getTop(5));
            profiler = null;
        }

        afterSuite();

        for (Session session : sessions) {
            if (session.isLive()) {
                session.logout();
            }
        }

        this.threads = null;
        this.sessions = null;
        this.credentials = null;
        this.repository = null;
    }

    /**
     * Run before any iterations of this test get executed. Subclasses can
     * override this method to set up static test content.
     *
     * @throws Exception if an error occurs
     */
    protected void beforeSuite() throws Exception {
    }

    protected void beforeTest() throws Exception {
    }

    protected abstract void runTest() throws Exception;

    protected void afterTest() throws Exception {
    }

    /**
     * Run after all iterations of this test have been executed. Subclasses can
     * override this method to clean up static test content.
     *
     * @throws Exception if an error occurs
     */
    protected void afterSuite() throws Exception {
    }

    protected void failOnRepositoryVersions(String... versions)
            throws RepositoryException {
        String repositoryVersion =
                repository.getDescriptor(Repository.REP_VERSION_DESC);
        for (String version : versions) {
            if (repositoryVersion.startsWith(version)) {
                throw new RepositoryException(
                        "Unable to run " + getClass().getName()
                        + " on repository version " + version);
            }
        }
    }

    protected Repository getRepository() {
        return repository;
    }

    protected Credentials getCredentials() {
        return credentials;
    }

    /**
     * Returns a new reader session that will be automatically closed once
     * all the iterations of this test have been executed.
     *
     * @return reader session
     */
    protected Session loginAnonymous() {
        return login(new GuestCredentials());
    }
   
    /**
    * Returns a new session for the given user
    * that will be automatically closed once
    * all the iterations of this test have been executed.
    *
    * @param credentials the user credentials
    * @return user session
    */
   protected Session login(Credentials credentials) {
       try {
           Session session = repository.login(credentials);
           sessions.add(session);
           return session;
       } catch (RepositoryException e) {
           throw new RuntimeException(e);
       }
   }
   

    /**
     * Returns a new writer session that will be automatically closed once
     * all the iterations of this test have been executed.
     *
     * @return writer session
     */
    protected Session loginWriter() {
        try {
            Session session = repository.login(credentials);
            sessions.add(session);
            return session;
        } catch (RepositoryException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Adds a background thread that repeatedly executes the given job
     * until all the iterations of this test have been executed.
     *
     * @param job background job
     */
    protected void addBackgroundJob(final Runnable job) {
        Thread thread = new Thread("Background job " + job) {
            @Override
            public void run() {
                while (running) {
                    job.run();
                }
            }
        };
        thread.start();
        threads.add(thread);
    }

}
TOP

Related Classes of org.apache.jackrabbit.oak.benchmark.AbstractTest

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.