| 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 ) ); |
| } |
| } |