/* * 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.aries.subsystem.itests.performance; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.apache.aries.subsystem.itests.SubsystemTest; import org.easymock.internal.matchers.Null; import org.ops4j.pax.tinybundles.core.TinyBundle; import org.ops4j.pax.tinybundles.core.TinyBundles; import org.osgi.framework.Constants; import org.osgi.service.subsystem.Subsystem; public abstract class AbstractPerformanceTest extends SubsystemTest { protected static final int ARRAY_SIZE_BYTES = 2048; protected static final int BUNDLE_COUNT = 25; protected static final int PACKAGE_COUNT = 10; protected static final int THREAD_COUNT = 1; protected static final int TRIAL_COUNT = 1; protected final ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT); protected void addBundles(ZipOutputStream zos, String symbolicNamePrefix, String packageNamePrefix, String importOrExport) throws IOException { for (int i = 0; i < BUNDLE_COUNT; i++) { String symbolicName = symbolicNamePrefix + i; zos.putNextEntry(new ZipEntry(symbolicName + ".jar")); InputStream is = createBundle(symbolicName, packageNamePrefix, importOrExport); copy(is, zos); is.close(); zos.closeEntry(); } } protected static double average(long[] values) { double sum = 0; for (long value : values) { sum += value; } return sum / values.length; } protected static void copy(InputStream is, OutputStream os) throws IOException { byte[] bytes = new byte[ARRAY_SIZE_BYTES]; int read; while ((read = is.read(bytes)) != -1) { os.write(bytes, 0, read); } } protected InputStream createBundle(String symbolicName, String packageNamePrefix, String importOrExport) { TinyBundle tinyBundle = TinyBundles.bundle(); tinyBundle.set(Constants.BUNDLE_SYMBOLICNAME, symbolicName); StringBuilder builder = new StringBuilder(packageNamePrefix + 0); for (int i = 1; i < PACKAGE_COUNT; i++) { builder.append(','); builder.append(packageNamePrefix + i); } tinyBundle.set(importOrExport, builder.toString()); InputStream is = tinyBundle.build(); return is; } protected static Collection<Callable<Null>> createUninstallSubsystemCallables(Collection<Future<Subsystem>> futures) { Collection<Callable<Null>> callables = new ArrayList<Callable<Null>>(futures.size()); for (Future<Subsystem> future : futures) { try { final Subsystem subsystem = future.get(); callables.add(new Callable<Null>() { @Override public Null call() throws Exception { subsystem.uninstall(); return null; } }); } catch (Exception e) {} } return callables; } protected void runTrials(Collection<Callable<Subsystem>> callables) throws InterruptedException { long[] times = new long[TRIAL_COUNT]; for (int i = 0; i < TRIAL_COUNT; i++) { long start = System.currentTimeMillis(); Collection<Future<Subsystem>> futures = executor.invokeAll(callables); long end = System.currentTimeMillis(); times[i] = end - start; System.out.println("Trial " + i + " took " + times[i] + " ms"); uninstallSubsystems(futures); } System.out.println("Average time across " + TRIAL_COUNT + " trials: " + average(times) + " ms"); executor.shutdownNow(); } protected void uninstallSubsystems(Collection<Future<Subsystem>> futures) throws InterruptedException { Collection<Callable<Null>> callables = createUninstallSubsystemCallables(futures); executor.invokeAll(callables); } }