blob: 764c57a69178105a87e23abbd04e9e3f77633779 [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.testset.TestSetFailedException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
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.RunWith;
import java.util.HashMap;
import java.util.Map;
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.pc.ParallelComputerUtil.resolveConcurrency;
import static org.apache.maven.surefire.junitcore.pc.ParallelComputerUtil.overrideAvailableProcessors;
import static org.apache.maven.surefire.junitcore.pc.ParallelComputerUtil.setDefaultAvailableProcessors;
import static org.hamcrest.core.Is.is;
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 optimized thread resources in ParallelComputer
* by given {@link org.apache.maven.surefire.junitcore.JUnitCoreParameters}.
*
* @author Tibor Digana (tibor17)
* @see ParallelComputerUtil
* @since 2.17
*/
@RunWith( Theories.class )
@SuppressWarnings( "checkstyle:magicnumber" )
public final class OptimizedParallelComputerTest
{
@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()
{
overrideAvailableProcessors( 1 );
}
@AfterClass
public static void afterClass()
{
setDefaultAvailableProcessors();
}
@Theory
public void threadCountSuites( int cpu ) throws TestSetFailedException
{
overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suites" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
RunnerCounter counter = new RunnerCounter( 5, 10, 20 );
Concurrency concurrency = resolveConcurrency( params, counter );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 0 ) );
assertThat( concurrency.suites, is( (int) Math.min( 3 * cpu, counter.suites ) ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void threadCountClasses( int cpu ) throws TestSetFailedException
{
overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classes" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
RunnerCounter counter = new RunnerCounter( 1, 5, 10 );
Concurrency concurrency = resolveConcurrency( params, counter );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 0 ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( (int) Math.min( 3 * cpu, counter.classes ) ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void threadCountMethods( int cpu ) throws TestSetFailedException
{
overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "methods" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
Concurrency concurrency = resolveConcurrency( params, counter );
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( (int) Math.min( 3 * cpu, counter.methods ) ) );
}
@Theory
public void threadCountBoth( int cpu ) throws TestSetFailedException
{
overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "both" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
Concurrency concurrency = resolveConcurrency( params, counter );
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) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void threadCountClassesAndMethods( int cpu ) throws TestSetFailedException
{
overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "classesAndMethods" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
Concurrency concurrency = resolveConcurrency( params, counter );
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) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void threadCountSuitesAndMethods( int cpu ) throws TestSetFailedException
{
overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndMethods" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
RunnerCounter counter = new RunnerCounter( 2, 3, 5 );
Concurrency concurrency = resolveConcurrency( params, counter );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
assertThat( concurrency.suites, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
assertThat( concurrency.classes, is( 0 ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void threadCountSuitesAndClasses( int cpu ) throws TestSetFailedException
{
overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "suitesAndClasses" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
RunnerCounter counter = new RunnerCounter( 2, 5, 20 );
Concurrency concurrency = resolveConcurrency( params, counter );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
assertThat( concurrency.suites, is( (int) Math.min( ( 2d * 3 / 7 ) * cpu, 2 ) ) );
assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
assertThat( concurrency.methods, is( 0 ) );
}
@Theory
public void threadCountAll( int cpu ) throws TestSetFailedException
{
overrideAvailableProcessors( cpu );
Map<String, String> properties = new HashMap<>();
properties.put( PARALLEL_KEY, "all" );
properties.put( THREADCOUNT_KEY, "3" );
JUnitCoreParameters params = new JUnitCoreParameters( properties );
RunnerCounter counter = new RunnerCounter( 2, 5, 20 );
Concurrency concurrency = resolveConcurrency( params, counter );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 3 * cpu ) );
assertThat( concurrency.suites, is( (int) Math.min( ( 2d * 3 / 11 ) * cpu, 2 ) ) );
assertThat( concurrency.classes, is( (int) Math.min( ( 5d * 3 / 11 ) * cpu, 5 ) ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
@Theory
public void reusableThreadCountSuitesAndClasses( int cpu ) throws TestSetFailedException
{
// 4 * cpu to 5 * cpu threads to run test classes
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 );
RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
Concurrency concurrency = resolveConcurrency( params, counter );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertFalse( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 6 * cpu ) );
assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
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
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 );
RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
Concurrency concurrency = resolveConcurrency( params, counter );
assertTrue( params.isParallelSuites() );
assertFalse( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 6 * cpu ) );
assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
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
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 );
RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
Concurrency concurrency = resolveConcurrency( params, counter );
assertFalse( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 6 * cpu ) );
assertThat( concurrency.suites, is( 0 ) );
assertThat( concurrency.classes, is( Math.min( 2 * cpu, 5 ) ) );
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
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 );
RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
Concurrency concurrency = resolveConcurrency( params, counter );
assertTrue( params.isParallelSuites() );
assertTrue( params.isParallelClasses() );
assertTrue( params.isParallelMethods() );
assertThat( concurrency.capacity, is( 14 * cpu ) );
assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
assertThat( concurrency.classes, is( Math.min( 4 * cpu, 5 ) ) );
assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
}
}