Skip to content

Commit

Permalink
Merge pull request #302 from zabetak/split-parameterized-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlatombe committed Sep 16, 2024
2 parents 305c065 + 4cf0586 commit 751ab24
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,15 @@ public boolean isSplitByCase() {
return false;
}

public boolean useParameters() {
return false;

Check warning on line 52 in src/main/java/org/jenkinsci/plugins/parallel_test_executor/testmode/JavaClassName.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 52 is not covered by tests
}

@Override
@NonNull
public Map<String, TestEntity> getTestEntitiesMap(@NonNull ClassResult classResult) {
if (isSplitByCase()) {
return classResult.getChildren().stream().map(JavaTestCase::new).collect(Collectors.toMap(JavaTestCase::getKey, identity(), JavaTestCase::new));
return classResult.getChildren().stream().map(cr -> new JavaTestCase(cr, useParameters())).collect(Collectors.toMap(JavaTestCase::getKey, identity(), JavaTestCase::new));
} else {
TestClass testClass = new TestClass(classResult);
return Map.of(testClass.getKey(), testClass);
Expand Down Expand Up @@ -90,10 +94,14 @@ public String getWord() {

private static class JavaTestCase extends TestEntity {
private final String output;
private JavaTestCase(CaseResult cr) {
private JavaTestCase(CaseResult cr, boolean useParams) {
// Parameterized tests use ${fqdnClassName}#${methodName}[{parametersDescription}] format
// passing parameters to surefire is not supported, so just drop them and will sum durations
this.output = cr.getClassName() + "#" + cr.getName().split("\\[")[0];
if (useParams) {
this.output = cr.getClassName() + "#" + cr.getName();
} else {
// Some surefire versions don't support parameters, so just drop them and will sum durations
this.output = cr.getClassName() + "#" + cr.getName().split("\\[")[0];
}
this.duration = (long)(cr.getDuration()*1000); // milliseconds is a good enough precision for us
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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.jenkinsci.plugins.parallel_test_executor.testmode;

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.model.Descriptor;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;

/**
* This mode works best with java projects.
* <p>
* Parallelize per java test case including parameters if present.
* </p>
* <p>
* It is also able to estimate tests to run from the workspace content if no historical context could be found.
* </p>
*/
public class JavaParameterizedTestCaseName extends JavaClassName {
@DataBoundConstructor
public JavaParameterizedTestCaseName() {
}

@Override
public boolean isSplitByCase() {
return true;
}

@Override
public boolean useParameters() {
return true;
}

@Extension
@Symbol("javaParamTestCase")
public static class DescriptorImpl extends Descriptor<TestMode> {
@Override
@NonNull
public String getDisplayName() {
return "By Java test cases with parameters";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* This mode works best with java projects.
* <p>
* Parallelize per java test case.
* Parallelize per java test case ingoring parameters if present.
* </p>
* <p>
* It is also able to estimate tests to run from the workspace content if no historical context could be found.
Expand All @@ -24,13 +24,17 @@ public boolean isSplitByCase() {
return true;
}

@Override public boolean useParameters() {
return false;
}

@Extension
@Symbol("javaTestCase")
public static class DescriptorImpl extends Descriptor<TestMode> {
@Override
@NonNull
public String getDisplayName() {
return "By Java test cases";
return "By Java test cases without parameters";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div>
This mode works best with Java projects.
<p>
Parallelize per Java test case including parameters.
<p>
It is also able to estimate tests (per class) to run from the workspace content if no historical context could be found.
</div>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div>
This mode works best with Java projects.
<p>
Parallelize per Java test case.
Parallelize per Java test case ignoring parameters. If parameters are present they are considered the same test.
<p>
It is also able to estimate tests (per class) to run from the workspace content if no historical context could be found.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.stream.Collectors;
import org.apache.tools.ant.DirectoryScanner;
import org.hamcrest.Matchers;
import org.jenkinsci.plugins.parallel_test_executor.testmode.JavaParameterizedTestCaseName;
import org.jenkinsci.plugins.parallel_test_executor.testmode.JavaTestCaseName;
import org.jenkinsci.plugins.parallel_test_executor.testmode.JavaClassName;
import org.jenkinsci.plugins.parallel_test_executor.testmode.TestClassAndCaseName;
Expand Down Expand Up @@ -152,6 +153,19 @@ public void findTestCasesWithParameters() throws Exception {
assertThat(allSplits, hasItem("org.jenkinsci.plugins.parallel_test_executor.Test1#testCase"));
}

@Test
public void findTestCasesWithParametersIncluded() throws Exception {
TestResult testResult = new TestResult(0L, scanner, false);
testResult.tally();
when(action.getResult()).thenReturn(testResult);
CountDrivenParallelism parallelism = new CountDrivenParallelism(3);
List<InclusionExclusionPattern> splits = Splitter.findTestSplits(parallelism, new JavaParameterizedTestCaseName(), build, listener, false, null, null);
assertEquals(3, splits.size());
var allSplits = splits.stream().flatMap(s -> s.getList().stream()).collect(Collectors.toSet());
assertThat(allSplits, hasSize(22));
assertThat(allSplits, hasItem("org.jenkinsci.plugins.parallel_test_executor.Test1#testCase[param1]"));
}

@Test
public void findTestSplitsInclusions() throws Exception {
CountDrivenParallelism parallelism = new CountDrivenParallelism(5);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="org.jenkinsci.plugins.parallel_test_executor.Test1" time="112.22" tests="21" errors="0" skipped="0" failures="0">
<testcase name="testCase[param1]" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="1.00"/>
<testcase name="testCase[param2]" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="1.00"/>
<testcase name="testCase[param3]" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="1.00"/>
<testcase name="test1Case2" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="2.00"/>
<testcase name="test1Case3" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="3.00"/>
<testcase name="test1Case4" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="4.00"/>
<testcase name="test1Case5" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="5.00"/>
<testcase name="test1Case6" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="6.00"/>
<testcase name="test1Case7" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="7.00"/>
<testcase name="test1Case8" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="8.00"/>
<testcase name="test1Case9" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="9.00"/>
<testcase name="test1Case10" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="10.00"/>
<testcase name="test1Case11" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="1.00"/>
<testcase name="test1Case12" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="2.00"/>
<testcase name="test1Case13" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="3.00"/>
<testcase name="test1Case14" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="4.00"/>
<testcase name="test1Case15" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="5.00"/>
<testcase name="test1Case16" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="6.00"/>
<testcase name="test1Case17" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="7.00"/>
<testcase name="test1Case18" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="8.00"/>
<testcase name="test1Case19" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="9.00"/>
<testcase name="test1Case20" classname="org.jenkinsci.plugins.parallel_test_executor.Test1" time="10.22"/>
</testsuite>

0 comments on commit 751ab24

Please sign in to comment.