blob: 0def58e9a225007db18bb700bd06d865f8c2ec3f [file] [log] [blame]
Eran Shalomf1db75c2018-08-27 07:09:19 -07001// Copyright 2015 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.devtools.build.lib.runtime;
16
Googlerba6fdb92018-12-08 06:29:58 -080017import static com.google.common.truth.Truth.assertThat;
Googlera6705772019-05-28 09:39:18 -070018import static org.mockito.ArgumentMatchers.any;
Googlerba6fdb92018-12-08 06:29:58 -080019import static org.mockito.Mockito.mock;
Eran Shalomf1db75c2018-08-27 07:09:19 -070020import static org.mockito.Mockito.never;
ichern8ec182a2020-01-08 05:29:11 -080021import static org.mockito.Mockito.times;
Eran Shalomf1db75c2018-08-27 07:09:19 -070022import static org.mockito.Mockito.verify;
23import static org.mockito.Mockito.when;
24
ichern8ec182a2020-01-08 05:29:11 -080025import com.google.common.collect.ImmutableList;
Eran Shalomf1db75c2018-08-27 07:09:19 -070026import com.google.common.collect.ImmutableMap;
Googlerba6fdb92018-12-08 06:29:58 -080027import com.google.common.collect.ImmutableSet;
ichern8ec182a2020-01-08 05:29:11 -080028import com.google.common.collect.ImmutableSortedSet;
Eran Shalomf1db75c2018-08-27 07:09:19 -070029import com.google.devtools.build.lib.cmdline.Label;
Googlerba6fdb92018-12-08 06:29:58 -080030import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
Eran Shalomf1db75c2018-08-27 07:09:19 -070031import com.google.devtools.build.lib.exec.ExecutionOptions;
jcaterd990df52020-04-07 04:38:15 -070032import com.google.devtools.build.lib.exec.ExecutionOptions.TestSummaryFormat;
Eran Shalomf1db75c2018-08-27 07:09:19 -070033import com.google.devtools.build.lib.runtime.TerminalTestResultNotifier.TestSummaryOptions;
34import com.google.devtools.build.lib.util.io.AnsiTerminalPrinter;
nharmataccc42952018-10-25 15:39:26 -070035import com.google.devtools.build.lib.vfs.Path;
Eran Shalomf1db75c2018-08-27 07:09:19 -070036import com.google.devtools.build.lib.view.test.TestStatus.BlazeTestStatus;
37import com.google.devtools.build.lib.view.test.TestStatus.TestCase;
38import com.google.devtools.build.lib.view.test.TestStatus.TestCase.Status;
39import com.google.devtools.common.options.OptionsParsingResult;
Eran Shalomf1db75c2018-08-27 07:09:19 -070040import java.util.Collections;
ichern8ec182a2020-01-08 05:29:11 -080041import java.util.Comparator;
Googlerba6fdb92018-12-08 06:29:58 -080042import java.util.List;
Eran Shalomf1db75c2018-08-27 07:09:19 -070043import org.junit.Test;
44import org.junit.runner.RunWith;
45import org.junit.runners.JUnit4;
Googlerba6fdb92018-12-08 06:29:58 -080046import org.mockito.ArgumentCaptor;
Eran Shalomf1db75c2018-08-27 07:09:19 -070047
Googlerba6fdb92018-12-08 06:29:58 -080048/** Tests for {@link TerminalTestResultNotifier}. */
Eran Shalomf1db75c2018-08-27 07:09:19 -070049@RunWith(JUnit4.class)
Googlerba6fdb92018-12-08 06:29:58 -080050public final class TerminalTestResultNotifierTest {
Eran Shalomf1db75c2018-08-27 07:09:19 -070051
ulfjack7c20af32020-01-15 07:59:02 -080052 private static final String SOME_TARGETS_ARE_MISSING_TEST_CASES_DISCLAIMER =
53 "some targets did not have test case information";
Eran Shalomf1db75c2018-08-27 07:09:19 -070054
Googlerba6fdb92018-12-08 06:29:58 -080055 private final OptionsParsingResult optionsParsingResult = mock(OptionsParsingResult.class);
56 private final AnsiTerminalPrinter ansiTerminalPrinter = mock(AnsiTerminalPrinter.class);
57
58 private BlazeTestStatus targetStatus;
59 private int numFailedTestCases;
ulfjack7c20af32020-01-15 07:59:02 -080060 private int numUnknownTestCases;
Googlerba6fdb92018-12-08 06:29:58 -080061 private int numTotalTestCases;
62 private TestSummaryFormat testSummaryFormat;
63
64 @Test
65 public void testCaseOption_allPass() throws Exception {
jcaterd990df52020-04-07 04:38:15 -070066 testSummaryFormat = ExecutionOptions.TestSummaryFormat.TESTCASE;
Googlerba6fdb92018-12-08 06:29:58 -080067 numFailedTestCases = 0;
68 numTotalTestCases = 10;
69 targetStatus = BlazeTestStatus.PASSED;
70
71 printTestCaseSummary();
72
73 String printed = getPrintedMessage();
74 assertThat(printed).contains(info("10 passing"));
75 assertThat(printed).contains("0 failing");
76 assertThat(printed).contains("out of 10 test cases");
ulfjack7c20af32020-01-15 07:59:02 -080077 assertThat(printed).doesNotContain(SOME_TARGETS_ARE_MISSING_TEST_CASES_DISCLAIMER);
Googlerba6fdb92018-12-08 06:29:58 -080078 assertThat(printed).doesNotContain(AnsiTerminalPrinter.Mode.ERROR.toString());
79 }
80
81 @Test
82 public void testCaseOption_allPassButTargetFails() throws Exception {
jcaterd990df52020-04-07 04:38:15 -070083 testSummaryFormat = ExecutionOptions.TestSummaryFormat.TESTCASE;
Googlerba6fdb92018-12-08 06:29:58 -080084 numFailedTestCases = 0;
ulfjack7c20af32020-01-15 07:59:02 -080085 numUnknownTestCases = 10;
Googlerba6fdb92018-12-08 06:29:58 -080086 numTotalTestCases = 10;
87 targetStatus = BlazeTestStatus.FAILED;
88
89 printTestCaseSummary();
90
91 String printed = getPrintedMessage();
ulfjack7c20af32020-01-15 07:59:02 -080092 assertThat(printed).contains("0 passing");
Googlerba6fdb92018-12-08 06:29:58 -080093 assertThat(printed).contains("0 failing");
94 assertThat(printed).contains("out of 10 test cases");
ulfjack7c20af32020-01-15 07:59:02 -080095 assertThat(printed).contains(SOME_TARGETS_ARE_MISSING_TEST_CASES_DISCLAIMER);
Googlerba6fdb92018-12-08 06:29:58 -080096 assertThat(printed).doesNotContain(AnsiTerminalPrinter.Mode.ERROR.toString());
97 }
98
99 @Test
100 public void testCaseOption_someFail() throws Exception {
jcaterd990df52020-04-07 04:38:15 -0700101 testSummaryFormat = ExecutionOptions.TestSummaryFormat.TESTCASE;
Googlerba6fdb92018-12-08 06:29:58 -0800102 numFailedTestCases = 2;
ulfjack7c20af32020-01-15 07:59:02 -0800103 numUnknownTestCases = 0;
Googlerba6fdb92018-12-08 06:29:58 -0800104 numTotalTestCases = 10;
105 targetStatus = BlazeTestStatus.FAILED;
106
107 printTestCaseSummary();
108
109 String printed = getPrintedMessage();
110 assertThat(printed).contains(info("8 passing"));
111 assertThat(printed).contains(error("2 failing"));
112 assertThat(printed).contains("out of 10 test cases");
ulfjack7c20af32020-01-15 07:59:02 -0800113 assertThat(printed).doesNotContain(SOME_TARGETS_ARE_MISSING_TEST_CASES_DISCLAIMER);
Googlerba6fdb92018-12-08 06:29:58 -0800114 }
115
116 @Test
ichern8ec182a2020-01-08 05:29:11 -0800117 public void shortOption_someFailToBuild() throws Exception {
jcaterd990df52020-04-07 04:38:15 -0700118 testSummaryFormat = ExecutionOptions.TestSummaryFormat.SHORT;
ichern8ec182a2020-01-08 05:29:11 -0800119 numFailedTestCases = 0;
120 int numFailedToBuildTestCases = TerminalTestResultNotifier.NUM_FAILED_TO_BUILD + 1;
ulfjack7c20af32020-01-15 07:59:02 -0800121 numUnknownTestCases = 0;
ichern8ec182a2020-01-08 05:29:11 -0800122 numTotalTestCases = 10;
123 targetStatus = BlazeTestStatus.FAILED_TO_BUILD;
124
125 printFailedToBuildSummaries();
126
127 String skippedMessage = getPrintedMessage();
128 assertThat(skippedMessage).isEqualTo("(Skipping other failed to build tests)");
129
130 ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
131 verify(ansiTerminalPrinter, times(numFailedToBuildTestCases)).print(messageCaptor.capture());
132 List<String> values = messageCaptor.getAllValues();
133
134 for (int i = 0; i < numFailedToBuildTestCases - 1; i++) {
135 String message = values.get(i);
136 assertThat(message).contains("//foo/bar:baz");
137 assertThat(message).contains(BlazeTestStatus.FAILED_TO_BUILD.toString().replace('_', ' '));
138 }
139
140 String last = values.get(numFailedToBuildTestCases - 1);
141 assertThat(last).contains("Executed 0 out of 6 tests");
142 assertThat(last).contains(numFailedToBuildTestCases + " fail to build");
143 }
144
145 @Test
Googlerba6fdb92018-12-08 06:29:58 -0800146 public void testCaseOption_allFail() throws Exception {
jcaterd990df52020-04-07 04:38:15 -0700147 testSummaryFormat = ExecutionOptions.TestSummaryFormat.TESTCASE;
Googlerba6fdb92018-12-08 06:29:58 -0800148 numFailedTestCases = 10;
ulfjack7c20af32020-01-15 07:59:02 -0800149 numUnknownTestCases = 0;
Googlerba6fdb92018-12-08 06:29:58 -0800150 numTotalTestCases = 10;
151 targetStatus = BlazeTestStatus.FAILED;
152
153 printTestCaseSummary();
154
155 String printed = getPrintedMessage();
156 assertThat(printed).contains("0 passing");
157 assertThat(printed).contains(error("10 failing"));
158 assertThat(printed).contains("out of 10 test cases");
ulfjack7c20af32020-01-15 07:59:02 -0800159 assertThat(printed).doesNotContain(SOME_TARGETS_ARE_MISSING_TEST_CASES_DISCLAIMER);
Googlerba6fdb92018-12-08 06:29:58 -0800160 assertThat(printed).doesNotContain(AnsiTerminalPrinter.Mode.INFO.toString());
161 }
162
163 @Test
164 public void detailedOption_allPass() throws Exception {
jcaterd990df52020-04-07 04:38:15 -0700165 testSummaryFormat = ExecutionOptions.TestSummaryFormat.DETAILED;
Googlerba6fdb92018-12-08 06:29:58 -0800166 numFailedTestCases = 0;
ulfjack7c20af32020-01-15 07:59:02 -0800167 numUnknownTestCases = 0;
Googlerba6fdb92018-12-08 06:29:58 -0800168 numTotalTestCases = 10;
169 targetStatus = BlazeTestStatus.PASSED;
170
171 printTestCaseSummary();
172
173 String printed = getPrintedMessage();
174 assertThat(printed).contains(info("10 passing"));
175 assertThat(printed).contains("0 failing");
176 assertThat(printed).contains("out of 10 test cases");
ulfjack7c20af32020-01-15 07:59:02 -0800177 assertThat(printed).doesNotContain(SOME_TARGETS_ARE_MISSING_TEST_CASES_DISCLAIMER);
Googlerba6fdb92018-12-08 06:29:58 -0800178 assertThat(printed).doesNotContain(AnsiTerminalPrinter.Mode.ERROR.toString());
179 }
180
181 @Test
182 public void detailedOption_allPassButTargetFails() throws Exception {
jcaterd990df52020-04-07 04:38:15 -0700183 testSummaryFormat = ExecutionOptions.TestSummaryFormat.DETAILED;
Googlerba6fdb92018-12-08 06:29:58 -0800184 numFailedTestCases = 0;
ulfjack7c20af32020-01-15 07:59:02 -0800185 numUnknownTestCases = 10;
Googlerba6fdb92018-12-08 06:29:58 -0800186 numTotalTestCases = 10;
187 targetStatus = BlazeTestStatus.FAILED;
188
189 printTestCaseSummary();
190
191 String printed = getPrintedMessage();
ulfjack7c20af32020-01-15 07:59:02 -0800192 assertThat(printed).contains("0 passing");
Googlerba6fdb92018-12-08 06:29:58 -0800193 assertThat(printed).contains("0 failing");
194 assertThat(printed).contains("out of 10 test cases");
ulfjack7c20af32020-01-15 07:59:02 -0800195 assertThat(printed).contains(SOME_TARGETS_ARE_MISSING_TEST_CASES_DISCLAIMER);
Googlerba6fdb92018-12-08 06:29:58 -0800196 assertThat(printed).doesNotContain(AnsiTerminalPrinter.Mode.ERROR.toString());
197 }
198
199 @Test
200 public void detailedOption_someFail() throws Exception {
jcaterd990df52020-04-07 04:38:15 -0700201 testSummaryFormat = ExecutionOptions.TestSummaryFormat.DETAILED;
Googlerba6fdb92018-12-08 06:29:58 -0800202 numFailedTestCases = 2;
ulfjack7c20af32020-01-15 07:59:02 -0800203 numUnknownTestCases = 0;
Googlerba6fdb92018-12-08 06:29:58 -0800204 numTotalTestCases = 10;
205 targetStatus = BlazeTestStatus.FAILED;
206
207 printTestCaseSummary();
208
209 String printed = getPrintedMessage();
210 assertThat(printed).contains(info("8 passing"));
211 assertThat(printed).contains(error("2 failing"));
212 assertThat(printed).contains("out of 10 test cases");
ulfjack7c20af32020-01-15 07:59:02 -0800213 assertThat(printed).doesNotContain(SOME_TARGETS_ARE_MISSING_TEST_CASES_DISCLAIMER);
Googlerba6fdb92018-12-08 06:29:58 -0800214 }
215
216 @Test
217 public void detailedOption_allFail() throws Exception {
jcaterd990df52020-04-07 04:38:15 -0700218 testSummaryFormat = ExecutionOptions.TestSummaryFormat.DETAILED;
Googlerba6fdb92018-12-08 06:29:58 -0800219 numFailedTestCases = 10;
ulfjack7c20af32020-01-15 07:59:02 -0800220 numUnknownTestCases = 0;
Googlerba6fdb92018-12-08 06:29:58 -0800221 numTotalTestCases = 10;
222 targetStatus = BlazeTestStatus.FAILED;
223
224 printTestCaseSummary();
225
226 String printed = getPrintedMessage();
227 assertThat(printed).contains("0 passing");
228 assertThat(printed).contains(error("10 failing"));
229 assertThat(printed).contains("out of 10 test cases");
ulfjack7c20af32020-01-15 07:59:02 -0800230 assertThat(printed).doesNotContain(SOME_TARGETS_ARE_MISSING_TEST_CASES_DISCLAIMER);
Googlerba6fdb92018-12-08 06:29:58 -0800231 assertThat(printed).doesNotContain(AnsiTerminalPrinter.Mode.INFO.toString());
232 }
233
234 @Test
235 public void shortOption_noSummaryPrinted() throws Exception {
jcaterd990df52020-04-07 04:38:15 -0700236 testSummaryFormat = ExecutionOptions.TestSummaryFormat.SHORT;
Googlerba6fdb92018-12-08 06:29:58 -0800237 numFailedTestCases = 2;
ulfjack7c20af32020-01-15 07:59:02 -0800238 numUnknownTestCases = 0;
Googlerba6fdb92018-12-08 06:29:58 -0800239 numTotalTestCases = 10;
240 targetStatus = BlazeTestStatus.FAILED;
241
242 printTestCaseSummary();
243
244 verifyNoSummaryPrinted();
245 }
246
247 @Test
248 public void terseOption_noSummaryPrinted() throws Exception {
jcaterd990df52020-04-07 04:38:15 -0700249 testSummaryFormat = ExecutionOptions.TestSummaryFormat.TERSE;
Googlerba6fdb92018-12-08 06:29:58 -0800250 numFailedTestCases = 2;
ulfjack7c20af32020-01-15 07:59:02 -0800251 numUnknownTestCases = 0;
Googlerba6fdb92018-12-08 06:29:58 -0800252 numTotalTestCases = 10;
253 targetStatus = BlazeTestStatus.FAILED;
254
255 printTestCaseSummary();
256
257 verifyNoSummaryPrinted();
258 }
259
260 @Test
261 public void noneOption_noSummaryPrinted() throws Exception {
jcaterd990df52020-04-07 04:38:15 -0700262 testSummaryFormat = ExecutionOptions.TestSummaryFormat.NONE;
Googlerba6fdb92018-12-08 06:29:58 -0800263 numFailedTestCases = 2;
ulfjack7c20af32020-01-15 07:59:02 -0800264 numUnknownTestCases = 0;
Googlerba6fdb92018-12-08 06:29:58 -0800265 numTotalTestCases = 10;
266 targetStatus = BlazeTestStatus.FAILED;
267
268 printTestCaseSummary();
269
270 verifyNoSummaryPrinted();
271 }
272
ichern8ec182a2020-01-08 05:29:11 -0800273 private void printFailedToBuildSummaries() throws LabelSyntaxException {
274 ExecutionOptions executionOptions = ExecutionOptions.DEFAULTS;
275 executionOptions.testSummary = testSummaryFormat;
276 when(optionsParsingResult.getOptions(ExecutionOptions.class)).thenReturn(executionOptions);
277 TestSummaryOptions testSummaryOptions = new TestSummaryOptions();
278 testSummaryOptions.verboseSummary = true;
279 when(optionsParsingResult.getOptions(TestSummaryOptions.class)).thenReturn(testSummaryOptions);
280
281 ImmutableSortedSet.Builder<TestSummary> builder =
282 ImmutableSortedSet.orderedBy(Comparator.comparing(o -> o.getLabel().getName()));
283 for (int i = 0; i < TerminalTestResultNotifier.NUM_FAILED_TO_BUILD + 1; i++) {
284 TestSummary testSummary = mock(TestSummary.class);
285 when(testSummary.getTotalTestCases()).thenReturn(0);
286
287 Label labelA = Label.parseAbsolute("//foo/bar:baz" + i, ImmutableMap.of());
288 when(testSummary.getFailedTestCases()).thenReturn(ImmutableList.of());
289 when(testSummary.getStatus()).thenReturn(BlazeTestStatus.FAILED_TO_BUILD);
290 when(testSummary.getLabel()).thenReturn(labelA);
291
292 builder.add(testSummary);
293 }
294
295 TerminalTestResultNotifier terminalTestResultNotifier =
296 new TerminalTestResultNotifier(
297 ansiTerminalPrinter, Path::getPathString, optionsParsingResult);
298 terminalTestResultNotifier.notify(builder.build(), 0);
299 }
300
Googlerba6fdb92018-12-08 06:29:58 -0800301 private void printTestCaseSummary() throws LabelSyntaxException {
Eran Shalomf1db75c2018-08-27 07:09:19 -0700302 ExecutionOptions executionOptions = ExecutionOptions.DEFAULTS;
Googlerba6fdb92018-12-08 06:29:58 -0800303 executionOptions.testSummary = testSummaryFormat;
Eran Shalomf1db75c2018-08-27 07:09:19 -0700304 when(optionsParsingResult.getOptions(ExecutionOptions.class)).thenReturn(executionOptions);
Eran Shalomf1db75c2018-08-27 07:09:19 -0700305 TestSummaryOptions testSummaryOptions = new TestSummaryOptions();
306 testSummaryOptions.verboseSummary = true;
307 when(optionsParsingResult.getOptions(TestSummaryOptions.class)).thenReturn(testSummaryOptions);
Eran Shalomf1db75c2018-08-27 07:09:19 -0700308
Googlerba6fdb92018-12-08 06:29:58 -0800309 TestSummary testSummary = mock(TestSummary.class);
310 when(testSummary.getTotalTestCases()).thenReturn(numTotalTestCases);
ulfjack7c20af32020-01-15 07:59:02 -0800311 when(testSummary.getUnkownTestCases()).thenReturn(numUnknownTestCases);
Eran Shalomf1db75c2018-08-27 07:09:19 -0700312 TestCase failedTestCase = TestCase.newBuilder().setStatus(Status.FAILED).build();
Googlerba6fdb92018-12-08 06:29:58 -0800313 List<TestCase> failedTestCases = Collections.nCopies(numFailedTestCases, failedTestCase);
Eran Shalomf1db75c2018-08-27 07:09:19 -0700314
315 Label labelA = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
Googlerba6fdb92018-12-08 06:29:58 -0800316 when(testSummary.getFailedTestCases()).thenReturn(failedTestCases);
317 when(testSummary.getStatus()).thenReturn(targetStatus);
Eran Shalomf1db75c2018-08-27 07:09:19 -0700318 when(testSummary.getLabel()).thenReturn(labelA);
319
Googlerba6fdb92018-12-08 06:29:58 -0800320 TerminalTestResultNotifier terminalTestResultNotifier =
321 new TerminalTestResultNotifier(
322 ansiTerminalPrinter, Path::getPathString, optionsParsingResult);
323 terminalTestResultNotifier.notify(ImmutableSet.of(testSummary), 1);
Eran Shalomf1db75c2018-08-27 07:09:19 -0700324 }
325
Googlerba6fdb92018-12-08 06:29:58 -0800326 private String getPrintedMessage() {
327 ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
328 verify(ansiTerminalPrinter).printLn(messageCaptor.capture());
329 return messageCaptor.getValue();
Eran Shalomf1db75c2018-08-27 07:09:19 -0700330 }
331
Googlerba6fdb92018-12-08 06:29:58 -0800332 private void verifyNoSummaryPrinted() {
333 verify(ansiTerminalPrinter, never()).printLn(any());
Eran Shalomf1db75c2018-08-27 07:09:19 -0700334 }
335
Googlerba6fdb92018-12-08 06:29:58 -0800336 private static String info(String message) {
337 return AnsiTerminalPrinter.Mode.INFO + message + AnsiTerminalPrinter.Mode.DEFAULT;
Eran Shalomf1db75c2018-08-27 07:09:19 -0700338 }
339
Googlerba6fdb92018-12-08 06:29:58 -0800340 private static String error(String message) {
341 return AnsiTerminalPrinter.Mode.ERROR + message + AnsiTerminalPrinter.Mode.DEFAULT;
Eran Shalomf1db75c2018-08-27 07:09:19 -0700342 }
343}