1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.tradefed.util; 17 18 import static org.junit.Assert.assertEquals; 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertTrue; 21 import static org.junit.Assert.fail; 22 23 import com.android.tradefed.build.BuildInfo; 24 import com.android.tradefed.build.IBuildInfo; 25 import com.android.tradefed.invoker.IInvocationContext; 26 import com.android.tradefed.invoker.InvocationContext; 27 import com.android.tradefed.log.LogUtil.CLog; 28 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric; 29 import com.android.tradefed.result.FailureDescription; 30 import com.android.tradefed.result.ILogSaverListener; 31 import com.android.tradefed.result.ITestInvocationListener; 32 import com.android.tradefed.result.LogDataType; 33 import com.android.tradefed.result.LogFile; 34 import com.android.tradefed.result.TestDescription; 35 36 import org.easymock.Capture; 37 import org.easymock.EasyMock; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 import org.junit.runners.JUnit4; 41 42 import java.io.BufferedReader; 43 import java.io.File; 44 import java.io.IOException; 45 import java.io.InputStream; 46 import java.io.InputStreamReader; 47 import java.io.PrintWriter; 48 import java.net.Socket; 49 import java.util.HashMap; 50 import java.util.Map; 51 import java.util.Vector; 52 53 /** Unit Tests for {@link SubprocessTestResultsParser} */ 54 @RunWith(JUnit4.class) 55 public class SubprocessTestResultsParserTest { 56 57 private static final String TEST_TYPE_DIR = "testdata"; 58 private static final String SUBPROC_OUTPUT_FILE_1 = "subprocess1.txt"; 59 private static final String SUBPROC_OUTPUT_FILE_2 = "subprocess2.txt"; 60 61 /** 62 * Helper to read a file from the res/testdata directory and return its contents as a String[] 63 * 64 * @param filename the name of the file (without the extension) in the res/testdata directory 65 * @return a String[] of the 66 */ readInFile(String filename)67 private String[] readInFile(String filename) { 68 Vector<String> fileContents = new Vector<String>(); 69 try { 70 InputStream gtestResultStream1 = getClass().getResourceAsStream(File.separator + 71 TEST_TYPE_DIR + File.separator + filename); 72 BufferedReader reader = new BufferedReader(new InputStreamReader(gtestResultStream1)); 73 String line = null; 74 while ((line = reader.readLine()) != null) { 75 fileContents.add(line); 76 } 77 } 78 catch (NullPointerException e) { 79 CLog.e("Gest output file does not exist: " + filename); 80 } 81 catch (IOException e) { 82 CLog.e("Unable to read contents of gtest output file: " + filename); 83 } 84 return fileContents.toArray(new String[fileContents.size()]); 85 } 86 87 /** Tests the parser for cases of test failed, ignored, assumption failure */ 88 @Test testParse_randomEvents()89 public void testParse_randomEvents() throws Exception { 90 String[] contents = readInFile(SUBPROC_OUTPUT_FILE_1); 91 ITestInvocationListener mockRunListener = 92 EasyMock.createMock(ITestInvocationListener.class); 93 mockRunListener.testRunStarted( 94 EasyMock.eq("arm64-v8a CtsGestureTestCases"), 95 EasyMock.eq(4), 96 EasyMock.eq(0), 97 EasyMock.anyLong()); 98 mockRunListener.testStarted((TestDescription) EasyMock.anyObject(), EasyMock.anyLong()); 99 EasyMock.expectLastCall().times(4); 100 mockRunListener.testEnded( 101 (TestDescription) EasyMock.anyObject(), 102 EasyMock.anyLong(), 103 EasyMock.<HashMap<String, Metric>>anyObject()); 104 EasyMock.expectLastCall().times(4); 105 mockRunListener.testRunEnded( 106 EasyMock.anyLong(), EasyMock.<HashMap<String, Metric>>anyObject()); 107 EasyMock.expectLastCall().times(1); 108 mockRunListener.testIgnored((TestDescription) EasyMock.anyObject()); 109 EasyMock.expectLastCall(); 110 mockRunListener.testFailed( 111 (TestDescription) EasyMock.anyObject(), (String) EasyMock.anyObject()); 112 EasyMock.expectLastCall(); 113 mockRunListener.testAssumptionFailure( 114 (TestDescription) EasyMock.anyObject(), (String) EasyMock.anyObject()); 115 EasyMock.expectLastCall(); 116 EasyMock.replay(mockRunListener); 117 File tmp = FileUtil.createTempFile("sub", "unit"); 118 SubprocessTestResultsParser resultParser = null; 119 try { 120 resultParser = 121 new SubprocessTestResultsParser(mockRunListener, new InvocationContext()); 122 resultParser.processNewLines(contents); 123 EasyMock.verify(mockRunListener); 124 } finally { 125 StreamUtil.close(resultParser); 126 FileUtil.deleteFile(tmp); 127 } 128 } 129 130 /** Tests the parser for cases of test starting without closing. */ 131 @Test testParse_invalidEventOrder()132 public void testParse_invalidEventOrder() throws Exception { 133 String[] contents = readInFile(SUBPROC_OUTPUT_FILE_2); 134 ITestInvocationListener mockRunListener = 135 EasyMock.createMock(ITestInvocationListener.class); 136 mockRunListener.testRunStarted( 137 EasyMock.eq("arm64-v8a CtsGestureTestCases"), 138 EasyMock.eq(4), 139 EasyMock.eq(0), 140 EasyMock.anyLong()); 141 mockRunListener.testStarted((TestDescription) EasyMock.anyObject(), EasyMock.anyLong()); 142 EasyMock.expectLastCall().times(4); 143 mockRunListener.testEnded( 144 (TestDescription) EasyMock.anyObject(), 145 EasyMock.anyLong(), 146 EasyMock.<HashMap<String, Metric>>anyObject()); 147 EasyMock.expectLastCall().times(3); 148 mockRunListener.testRunFailed((FailureDescription) EasyMock.anyObject()); 149 EasyMock.expectLastCall().times(1); 150 mockRunListener.testRunEnded( 151 EasyMock.anyLong(), EasyMock.<HashMap<String, Metric>>anyObject()); 152 EasyMock.expectLastCall().times(1); 153 mockRunListener.testIgnored((TestDescription) EasyMock.anyObject()); 154 EasyMock.expectLastCall(); 155 mockRunListener.testAssumptionFailure( 156 (TestDescription) EasyMock.anyObject(), (String) EasyMock.anyObject()); 157 EasyMock.expectLastCall(); 158 EasyMock.replay(mockRunListener); 159 File tmp = FileUtil.createTempFile("sub", "unit"); 160 SubprocessTestResultsParser resultParser = null; 161 try { 162 resultParser = 163 new SubprocessTestResultsParser(mockRunListener, new InvocationContext()); 164 resultParser.processNewLines(contents); 165 EasyMock.verify(mockRunListener); 166 } finally { 167 StreamUtil.close(resultParser); 168 FileUtil.deleteFile(tmp); 169 } 170 } 171 172 /** Tests the parser for cases of test starting without closing. */ 173 @Test testParse_testNotStarted()174 public void testParse_testNotStarted() throws Exception { 175 ITestInvocationListener mockRunListener = 176 EasyMock.createMock(ITestInvocationListener.class); 177 mockRunListener.testRunStarted( 178 EasyMock.eq("arm64-v8a CtsGestureTestCases"), 179 EasyMock.eq(4), 180 EasyMock.eq(0), 181 EasyMock.anyLong()); 182 mockRunListener.testEnded( 183 (TestDescription) EasyMock.anyObject(), 184 EasyMock.anyLong(), 185 EasyMock.<HashMap<String, Metric>>anyObject()); 186 EasyMock.expectLastCall().times(1); 187 EasyMock.replay(mockRunListener); 188 File tmp = FileUtil.createTempFile("sub", "unit"); 189 SubprocessTestResultsParser resultParser = null; 190 try { 191 resultParser = 192 new SubprocessTestResultsParser(mockRunListener, new InvocationContext()); 193 String startRun = 194 "TEST_RUN_STARTED {\"testCount\":4,\"runName\":\"arm64-v8a " 195 + "CtsGestureTestCases\"}\n"; 196 FileUtil.writeToFile(startRun, tmp, true); 197 String testEnded = 198 "03-22 14:04:02 E/SubprocessResultsReporter: TEST_ENDED " 199 + "{\"end_time\":1489160958359,\"className\":\"android.gesture.cts." 200 + "GestureLibraryTest\",\"testName\":\"testGetGestures\",\"extra\":\"" 201 + "data\"}\n"; 202 FileUtil.writeToFile(testEnded, tmp, true); 203 resultParser.parseFile(tmp); 204 EasyMock.verify(mockRunListener); 205 } finally { 206 StreamUtil.close(resultParser); 207 FileUtil.deleteFile(tmp); 208 } 209 } 210 211 /** Tests the parser for a cases when there is no start/end time stamp. */ 212 @Test testParse_noTimeStamp()213 public void testParse_noTimeStamp() throws Exception { 214 ITestInvocationListener mockRunListener = 215 EasyMock.createMock(ITestInvocationListener.class); 216 mockRunListener.testRunStarted( 217 EasyMock.eq("arm64-v8a CtsGestureTestCases"), 218 EasyMock.eq(4), 219 EasyMock.eq(0), 220 EasyMock.anyLong()); 221 mockRunListener.testStarted(EasyMock.anyObject()); 222 mockRunListener.testEnded( 223 (TestDescription) EasyMock.anyObject(), 224 EasyMock.<HashMap<String, Metric>>anyObject()); 225 EasyMock.expectLastCall().times(1); 226 EasyMock.replay(mockRunListener); 227 File tmp = FileUtil.createTempFile("sub", "unit"); 228 SubprocessTestResultsParser resultParser = null; 229 try { 230 resultParser = 231 new SubprocessTestResultsParser(mockRunListener, new InvocationContext()); 232 String startRun = "TEST_RUN_STARTED {\"testCount\":4,\"runName\":\"arm64-v8a " 233 + "CtsGestureTestCases\"}\n"; 234 FileUtil.writeToFile(startRun, tmp, true); 235 String testStarted = 236 "03-22 14:04:02 E/SubprocessResultsReporter: TEST_STARTED " 237 + "{\"className\":\"android.gesture.cts." 238 + "GestureLibraryTest\",\"testName\":\"testGetGestures\"}\n"; 239 FileUtil.writeToFile(testStarted, tmp, true); 240 String testEnded = 241 "03-22 14:04:02 E/SubprocessResultsReporter: TEST_ENDED " 242 + "{\"className\":\"android.gesture.cts." 243 + "GestureLibraryTest\",\"testName\":\"testGetGestures\",\"extra\":\"" 244 + "data\"}\n"; 245 FileUtil.writeToFile(testEnded, tmp, true); 246 resultParser.parseFile(tmp); 247 EasyMock.verify(mockRunListener); 248 } finally { 249 StreamUtil.close(resultParser); 250 FileUtil.deleteFile(tmp); 251 } 252 } 253 254 /** Test injecting an invocation failure and verify the callback is called. */ 255 @Test testParse_invocationFailed()256 public void testParse_invocationFailed() throws Exception { 257 ITestInvocationListener mockRunListener = 258 EasyMock.createMock(ITestInvocationListener.class); 259 Capture<Throwable> cap = new Capture<Throwable>(); 260 mockRunListener.invocationFailed(EasyMock.capture(cap)); 261 EasyMock.replay(mockRunListener); 262 File tmp = FileUtil.createTempFile("sub", "unit"); 263 SubprocessTestResultsParser resultParser = null; 264 try { 265 resultParser = 266 new SubprocessTestResultsParser(mockRunListener, new InvocationContext()); 267 String cause = "com.android.tradefed.targetprep." 268 + "TargetSetupError: Not all target preparation steps completed\n\tat " 269 + "com.android.compatibility.common.tradefed.targetprep." 270 + "ApkInstrumentationPreparer.run(ApkInstrumentationPreparer.java:88)\n"; 271 String startRun = "03-23 11:50:12 E/SubprocessResultsReporter: " 272 + "INVOCATION_FAILED {\"cause\":\"com.android.tradefed.targetprep." 273 + "TargetSetupError: Not all target preparation steps completed\\n\\tat " 274 + "com.android.compatibility.common.tradefed.targetprep." 275 + "ApkInstrumentationPreparer.run(ApkInstrumentationPreparer.java:88)\\n\"}\n"; 276 FileUtil.writeToFile(startRun, tmp, true); 277 resultParser.parseFile(tmp); 278 EasyMock.verify(mockRunListener); 279 String expected = cap.getValue().getMessage(); 280 assertEquals(cause, expected); 281 } finally { 282 StreamUtil.close(resultParser); 283 FileUtil.deleteFile(tmp); 284 } 285 } 286 287 /** Report results when received from socket. */ 288 @Test testParser_receiveFromSocket()289 public void testParser_receiveFromSocket() throws Exception { 290 ITestInvocationListener mockRunListener = 291 EasyMock.createMock(ITestInvocationListener.class); 292 mockRunListener.testRunStarted( 293 EasyMock.eq("arm64-v8a CtsGestureTestCases"), 294 EasyMock.eq(4), 295 EasyMock.eq(0), 296 EasyMock.anyLong()); 297 mockRunListener.testEnded( 298 (TestDescription) EasyMock.anyObject(), 299 EasyMock.anyLong(), 300 EasyMock.<HashMap<String, Metric>>anyObject()); 301 EasyMock.expectLastCall().times(1); 302 EasyMock.replay(mockRunListener); 303 SubprocessTestResultsParser resultParser = null; 304 Socket socket = null; 305 try { 306 resultParser = 307 new SubprocessTestResultsParser(mockRunListener, true, new InvocationContext()); 308 socket = new Socket("localhost", resultParser.getSocketServerPort()); 309 if (!socket.isConnected()) { 310 fail("socket did not connect"); 311 } 312 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 313 String startRun = "TEST_RUN_STARTED {\"testCount\":4,\"runName\":\"arm64-v8a " 314 + "CtsGestureTestCases\"}\n"; 315 out.print(startRun); 316 out.flush(); 317 String testEnded = 318 "03-22 14:04:02 E/SubprocessResultsReporter: TEST_ENDED " 319 + "{\"end_time\":1489160958359,\"className\":\"android.gesture.cts." 320 + "GestureLibraryTest\",\"testName\":\"testGetGestures\",\"extra\":\"" 321 + "data\"}\n"; 322 out.print(testEnded); 323 out.flush(); 324 StreamUtil.close(socket); 325 assertTrue(resultParser.joinReceiver(500)); 326 EasyMock.verify(mockRunListener); 327 } finally { 328 StreamUtil.close(resultParser); 329 StreamUtil.close(socket); 330 } 331 } 332 333 /** When the receiver thread fails to join then an exception is thrown. */ 334 @Test testParser_failToJoin()335 public void testParser_failToJoin() throws Exception { 336 ITestInvocationListener mockRunListener = 337 EasyMock.createMock(ITestInvocationListener.class); 338 EasyMock.replay(mockRunListener); 339 SubprocessTestResultsParser resultParser = null; 340 try { 341 resultParser = 342 new SubprocessTestResultsParser(mockRunListener, true, new InvocationContext()); 343 assertFalse(resultParser.joinReceiver(50)); 344 EasyMock.verify(mockRunListener); 345 } finally { 346 StreamUtil.close(resultParser); 347 } 348 } 349 350 /** Tests that the parser can be joined immediately if no connection was established. */ 351 @Test testParser_noConnection()352 public void testParser_noConnection() throws Exception { 353 ITestInvocationListener listener = EasyMock.createMock(ITestInvocationListener.class); 354 EasyMock.replay(listener); 355 try (SubprocessTestResultsParser parser = 356 new SubprocessTestResultsParser(listener, true, new InvocationContext())) { 357 // returns immediately as a connection was not established 358 assertTrue(parser.joinReceiver(50, false)); 359 EasyMock.verify(listener); 360 } 361 } 362 363 /** Tests the parser receiving event on updating test tag. */ 364 @Test testParse_testTag()365 public void testParse_testTag() throws Exception { 366 final String subTestTag = "test_tag_in_subprocess"; 367 InvocationContext context = new InvocationContext(); 368 context.setTestTag("stub"); 369 370 ITestInvocationListener mockRunListener = 371 EasyMock.createMock(ITestInvocationListener.class); 372 EasyMock.replay(mockRunListener); 373 File tmp = FileUtil.createTempFile("sub", "unit"); 374 SubprocessTestResultsParser resultParser = null; 375 try { 376 resultParser = new SubprocessTestResultsParser(mockRunListener, false, context); 377 String testTagEvent = 378 String.format( 379 "INVOCATION_STARTED {\"testTag\": \"%s\",\"start_time\":250}", 380 subTestTag); 381 FileUtil.writeToFile(testTagEvent, tmp, true); 382 resultParser.parseFile(tmp); 383 EasyMock.verify(mockRunListener); 384 assertEquals(subTestTag, context.getTestTag()); 385 assertEquals(250l, resultParser.getStartTime().longValue()); 386 } finally { 387 StreamUtil.close(resultParser); 388 FileUtil.deleteFile(tmp); 389 } 390 } 391 392 /** Tests the parser smoothly handling case where there is no build info. */ 393 @Test testParse_testInvocationEndedWithoutBuildInfo()394 public void testParse_testInvocationEndedWithoutBuildInfo() throws Exception { 395 InvocationContext context = new InvocationContext(); 396 context.setTestTag("stub"); 397 398 ITestInvocationListener mockRunListener = 399 EasyMock.createMock(ITestInvocationListener.class); 400 EasyMock.replay(mockRunListener); 401 File tmp = FileUtil.createTempFile("sub", "unit"); 402 SubprocessTestResultsParser resultParser = null; 403 try { 404 resultParser = new SubprocessTestResultsParser(mockRunListener, false, context); 405 String event = "INVOCATION_ENDED {\"foo\": \"bar\"}"; 406 FileUtil.writeToFile(event, tmp, true); 407 resultParser.parseFile(tmp); 408 EasyMock.verify(mockRunListener); 409 } finally { 410 StreamUtil.close(resultParser); 411 FileUtil.deleteFile(tmp); 412 } 413 } 414 415 /** Tests the parser propagating up build attributes. */ 416 @Test testParse_testInvocationEnded()417 public void testParse_testInvocationEnded() throws Exception { 418 InvocationContext context = new InvocationContext(); 419 IBuildInfo info = new BuildInfo(); 420 context.setTestTag("stub"); 421 context.addDeviceBuildInfo("device1", info); 422 info.addBuildAttribute("baz", "qux"); 423 424 ITestInvocationListener mockRunListener = 425 EasyMock.createMock(ITestInvocationListener.class); 426 EasyMock.replay(mockRunListener); 427 File tmp = FileUtil.createTempFile("sub", "unit"); 428 SubprocessTestResultsParser resultParser = null; 429 try { 430 resultParser = new SubprocessTestResultsParser(mockRunListener, false, context); 431 String event = "INVOCATION_ENDED {\"foo\": \"bar\", \"baz\": \"wrong\"}"; 432 FileUtil.writeToFile(event, tmp, true); 433 resultParser.parseFile(tmp); 434 Map<String, String> attributes = info.getBuildAttributes(); 435 // foo=bar is propagated up 436 assertEquals("bar", attributes.get("foo")); 437 // baz=qux is not overwritten 438 assertEquals("qux", attributes.get("baz")); 439 EasyMock.verify(mockRunListener); 440 } finally { 441 StreamUtil.close(resultParser); 442 FileUtil.deleteFile(tmp); 443 } 444 } 445 446 /** Tests the parser should not overwrite the test tag in parent process if it's already set. */ 447 @Test testParse_testTagNotOverwrite()448 public void testParse_testTagNotOverwrite() throws Exception { 449 final String subTestTag = "test_tag_in_subprocess"; 450 final String parentTestTag = "test_tag_in_parent_process"; 451 InvocationContext context = new InvocationContext(); 452 context.setTestTag(parentTestTag); 453 454 ITestInvocationListener mockRunListener = 455 EasyMock.createMock(ITestInvocationListener.class); 456 EasyMock.replay(mockRunListener); 457 File tmp = FileUtil.createTempFile("sub", "unit"); 458 SubprocessTestResultsParser resultParser = null; 459 try { 460 resultParser = new SubprocessTestResultsParser(mockRunListener, false, context); 461 String testTagEvent = String.format("TEST_TAG %s", subTestTag); 462 FileUtil.writeToFile(testTagEvent, tmp, true); 463 resultParser.parseFile(tmp); 464 EasyMock.verify(mockRunListener); 465 assertEquals(parentTestTag, context.getTestTag()); 466 } finally { 467 StreamUtil.close(resultParser); 468 FileUtil.deleteFile(tmp); 469 } 470 } 471 472 /** Test that module start and end is properly parsed when reported. */ 473 @Test testParse_moduleStarted_end()474 public void testParse_moduleStarted_end() throws Exception { 475 ITestInvocationListener mockRunListener = 476 EasyMock.createMock(ITestInvocationListener.class); 477 mockRunListener.testModuleStarted(EasyMock.anyObject()); 478 mockRunListener.testModuleEnded(); 479 EasyMock.replay(mockRunListener); 480 IInvocationContext fakeModuleContext = new InvocationContext(); 481 File tmp = FileUtil.createTempFile("sub", "unit"); 482 SubprocessTestResultsParser resultParser = null; 483 File serializedModule = null; 484 try { 485 serializedModule = SerializationUtil.serialize(fakeModuleContext); 486 resultParser = 487 new SubprocessTestResultsParser(mockRunListener, new InvocationContext()); 488 String moduleStart = 489 String.format( 490 "TEST_MODULE_STARTED {\"moduleContextFileName\":\"%s\"}\n", 491 serializedModule.getAbsolutePath()); 492 FileUtil.writeToFile(moduleStart, tmp, true); 493 String moduleEnd = "TEST_MODULE_ENDED {}\n"; 494 FileUtil.writeToFile(moduleEnd, tmp, true); 495 496 resultParser.parseFile(tmp); 497 EasyMock.verify(mockRunListener); 498 } finally { 499 StreamUtil.close(resultParser); 500 FileUtil.deleteFile(tmp); 501 FileUtil.deleteFile(serializedModule); 502 } 503 } 504 505 /** Test that logAssociation event is properly passed and parsed. */ 506 @Test testParse_logAssociation()507 public void testParse_logAssociation() throws Exception { 508 ILogSaverListener mockRunListener = EasyMock.createMock(ILogSaverListener.class); 509 Capture<LogFile> capture = new Capture<>(); 510 mockRunListener.logAssociation( 511 EasyMock.eq("subprocess-dataname"), EasyMock.capture(capture)); 512 EasyMock.replay(mockRunListener); 513 LogFile logFile = new LogFile("path", "url", LogDataType.TEXT); 514 File serializedLogFile = null; 515 File tmp = FileUtil.createTempFile("sub", "unit"); 516 SubprocessTestResultsParser resultParser = null; 517 try { 518 serializedLogFile = SerializationUtil.serialize(logFile); 519 resultParser = 520 new SubprocessTestResultsParser(mockRunListener, new InvocationContext()); 521 String logAssociation = 522 String.format( 523 "LOG_ASSOCIATION {\"loggedFile\":\"%s\",\"dataName\":\"dataname\"}\n", 524 serializedLogFile.getAbsolutePath()); 525 FileUtil.writeToFile(logAssociation, tmp, true); 526 resultParser.parseFile(tmp); 527 EasyMock.verify(mockRunListener); 528 } finally { 529 StreamUtil.close(resultParser); 530 FileUtil.deleteFile(serializedLogFile); 531 FileUtil.deleteFile(tmp); 532 } 533 LogFile received = capture.getValue(); 534 assertEquals(logFile.getPath(), received.getPath()); 535 assertEquals(logFile.getUrl(), received.getUrl()); 536 assertEquals(logFile.getType(), received.getType()); 537 } 538 539 /** If a log comes from subprocess but was not uploaded (no URL), we relog it. */ 540 @Test testParse_logAssociation_notUploaded()541 public void testParse_logAssociation_notUploaded() throws Exception { 542 ILogSaverListener mockRunListener = EasyMock.createMock(ILogSaverListener.class); 543 mockRunListener.testLog( 544 EasyMock.eq("subprocess-dataname"), 545 EasyMock.eq(LogDataType.TEXT), 546 EasyMock.anyObject()); 547 EasyMock.replay(mockRunListener); 548 File log = FileUtil.createTempFile("dataname-log-assos", ".txt"); 549 LogFile logFile = new LogFile(log.getAbsolutePath(), null, LogDataType.TEXT); 550 File serializedLogFile = null; 551 File tmp = FileUtil.createTempFile("sub", "unit"); 552 SubprocessTestResultsParser resultParser = null; 553 try { 554 serializedLogFile = SerializationUtil.serialize(logFile); 555 resultParser = 556 new SubprocessTestResultsParser(mockRunListener, new InvocationContext()); 557 String logAssociation = 558 String.format( 559 "LOG_ASSOCIATION {\"loggedFile\":\"%s\",\"dataName\":\"dataname\"}\n", 560 serializedLogFile.getAbsolutePath()); 561 FileUtil.writeToFile(logAssociation, tmp, true); 562 resultParser.parseFile(tmp); 563 EasyMock.verify(mockRunListener); 564 } finally { 565 StreamUtil.close(resultParser); 566 FileUtil.deleteFile(serializedLogFile); 567 FileUtil.deleteFile(tmp); 568 FileUtil.deleteFile(log); 569 } 570 } 571 572 @Test testParse_logAssociation_zipped()573 public void testParse_logAssociation_zipped() throws Exception { 574 ILogSaverListener mockRunListener = EasyMock.createMock(ILogSaverListener.class); 575 mockRunListener.testLog( 576 EasyMock.eq("subprocess-dataname"), 577 EasyMock.eq(LogDataType.TEXT), 578 EasyMock.anyObject()); 579 EasyMock.replay(mockRunListener); 580 File logDir = FileUtil.createTempDir("log-assos-dir"); 581 File log = FileUtil.createTempFile("dataname-log-assos", ".txt", logDir); 582 File zipLog = ZipUtil.createZip(logDir); 583 LogFile logFile = new LogFile(zipLog.getAbsolutePath(), null, LogDataType.TEXT); 584 File serializedLogFile = null; 585 File tmp = FileUtil.createTempFile("sub", "unit"); 586 SubprocessTestResultsParser resultParser = null; 587 try { 588 serializedLogFile = SerializationUtil.serialize(logFile); 589 resultParser = 590 new SubprocessTestResultsParser(mockRunListener, new InvocationContext()); 591 String logAssociation = 592 String.format( 593 "LOG_ASSOCIATION {\"loggedFile\":\"%s\",\"dataName\":\"dataname\"}\n", 594 serializedLogFile.getAbsolutePath()); 595 FileUtil.writeToFile(logAssociation, tmp, true); 596 resultParser.parseFile(tmp); 597 EasyMock.verify(mockRunListener); 598 } finally { 599 StreamUtil.close(resultParser); 600 FileUtil.deleteFile(serializedLogFile); 601 FileUtil.deleteFile(tmp); 602 FileUtil.deleteFile(log); 603 FileUtil.recursiveDelete(logDir); 604 FileUtil.deleteFile(zipLog); 605 } 606 } 607 608 @Test testParse_avoidDoubleLog()609 public void testParse_avoidDoubleLog() throws Exception { 610 ILogSaverListener mockRunListener = EasyMock.createMock(ILogSaverListener.class); 611 mockRunListener.testLog( 612 EasyMock.eq("subprocess-dataname"), 613 EasyMock.eq(LogDataType.TEXT), 614 EasyMock.anyObject()); 615 EasyMock.replay(mockRunListener); 616 File testLogFile = FileUtil.createTempFile("dataname", ".txt"); 617 File testLogFile2 = FileUtil.createTempFile("dataname", ".txt"); 618 LogFile logFile = new LogFile(testLogFile.getAbsolutePath(), "", LogDataType.TEXT); 619 File serializedLogFile = null; 620 File tmp = FileUtil.createTempFile("sub", "unit"); 621 SubprocessTestResultsParser resultParser = null; 622 try { 623 serializedLogFile = SerializationUtil.serialize(logFile); 624 resultParser = 625 new SubprocessTestResultsParser(mockRunListener, new InvocationContext()); 626 resultParser.setIgnoreTestLog(false); 627 String logAssociation = 628 String.format( 629 "TEST_LOG {\"dataType\":\"TEXT\",\"dataName\":\"dataname\"," 630 + "\"dataFile\":\"%s\"}'\n" 631 + "LOG_ASSOCIATION {\"loggedFile\":\"%s\"," 632 + "\"dataName\":\"dataname\"}\n", 633 testLogFile2.getAbsolutePath(), serializedLogFile.getAbsolutePath()); 634 FileUtil.writeToFile(logAssociation, tmp, true); 635 resultParser.parseFile(tmp); 636 EasyMock.verify(mockRunListener); 637 } finally { 638 StreamUtil.close(resultParser); 639 FileUtil.deleteFile(serializedLogFile); 640 FileUtil.deleteFile(tmp); 641 FileUtil.deleteFile(testLogFile); 642 FileUtil.deleteFile(testLogFile2); 643 } 644 } 645 } 646