1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.surefire;
20
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import org.apache.maven.plugin.MojoExecutionException;
26 import org.apache.maven.plugin.MojoFailureException;
27 import org.apache.maven.plugin.surefire.AbstractSurefireMojoTest.Mojo;
28 import org.apache.maven.plugin.surefire.log.PluginConsoleLogger;
29 import org.apache.maven.surefire.api.suite.RunResult;
30 import org.apache.maven.surefire.api.testset.TestSetFailedException;
31 import org.apache.maven.surefire.booter.SurefireBooterForkException;
32 import org.junit.Rule;
33 import org.junit.Test;
34 import org.junit.rules.ExpectedException;
35 import org.mockito.ArgumentCaptor;
36 import org.slf4j.Logger;
37
38 import static java.util.Collections.addAll;
39 import static java.util.Collections.singleton;
40 import static org.apache.maven.plugin.surefire.SurefireHelper.escapeToPlatformPath;
41 import static org.apache.maven.plugin.surefire.SurefireHelper.reportExecution;
42 import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_WINDOWS;
43 import static org.assertj.core.api.Assertions.assertThat;
44 import static org.hamcrest.Matchers.containsString;
45 import static org.junit.Assume.assumeTrue;
46 import static org.mockito.ArgumentMatchers.anyString;
47 import static org.mockito.Mockito.verify;
48 import static org.mockito.Mockito.when;
49 import static org.powermock.api.mockito.PowerMockito.doNothing;
50 import static org.powermock.api.mockito.PowerMockito.mock;
51
52
53
54
55 public class SurefireHelperTest {
56
57 @Rule
58 public ExpectedException e = ExpectedException.none();
59
60 @Test
61 public void shouldReplaceForkNumberPath() {
62 File root = new File(System.getProperty("user.dir", ""));
63 File pathWithPlaceholder = new File(root, "${surefire.forkNumber}");
64 File changed = SurefireHelper.replaceForkThreadsInPath(pathWithPlaceholder, 5);
65 assertThat(changed.getPath()).isEqualTo(new File(root, "5").getPath());
66 }
67
68 @Test
69 public void shouldReplaceLongForkNumberPath() {
70 File root = new File(System.getProperty("user.dir", ""));
71 File subDir = new File(root, "reports-${surefire.forkNumber}");
72 File pathWithPlaceholder = new File(subDir, "subdir");
73 File changed = SurefireHelper.replaceForkThreadsInPath(pathWithPlaceholder, 5);
74 assertThat(changed.getPath()).isEqualTo(new File(new File(root, "reports-5"), "subdir").getPath());
75 }
76
77 @Test
78 public void shouldBeThreeDumpFiles() {
79 String[] dumps = SurefireHelper.getDumpFilesToPrint();
80 assertThat(dumps).hasSize(4);
81 assertThat(dumps).doesNotHaveDuplicates();
82 List<String> onlyStrings = new ArrayList<>();
83 addAll(onlyStrings, dumps);
84 onlyStrings.removeAll(singleton((String) null));
85 assertThat(onlyStrings).hasSize(4);
86 }
87
88 @Test
89 public void shouldCloneDumpFiles() {
90 String[] dumps1 = SurefireHelper.getDumpFilesToPrint();
91 String[] dumps2 = SurefireHelper.getDumpFilesToPrint();
92 assertThat(dumps1).isNotSameAs(dumps2);
93 }
94
95 @Test
96 public void testConstants() {
97 assertThat(SurefireHelper.DUMPSTREAM_FILENAME_FORMATTER)
98 .isEqualTo(SurefireHelper.DUMP_FILE_PREFIX + "%d.dumpstream");
99
100 assertThat(String.format(SurefireHelper.DUMPSTREAM_FILENAME_FORMATTER, 5))
101 .endsWith("-jvmRun5.dumpstream");
102 }
103
104 @Test
105 public void shouldEscapeWindowsPath() {
106 assumeTrue(IS_OS_WINDOWS);
107 String root = "X:\\path\\to\\project\\";
108 String pathToJar = "target\\surefire\\surefirebooter4942721306300108667.jar";
109 @SuppressWarnings("checkstyle:magicnumber")
110 int projectNameLength = 247 - root.length() - pathToJar.length();
111 StringBuilder projectDir = new StringBuilder();
112 for (int i = 0; i < projectNameLength; i++) {
113 projectDir.append('x');
114 }
115 String path = root + projectDir + "\\" + pathToJar;
116 String escaped = escapeToPlatformPath(path);
117 assertThat(escaped).isEqualTo("\\\\?\\" + path);
118
119 path = root + "\\" + pathToJar;
120 escaped = escapeToPlatformPath(path);
121 assertThat(escaped).isEqualTo(root + "\\" + pathToJar);
122 }
123
124 @Test
125 public void shouldHandleFailWithoutExitCode() throws Exception {
126 RunResult summary = new RunResult(0, 0, 0, 0);
127 Mojo plugin = new Mojo();
128 plugin.setTestFailureIgnore(true);
129
130 Logger logger = mock(Logger.class);
131 when(logger.isErrorEnabled()).thenReturn(true);
132 doNothing().when(logger).error(anyString());
133 TestSetFailedException exc = new TestSetFailedException("failure");
134 reportExecution(plugin, summary, new PluginConsoleLogger(logger), exc);
135 ArgumentCaptor<String> errorMessage = ArgumentCaptor.forClass(String.class);
136 verify(logger).error(errorMessage.capture());
137 assertThat(errorMessage.getValue()).contains("failure");
138 }
139
140 @Test
141 public void shouldHandleFailIfJvmNonZeroExitCode() throws Exception {
142 RunResult summary = new RunResult(0, 0, 0, 0);
143 Mojo plugin = new Mojo();
144 plugin.setTestFailureIgnore(true);
145
146 SurefireBooterForkException exc = new SurefireBooterForkException("Unrecognized option: -Xxxx");
147 e.expect(MojoExecutionException.class);
148 e.expectMessage(containsString("Unrecognized option: -Xxxx"));
149 reportExecution(plugin, summary, new PluginConsoleLogger(mock(Logger.class)), exc);
150 }
151
152 @Test
153 public void shouldHandleFailIfNoTests() throws Exception {
154 RunResult summary = new RunResult(0, 0, 0, 0);
155 Mojo plugin = new Mojo();
156 plugin.setFailIfNoTests(true);
157 e.expect(MojoFailureException.class);
158 e.expectMessage("No tests were executed! (Set -DfailIfNoTests=false to ignore this error.)");
159 reportExecution(plugin, summary, null, null);
160 }
161
162 @Test
163 public void shouldHandleTestFailure() throws Exception {
164 RunResult summary = new RunResult(1, 0, 1, 0);
165 e.expect(MojoFailureException.class);
166 e.expectMessage("There are test failures.\n\nSee null "
167 + "for the individual test results.\nSee dump files (if any exist) "
168 + "[date].dump, [date]-jvmRun[N].dump and [date].dumpstream.");
169 reportExecution(new Mojo(), summary, null, null);
170 }
171
172 @Test
173 public void failsIfThereAreTooManyFlakes() throws Exception {
174 RunResult summary = new RunResult(1, 0, 0, 0, 1);
175 Mojo reportParameters = new Mojo();
176 reportParameters.setFailOnFlakeCount(1);
177 e.expect(MojoFailureException.class);
178 e.expectMessage("There is 1 flake and failOnFlakeCount is set to 1.\n\nSee null "
179 + "for the individual test results.\nSee dump files (if any exist) "
180 + "[date].dump, [date]-jvmRun[N].dump and [date].dumpstream.");
181 reportExecution(reportParameters, summary, null, null);
182 }
183
184 @Test
185 public void reportsFailuresAndFlakes() throws Exception {
186 RunResult summary = new RunResult(1, 0, 1, 0, 2);
187 Mojo reportParameters = new Mojo();
188 reportParameters.setFailOnFlakeCount(1);
189 e.expect(MojoFailureException.class);
190 e.expectMessage("There are test failures.\nThere are 2 flakes and failOnFlakeCount is set to 1."
191 + "\n\nSee null "
192 + "for the individual test results.\nSee dump files (if any exist) "
193 + "[date].dump, [date]-jvmRun[N].dump and [date].dumpstream.");
194 reportExecution(reportParameters, summary, null, null);
195 }
196
197 @Test
198 public void passesIfFlakesAreWithinThreshold() throws Exception {
199 RunResult summary = new RunResult(1, 0, 0, 0, 1);
200 reportExecution(new Mojo(), summary, null, null);
201 }
202 }