View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.surefire.its.jiras;
20  
21  import java.text.Format;
22  import java.text.NumberFormat;
23  import java.util.Iterator;
24  import java.util.Set;
25  import java.util.TreeSet;
26  
27  import org.apache.maven.shared.verifier.VerificationException;
28  import org.apache.maven.surefire.its.fixture.OutputValidator;
29  import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
30  import org.apache.maven.surefire.its.fixture.SurefireLauncher;
31  import org.junit.Before;
32  import org.junit.Test;
33  
34  import static java.lang.String.format;
35  import static java.math.RoundingMode.DOWN;
36  import static java.util.Locale.ROOT;
37  import static org.hamcrest.CoreMatchers.anyOf;
38  import static org.hamcrest.CoreMatchers.containsString;
39  import static org.hamcrest.CoreMatchers.endsWith;
40  import static org.hamcrest.MatcherAssert.assertThat;
41  import static org.hamcrest.Matchers.hasSize;
42  import static org.hamcrest.core.Is.is;
43  import static org.junit.Assert.assertTrue;
44  
45  /**
46   * @author Kristian Rosenvold
47   */
48  @SuppressWarnings("checkstyle:magicnumber")
49  public class SurefireJUnit4MethodParallelWithSuiteCountIT extends SurefireJUnit4IntegrationTestCase {
50      // if you want to change his constant, change it in SuiteTest1.java and SuiteTest2.java as well
51      private static final int PERFORMANCE_TEST_MULTIPLICATION_FACTOR = 4;
52  
53      private Format lowerScaleFormatter, noFractionalDigitsFormatter;
54  
55      private static Set<String> printTestLines(OutputValidator validator, String pattern) throws VerificationException {
56          Set<String> log = new TreeSet<>(validator.loadLogLines());
57          for (Iterator<String> it = log.iterator(); it.hasNext(); ) {
58              String line = it.next();
59              if (!line.contains(pattern)) {
60                  it.remove();
61              }
62          }
63          return log;
64      }
65  
66      private static long duration(String logLine) {
67          return Integer.decode(logLine.split("=")[1]);
68      }
69  
70      @Before
71      public void init() {
72          NumberFormat lowScaleFormatter = NumberFormat.getInstance(ROOT);
73          lowScaleFormatter.setRoundingMode(DOWN);
74          lowScaleFormatter.setMinimumFractionDigits(1);
75          lowScaleFormatter.setMaximumFractionDigits(1);
76          this.lowerScaleFormatter = lowScaleFormatter;
77  
78          NumberFormat noFractionalDigitsFormatter = NumberFormat.getInstance(ROOT);
79          noFractionalDigitsFormatter.setRoundingMode(DOWN);
80          noFractionalDigitsFormatter.setMinimumFractionDigits(0);
81          noFractionalDigitsFormatter.setMaximumFractionDigits(0);
82          this.noFractionalDigitsFormatter = noFractionalDigitsFormatter;
83      }
84  
85      @Test
86      public void testMethodsParallelWithSuite() throws VerificationException {
87          OutputValidator validator = unpack().addGoal("-Djunit.jupiter.execution.parallel.mode.default=concurrent")
88                  .executeTest()
89                  .verifyErrorFree(6);
90          Set<String> testLines = printTestLines(validator, "test finished after duration=");
91          assertThat(testLines.size(), is(2));
92          for (String testLine : testLines) {
93              long duration = duration(testLine);
94              long min = 250 * PERFORMANCE_TEST_MULTIPLICATION_FACTOR;
95              long max = 750 * PERFORMANCE_TEST_MULTIPLICATION_FACTOR;
96              assertTrue(
97                      format("duration %d should be between %d and %d ms", duration, min, max),
98                      duration > min && duration < max);
99          }
100         Set<String> suiteLines = printTestLines(validator, "suite finished after duration=");
101         assertThat(suiteLines, hasSize(1));
102         //        long duration = duration(suiteLines.iterator().next());
103         //        long min = 750 * PERFORMANCE_TEST_MULTIPLICATION_FACTOR;
104         //        long max = 1250 * PERFORMANCE_TEST_MULTIPLICATION_FACTOR;
105         //        assertTrue(
106         //                format("duration %d should be between %d and %d ms", duration, min, max),
107         //                duration > min && duration < max);
108 
109         String delayMin = lowerScaleFormatter.format(0.98 * PERFORMANCE_TEST_MULTIPLICATION_FACTOR * 0.5);
110         String delayMax = noFractionalDigitsFormatter.format(PERFORMANCE_TEST_MULTIPLICATION_FACTOR * 0.5) + ".";
111 
112         for (String line : validator.loadLogLines()) {
113             if (line.startsWith("Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:")) {
114                 assertThat(
115                         line,
116                         anyOf( // 1.9xx to 2.xxx can vary depending on CI jobs
117                                 containsString("Time elapsed: " + delayMin),
118                                 containsString("Time elapsed: " + delayMax)));
119                 assertThat(
120                         line,
121                         anyOf(
122                                 endsWith(" s -- in surefire747.SuiteTest1"),
123                                 endsWith(" s -- in surefire747.SuiteTest2")));
124             }
125         }
126     }
127 
128     @Test
129     public void testClassesParallelWithSuite() throws VerificationException {
130         OutputValidator validator = unpack().addGoal("-Djunit.vintage.execution.parallel.classes=true")
131                 .executeTest()
132                 .verifyErrorFree(6);
133         Set<String> testLines = printTestLines(validator, "test finished after duration=");
134         assertThat(testLines.size(), is(2));
135         //        for (String testLine : testLines) {
136         //            long duration = duration(testLine);
137         //            long min = 1450 * PERFORMANCE_TEST_MULTIPLICATION_FACTOR;
138         //            long max = 1750 * PERFORMANCE_TEST_MULTIPLICATION_FACTOR;
139         //            assertTrue(
140         //                    format("duration %d should be between %d and %d ms", duration, min, max),
141         //                    duration > min && duration < max);
142         //        }
143         Set<String> suiteLines = printTestLines(validator, "suite finished after duration=");
144         assertThat(suiteLines.size(), is(1));
145         long duration = duration(suiteLines.iterator().next());
146         long min = 1450 * PERFORMANCE_TEST_MULTIPLICATION_FACTOR;
147         long max = 1750 * PERFORMANCE_TEST_MULTIPLICATION_FACTOR;
148         assertTrue(
149                 format("duration %d should be between %d and %d ms", duration, min, max),
150                 duration > min && duration < max);
151     }
152 
153     public SurefireLauncher unpack() {
154         return unpack("junit-parallel-with-suite");
155     }
156 }