blob: 6f7e02bd558e921b7b4e1401e66b1e2662a5440d [file] [log] [blame]
package org.apache.maven.surefire.junitcore.pc;
/*
* 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.
*/
import org.apache.maven.surefire.junitcore.JUnitCoreParameters;
import org.apache.maven.surefire.api.report.ConsoleStream;
import org.apache.maven.surefire.api.report.DefaultDirectConsoleReporter;
import org.apache.maven.surefire.api.testset.TestSetFailedException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.theories.DataPoint;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.rules.ExpectedException;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.apache.maven.surefire.junitcore.pc.ParallelComputerUtil.resolveConcurrency;
import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.PARALLEL_KEY;
import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.THREADCOUNT_KEY;
import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.THREADCOUNTSUITES_KEY;
import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.THREADCOUNTCLASSES_KEY;
import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.THREADCOUNTMETHODS_KEY;
import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.PARALLEL_TIMEOUT_KEY;
import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.PARALLEL_TIMEOUTFORCED_KEY;
import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.USEUNLIMITEDTHREADS_KEY;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* Testing an algorithm in {@link ParallelComputerUtil} which configures allocated thread resources in ParallelComputer
* by given {@link org.apache.maven.surefire.junitcore.JUnitCoreParameters}.
*
* @author Tibor Digana (tibor17)
* @see ParallelComputerUtil
* @since 2.16
*/
@RunWith( Theories.class )
@SuppressWarnings( "checkstyle:magicnumber" )
public final class ParallelComputerUtilTest
{
private static final ConsoleStream LOGGER = new DefaultDirectConsoleReporter( System.out );
@DataPoint
public static final int CPU_1 = 1;
@DataPoint
public static final int CPU_4 = 4;
@Rule
public final ExpectedException exception = ExpectedException.none();
@BeforeClass
public static void beforeClass()
{
ParallelComputerUtil.overrideAvailableProcessors( 1 );
}
@AfterClass
public static void afterClass()
{
ParallelComputerUtil.setDefaultAvailableProcessors();
}
@Before
public void beforeTest() throws InterruptedException
{
System.gc();
Thread.sleep( 50L );
assertFalse( Thread.currentThread().isInterrupted() );
}
private static Map<String, String> parallel( String parallel )
{
return Collections.singletonMap( PARALLEL_KEY, parallel );
}
@Test
public void unknownParallel() throws TestSetFailedException
{
Map<String, String> properties = new HashMap<>();
exception.expect( TestSetFailedException.class );
resolveConcurrency( new JUnitCoreParameters( properties ), null );
}
@Test
public void unknownThreadCountSuites() throws TestSetFailedException
{
JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suites" ) );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
exception.expect( TestSetFailedException.class );
resolveConcurrency( params, null );
}
@Test
public void unknownThreadCountClasses() throws TestSetFailedException
{
JUnitCoreParameters params = new JUnitCoreParameters( parallel( "classes" ) );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
exception.expect( TestSetFailedException.class );
resolveConcurrency( params, null );
}
@Test
public void unknownThreadCountMethods() throws TestSetFailedException
{
JUnitCoreParameters params = new JUnitCoreParameters( parallel( "methods" ) );
assertFalse( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
exception.expect( TestSetFailedException.class );
resolveConcurrency( params, null );
}
@Test
public void unknownThreadCountBoth() throws TestSetFailedException
{
JUnitCoreParameters params = new JUnitCoreParameters( parallel( "both" ) );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
exception.expect( TestSetFailedException.class );
resolveConcurrency( params, null );
}
@Test
public void unknownThreadCountAll() throws TestSetFailedException
{
JUnitCoreParameters params = new JUnitCoreParameters( parallel( "all" ) );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
exception.expect( TestSetFailedException.class );
resolveConcurrency( params, null );
}
@Test
public void unknownThreadCountSuitesAndClasses() throws TestSetFailedException
{
JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suitesAndClasses" ) );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
exception.expect( TestSetFailedException.class );
resolveConcurrency( params, null );
}
@Test
public void unknownThreadCountSuitesAndMethods() throws TestSetFailedException
{
JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suitesAndMethods" ) );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
exception.expect( TestSetFailedException.class );
resolveConcurrency( params, null );
}
@Test
public void unknownThreadCountClassesAndMethods() throws TestSetFailedException
{
JUnitCoreParameters params = new JUnitCoreParameters( parallel( "classesAndMethods" ) );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
exception.expect( TestSetFailedException.class );
resolveConcurrency( params, null );
}
@Theory
public void useUnlimitedThreadsSuites( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suites" );
properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( 0 ) );
properties.put( THREADCOUNTSUITES_KEY, "5" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void useUnlimitedThreadsClasses( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classes" );
properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
assertThat( concurrency.methods, is( 0 ) );
properties.put( THREADCOUNTCLASSES_KEY, "5" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 5 * cpu ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void unlimitedThreadsMethods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "methods" );
properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
properties.put( THREADCOUNTMETHODS_KEY, "5" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( 5 * cpu ) );
}
@Theory
public void unlimitedThreadsSuitesAndClasses( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndClasses" );
properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
assertThat( concurrency.methods, is( 0 ) );
properties.put( THREADCOUNTSUITES_KEY, "5" );
properties.put( THREADCOUNTCLASSES_KEY, "15" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( 15 * cpu ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void unlimitedThreadsSuitesAndMethods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndMethods" );
properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
properties.put( THREADCOUNTSUITES_KEY, "5" );
properties.put( THREADCOUNTMETHODS_KEY, "15" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( 15 * cpu ) );
}
@Theory
public void unlimitedThreadsClassesAndMethods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classesAndMethods" );
properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
properties.put( THREADCOUNTCLASSES_KEY, "5" );
properties.put( THREADCOUNTMETHODS_KEY, "15" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 5 * cpu ) );
assertThat( concurrency.methods, is( 15 * cpu ) );
}
@Theory
public void unlimitedThreadsAll( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "all" );
properties.put( USEUNLIMITEDTHREADS_KEY, "true" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
properties.put( THREADCOUNTSUITES_KEY, "5" );
properties.put( THREADCOUNTCLASSES_KEY, "15" );
properties.put( THREADCOUNTMETHODS_KEY, "30" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( 15 * cpu ) );
assertThat( concurrency.methods, is( 30 * cpu ) );
}
@Theory
public void threadCountSuites( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suites" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 0 ) );
assertThat( concurrency.suites, is( 3 * cpu ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void threadCountClasses( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classes" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 0 ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 3 * cpu ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void threadCountMethods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "methods" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 0 ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( 3 * cpu ) );
}
@Theory
public void threadCountBoth( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "both" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( (int) ( ( 3d / 2 ) * cpu ) ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void threadCountClassesAndMethods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classesAndMethods" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( (int) ( ( 3d / 2 ) * cpu ) ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void threadCountSuitesAndMethods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndMethods" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
assertThat( concurrency.suites, is( (int) ( ( 3d / 2 ) * cpu ) ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void threadCountSuitesAndClasses( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndClasses" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
assertThat( concurrency.suites, is( (int) ( ( 3d / 2 ) * cpu ) ) );
assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void threadCountAll( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "all" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
assertThat( concurrency.suites, is( cpu ) );
assertThat( concurrency.classes, is( cpu ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void everyThreadCountSuitesAndClasses( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndClasses" );
properties.put( THREADCOUNT_KEY, "3" );
// % percentage ratio
properties.put( THREADCOUNTSUITES_KEY, "34" );
properties.put( THREADCOUNTCLASSES_KEY, "66" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
int concurrentSuites = (int) ( 0.34d * concurrency.capacity );
assertThat( concurrency.suites, is( concurrentSuites ) );
assertThat( concurrency.classes, is( concurrency.capacity - concurrentSuites ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void everyThreadCountSuitesAndMethods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndMethods" );
properties.put( THREADCOUNT_KEY, "3" );
// % percentage ratio
properties.put( THREADCOUNTSUITES_KEY, "34" );
properties.put( THREADCOUNTMETHODS_KEY, "66" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
int concurrentSuites = (int) ( 0.34d * concurrency.capacity );
assertThat( concurrency.suites, is( concurrentSuites ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( concurrency.capacity - concurrentSuites ) );
}
@Theory
public void everyThreadCountClassesAndMethods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classesAndMethods" );
properties.put( THREADCOUNT_KEY, "3" );
// % percentage ratio
properties.put( THREADCOUNTCLASSES_KEY, "34" );
properties.put( THREADCOUNTMETHODS_KEY, "66" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
assertThat( concurrency.suites, is( 0 ) );
int concurrentClasses = (int) ( 0.34d * concurrency.capacity );
assertThat( concurrency.classes, is( concurrentClasses ) );
assertThat( concurrency.methods, is( concurrency.capacity - concurrentClasses ) );
}
@Theory
public void everyThreadCountAll( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "all" );
properties.put( THREADCOUNT_KEY, "3" );
// % percentage ratio
properties.put( THREADCOUNTSUITES_KEY, "17" );
properties.put( THREADCOUNTCLASSES_KEY, "34" );
properties.put( THREADCOUNTMETHODS_KEY, "49" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
int concurrentSuites = (int) ( 0.17d * concurrency.capacity );
int concurrentClasses = (int) ( 0.34d * concurrency.capacity );
assertThat( concurrency.suites, is( concurrentSuites ) );
assertThat( concurrency.classes, is( concurrentClasses ) );
assertThat( concurrency.methods, is( concurrency.capacity - concurrentSuites - concurrentClasses ) );
}
@Theory
public void reusableThreadCountSuitesAndClasses( int cpu ) throws TestSetFailedException
{
// 4 * cpu to 5 * cpu threads to run test classes
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndClasses" );
properties.put( THREADCOUNT_KEY, "6" );
properties.put( THREADCOUNTSUITES_KEY, "2" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 6 * cpu ) );
assertThat( concurrency.suites, is( 2 * cpu ) );
assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void reusableThreadCountSuitesAndMethods( int cpu ) throws TestSetFailedException
{
// 4 * cpu to 5 * cpu threads to run test methods
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndMethods" );
properties.put( THREADCOUNT_KEY, "6" );
properties.put( THREADCOUNTSUITES_KEY, "2" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 6 * cpu ) );
assertThat( concurrency.suites, is( 2 * cpu ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void reusableThreadCountClassesAndMethods( int cpu ) throws TestSetFailedException
{
// 4 * cpu to 5 * cpu threads to run test methods
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classesAndMethods" );
properties.put( THREADCOUNT_KEY, "6" );
properties.put( THREADCOUNTCLASSES_KEY, "2" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 6 * cpu ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 2 * cpu ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void reusableThreadCountAll( int cpu ) throws TestSetFailedException
{
// 8 * cpu to 13 * cpu threads to run test methods
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "all" );
properties.put( THREADCOUNT_KEY, "14" );
properties.put( THREADCOUNTSUITES_KEY, "2" );
properties.put( THREADCOUNTCLASSES_KEY, "4" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 14 * cpu ) );
assertThat( concurrency.suites, is( 2 * cpu ) );
assertThat( concurrency.classes, is( 4 * cpu ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void suites( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suites" );
properties.put( THREADCOUNTSUITES_KEY, "5" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 5 * cpu ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void classes( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classes" );
properties.put( THREADCOUNTCLASSES_KEY, "5" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 5 * cpu ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 5 * cpu ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void methods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "methods" );
properties.put( THREADCOUNTMETHODS_KEY, "5" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 5 * cpu ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( 5 * cpu ) );
}
@Theory
public void suitesAndClasses( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndClasses" );
properties.put( THREADCOUNTSUITES_KEY, "5" );
properties.put( THREADCOUNTCLASSES_KEY, "15" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 20 * cpu ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( 15 * cpu ) );
assertThat( concurrency.methods, is( 0 ) );
// Warning: this case works but is not enabled in AbstractSurefireMojo
// Instead use the 'useUnlimitedThreads' parameter.
properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndClasses" );
properties.put( THREADCOUNTSUITES_KEY, "5" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void suitesAndMethods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndMethods" );
properties.put( THREADCOUNTSUITES_KEY, "5" );
properties.put( THREADCOUNTMETHODS_KEY, "15" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 20 * cpu ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( 15 * cpu ) );
// Warning: this case works but is not enabled in AbstractSurefireMojo
// Instead use the 'useUnlimitedThreads' parameter.
properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndMethods" );
properties.put( THREADCOUNTSUITES_KEY, "5" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void classesAndMethods( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classesAndMethods" );
properties.put( THREADCOUNTCLASSES_KEY, "5" );
properties.put( THREADCOUNTMETHODS_KEY, "15" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 20 * cpu ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 5 * cpu ) );
assertThat( concurrency.methods, is( 15 * cpu ) );
// Warning: this case works but is not enabled in AbstractSurefireMojo
// Instead use the 'useUnlimitedThreads' parameter.
properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classesAndMethods" );
properties.put( THREADCOUNTCLASSES_KEY, "5" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( 5 * cpu ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void all( int cpu ) throws TestSetFailedException
{
ParallelComputerUtil.overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "all" );
properties.put( THREADCOUNTSUITES_KEY, "5" );
properties.put( THREADCOUNTCLASSES_KEY, "15" );
properties.put( THREADCOUNTMETHODS_KEY, "30" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
Concurrency concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 50 * cpu ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( 15 * cpu ) );
assertThat( concurrency.methods, is( 30 * cpu ) );
// Warning: these cases work but they are not enabled in AbstractSurefireMojo
// Instead use the 'useUnlimitedThreads' parameter.
properties = new HashMap<>();
properties.put( PARALLEL_KEY, "all" );
properties.put( THREADCOUNTSUITES_KEY, "5" );
properties.put( THREADCOUNTCLASSES_KEY, "15" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( 5 * cpu ) );
assertThat( concurrency.classes, is( 15 * cpu ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
properties = new HashMap<>();
properties.put( PARALLEL_KEY, "all" );
properties.put( THREADCOUNTCLASSES_KEY, "15" );
params = new JUnitCoreParameters( properties );
concurrency = resolveConcurrency( params, null );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
assertThat( concurrency.classes, is( 15 * cpu ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Test
public void withoutShutdown()
{
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "methods" );
properties.put( THREADCOUNTMETHODS_KEY, "2" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( LOGGER, params );
ParallelComputer pc = pcBuilder.buildComputer();
final JUnitCore core = new JUnitCore();
final long t1 = systemMillis();
final Result result = core.run( pc, TestClass.class );
final long t2 = systemMillis();
long timeSpent = t2 - t1;
final long deltaTime = 500L;
assertTrue( result.wasSuccessful() );
assertThat( result.getRunCount(), is( 3 ) );
assertThat( result.getFailureCount(), is( 0 ) );
assertThat( result.getIgnoreCount(), is( 0 ) );
//assertThat( timeSpent, between (timeSpent - deltaTime, timeSpent + deltaTime + 2000L ) );
assertEquals( 10000L, timeSpent, deltaTime );
}
@Test
public void shutdown() throws TestSetFailedException
{
// The JUnitCore returns after 2.5s.
// The test-methods in TestClass are NOT interrupted, and return normally after 5s.
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "methods" );
properties.put( THREADCOUNTMETHODS_KEY, "2" );
properties.put( PARALLEL_TIMEOUT_KEY, Double.toString( 2.5d ) );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( LOGGER, params );
ParallelComputer pc = pcBuilder.buildComputer();
final JUnitCore core = new JUnitCore();
final long t1 = systemMillis();
core.run( pc, TestClass.class );
final long t2 = systemMillis();
final long timeSpent = t2 - t1;
final long deltaTime = 500L;
assertEquals( 5000L, timeSpent, deltaTime );
String description = pc.describeElapsedTimeout();
assertTrue( description.contains( "The test run has finished abruptly after timeout of 2.5 seconds." ) );
assertTrue( description.contains(
"These tests were executed in prior to the shutdown operation:\n" + TestClass.class.getName() ) );
}
@Test
public void forcedShutdown() throws TestSetFailedException
{
// The JUnitCore returns after 2.5s, and the test-methods in TestClass are interrupted.
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "methods" );
properties.put( THREADCOUNTMETHODS_KEY, "2" );
properties.put( PARALLEL_TIMEOUTFORCED_KEY, Double.toString( 2.5d ) );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( LOGGER, params );
ParallelComputer pc = pcBuilder.buildComputer();
final JUnitCore core = new JUnitCore();
final long t1 = systemMillis();
core.run( pc, TestClass.class );
final long t2 = systemMillis();
final long timeSpent = t2 - t1;
final long deltaTime = 500L;
assertEquals( 2500L, timeSpent, deltaTime );
String description = pc.describeElapsedTimeout();
assertTrue( description.contains( "The test run has finished abruptly after timeout of 2.5 seconds." ) );
assertTrue( description.contains(
"These tests were executed in prior to the shutdown operation:\n" + TestClass.class.getName() ) );
}
@Test
public void timeoutAndForcedShutdown() throws TestSetFailedException
{
// The JUnitCore returns after 3.5s and the test-methods in TestClass are timed out after 2.5s.
// No new test methods are scheduled for execution after 2.5s.
// Interruption of test methods after 3.5s.
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "methods" );
properties.put( THREADCOUNTMETHODS_KEY, "2" );
properties.put( PARALLEL_TIMEOUT_KEY, Double.toString( 2.5d ) );
properties.put( PARALLEL_TIMEOUTFORCED_KEY, Double.toString( 3.5d ) );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( LOGGER, params );
ParallelComputer pc = pcBuilder.buildComputer();
final JUnitCore core = new JUnitCore();
final long t1 = systemMillis();
core.run( pc, TestClass.class );
final long t2 = systemMillis();
final long timeSpent = t2 - t1;
final long deltaTime = 500L;
assertEquals( 3500L, timeSpent, deltaTime );
String description = pc.describeElapsedTimeout();
assertTrue( description.contains( "The test run has finished abruptly after timeout of 2.5 seconds." ) );
assertTrue( description.contains(
"These tests were executed in prior to the shutdown operation:\n" + TestClass.class.getName() ) );
}
@Test
public void forcedTimeoutAndShutdown() throws Exception
{
// The JUnitCore returns after 3.5s and the test-methods in TestClass are interrupted after 3.5s.
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "methods" );
properties.put( THREADCOUNTMETHODS_KEY, "2" );
properties.put( PARALLEL_TIMEOUTFORCED_KEY, Double.toString( 3.5d ) );
properties.put( PARALLEL_TIMEOUT_KEY, Double.toString( 4.0d ) );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( LOGGER, params );
ParallelComputer pc = pcBuilder.buildComputer();
final JUnitCore core = new JUnitCore();
final long t1 = systemMillis();
core.run( pc, TestClass.class );
final long t2 = systemMillis();
final long timeSpent = t2 - t1;
final long deltaTime = 500L;
assertEquals( 3500L, timeSpent, deltaTime );
String description = pc.describeElapsedTimeout();
assertTrue( description.contains( "The test run has finished abruptly after timeout of 3.5 seconds." ) );
assertTrue( description.contains(
"These tests were executed in prior to the shutdown operation:\n" + TestClass.class.getName() ) );
}
/**
*
*/
public static class TestClass
{
@Test
public void a() throws InterruptedException
{
long t1 = systemMillis();
try
{
Thread.sleep( 5000L );
}
finally
{
System.out.println( getClass().getSimpleName() + "#a() spent " + ( systemMillis() - t1 ) );
}
}
@Test
public void b() throws InterruptedException
{
long t1 = systemMillis();
try
{
Thread.sleep( 5000L );
}
finally
{
System.out.println( getClass().getSimpleName() + "#b() spent " + ( systemMillis() - t1 ) );
}
}
@Test
public void c() throws InterruptedException
{
long t1 = systemMillis();
try
{
Thread.sleep( 5000L );
}
finally
{
System.out.println( getClass().getSimpleName() + "#c() spent " + ( systemMillis() - t1 ) );
}
}
}
private static long systemMillis()
{
return TimeUnit.NANOSECONDS.toMillis( System.nanoTime() );
}
}