1 /* 2 * Copyright (C) 2018 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.compatibility.common.tradefed.result.suite; 17 18 import com.android.annotations.VisibleForTesting; 19 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; 20 import com.android.compatibility.common.util.DeviceInfo; 21 import com.android.compatibility.common.util.ResultHandler; 22 import com.android.compatibility.common.util.ResultUploader; 23 import com.android.tradefed.build.IBuildInfo; 24 import com.android.tradefed.cluster.SubprocessConfigBuilder; 25 import com.android.tradefed.config.IConfiguration; 26 import com.android.tradefed.config.Option; 27 import com.android.tradefed.config.OptionClass; 28 import com.android.tradefed.invoker.IInvocationContext; 29 import com.android.tradefed.log.LogUtil.CLog; 30 import com.android.tradefed.result.FileInputStreamSource; 31 import com.android.tradefed.result.ILogSaver; 32 import com.android.tradefed.result.ILogSaverListener; 33 import com.android.tradefed.result.ITestInvocationListener; 34 import com.android.tradefed.result.ITestSummaryListener; 35 import com.android.tradefed.result.InputStreamSource; 36 import com.android.tradefed.result.LogDataType; 37 import com.android.tradefed.result.LogFile; 38 import com.android.tradefed.result.LogFileSaver; 39 import com.android.tradefed.result.SnapshotInputStreamSource; 40 import com.android.tradefed.result.TestRunResult; 41 import com.android.tradefed.result.TestSummary; 42 import com.android.tradefed.result.suite.IFormatterGenerator; 43 import com.android.tradefed.result.suite.SuiteResultReporter; 44 import com.android.tradefed.result.suite.XmlFormattedGeneratorReporter; 45 import com.android.tradefed.util.FileUtil; 46 import com.android.tradefed.util.StreamUtil; 47 import com.android.tradefed.util.ZipUtil; 48 49 import java.io.File; 50 import java.io.FileInputStream; 51 import java.io.FileNotFoundException; 52 import java.io.FileOutputStream; 53 import java.io.IOException; 54 import java.io.InputStream; 55 import java.io.OutputStream; 56 import java.nio.file.Files; 57 import java.nio.file.Path; 58 import java.util.Collection; 59 import java.util.HashMap; 60 import java.util.HashSet; 61 import java.util.LinkedHashMap; 62 import java.util.List; 63 import java.util.Map; 64 import java.util.Set; 65 66 import javax.xml.transform.Transformer; 67 import javax.xml.transform.TransformerException; 68 import javax.xml.transform.TransformerFactory; 69 import javax.xml.transform.stream.StreamResult; 70 import javax.xml.transform.stream.StreamSource; 71 72 /** 73 * Extension of {@link XmlFormattedGeneratorReporter} and {@link SuiteResultReporter} to handle 74 * Compatibility specific format and operations. 75 */ 76 @OptionClass(alias = "result-reporter") 77 public class CertificationSuiteResultReporter extends XmlFormattedGeneratorReporter 78 implements ITestSummaryListener { 79 80 // The known existing variant of suites. 81 // Adding a new variant requires approval from Android Partner team and Test Harness team. 82 private enum SuiteVariant { 83 CTS_ON_GSI("CTS_ON_GSI", "cts-on-gsi"); 84 85 private final String mReportDisplayName; 86 private final String mConfigName; 87 SuiteVariant(String reportName, String configName)88 private SuiteVariant(String reportName, String configName) { 89 mReportDisplayName = reportName; 90 mConfigName = configName; 91 } 92 getReportDisplayName()93 public String getReportDisplayName() { 94 return mReportDisplayName; 95 } 96 getConfigName()97 public String getConfigName() { 98 return mConfigName; 99 } 100 } 101 102 public static final String LATEST_LINK_NAME = "latest"; 103 public static final String SUMMARY_FILE = "invocation_summary.txt"; 104 public static final String HTLM_REPORT_NAME = "test_result.html"; 105 public static final String REPORT_XSL_FILE_NAME = "compatibility_result.xsl"; 106 public static final String FAILURE_REPORT_NAME = "test_result_failures_suite.html"; 107 public static final String FAILURE_XSL_FILE_NAME = "compatibility_failures.xsl"; 108 109 public static final String BUILD_FINGERPRINT = "build_fingerprint"; 110 111 @Option(name = "result-server", description = "Server to publish test results.") 112 private String mResultServer; 113 114 @Option( 115 name = "disable-result-posting", 116 description ="Disable result posting into report server." 117 ) 118 private boolean mDisableResultPosting = false; 119 120 @Option(name = "include-test-log-tags", description = "Include test log tags in report.") 121 private boolean mIncludeTestLogTags = false; 122 123 @Option(name = "use-log-saver", description = "Also saves generated result with log saver") 124 private boolean mUseLogSaver = false; 125 126 @Option(name = "compress-logs", description = "Whether logs will be saved with compression") 127 private boolean mCompressLogs = true; 128 129 public static final String INCLUDE_HTML_IN_ZIP = "html-in-zip"; 130 @Option(name = INCLUDE_HTML_IN_ZIP, 131 description = "Whether failure summary report is included in the zip fie.") 132 private boolean mIncludeHtml = false; 133 134 @Option( 135 name = "result-attribute", 136 description = 137 "Extra key-value pairs to be added as attributes and corresponding values " 138 + "of the \"Result\" tag in the result XML.") 139 private Map<String, String> mResultAttributes = new HashMap<String, String>(); 140 141 // Should be removed for the S release. 142 @Option( 143 name = "cts-on-gsi-variant", 144 description = 145 "Workaround for the R release to ensure the CTS-on-GSI report can be parsed " 146 + "by the APFE.") 147 private boolean mCtsOnGsiVariant = false; 148 149 private CompatibilityBuildHelper mBuildHelper; 150 151 /** The directory containing the results */ 152 private File mResultDir = null; 153 /** The directory containing the logs */ 154 private File mLogDir = null; 155 156 private ResultUploader mUploader; 157 158 /** LogFileSaver to copy the file to the CTS results folder */ 159 private LogFileSaver mTestLogSaver; 160 161 private Map<LogFile, InputStreamSource> mPreInvocationLogs = new HashMap<>(); 162 /** Invocation level Log saver to receive when files are logged */ 163 private ILogSaver mLogSaver; 164 165 private String mReferenceUrl; 166 167 private Map<String, String> mLoggedFiles; 168 169 private static final String[] RESULT_RESOURCES = { 170 "compatibility_result.css", 171 "compatibility_result.xsl", 172 "logo.png" 173 }; 174 CertificationSuiteResultReporter()175 public CertificationSuiteResultReporter() { 176 super(); 177 mLoggedFiles = new LinkedHashMap<>(); 178 } 179 180 /** 181 * {@inheritDoc} 182 */ 183 @Override invocationStarted(IInvocationContext context)184 public final void invocationStarted(IInvocationContext context) { 185 super.invocationStarted(context); 186 187 if (mBuildHelper == null) { 188 mBuildHelper = createBuildHelper(); 189 } 190 if (mResultDir == null) { 191 initializeResultDirectories(); 192 } 193 } 194 195 @VisibleForTesting createBuildHelper()196 CompatibilityBuildHelper createBuildHelper() { 197 return new CompatibilityBuildHelper(getPrimaryBuildInfo()); 198 } 199 200 /** 201 * {@inheritDoc} 202 */ 203 @Override testLog(String name, LogDataType type, InputStreamSource stream)204 public void testLog(String name, LogDataType type, InputStreamSource stream) { 205 if (name.endsWith(DeviceInfo.FILE_SUFFIX)) { 206 // Handle device info file case 207 testLogDeviceInfo(name, stream); 208 return; 209 } 210 if (mTestLogSaver == null) { 211 LogFile info = new LogFile(name, null, type); 212 mPreInvocationLogs.put( 213 info, new SnapshotInputStreamSource(name, stream.createInputStream())); 214 return; 215 } 216 try { 217 File logFile = null; 218 if (mCompressLogs) { 219 try (InputStream inputStream = stream.createInputStream()) { 220 logFile = mTestLogSaver.saveAndGZipLogData(name, type, inputStream); 221 } 222 } else { 223 try (InputStream inputStream = stream.createInputStream()) { 224 logFile = mTestLogSaver.saveLogData(name, type, inputStream); 225 } 226 } 227 CLog.d("Saved logs for %s in %s", name, logFile.getAbsolutePath()); 228 } catch (IOException e) { 229 CLog.e("Failed to write log for %s", name); 230 CLog.e(e); 231 } 232 } 233 234 /** Write device-info files to the result */ testLogDeviceInfo(String name, InputStreamSource stream)235 private void testLogDeviceInfo(String name, InputStreamSource stream) { 236 try { 237 File ediDir = new File(mResultDir, DeviceInfo.RESULT_DIR_NAME); 238 ediDir.mkdirs(); 239 File ediFile = new File(ediDir, name); 240 if (!ediFile.exists()) { 241 // only write this file to the results if not already present 242 FileUtil.writeToFile(stream.createInputStream(), ediFile); 243 } 244 } catch (IOException e) { 245 CLog.w("Failed to write device info %s to result", name); 246 CLog.e(e); 247 } 248 } 249 250 /** 251 * {@inheritDoc} 252 */ 253 @Override testLogSaved(String dataName, LogDataType dataType, InputStreamSource dataStream, LogFile logFile)254 public void testLogSaved(String dataName, LogDataType dataType, InputStreamSource dataStream, 255 LogFile logFile) { 256 if (mIncludeTestLogTags) { 257 switch (dataType) { 258 case BUGREPORT: 259 case LOGCAT: 260 case PNG: 261 mLoggedFiles.put(dataName, logFile.getUrl()); 262 break; 263 default: 264 // Do nothing 265 break; 266 } 267 } 268 } 269 270 /** 271 * {@inheritDoc} 272 */ 273 @Override putSummary(List<TestSummary> summaries)274 public void putSummary(List<TestSummary> summaries) { 275 for (TestSummary summary : summaries) { 276 if (mReferenceUrl == null && summary.getSummary().getString() != null) { 277 mReferenceUrl = summary.getSummary().getString(); 278 } 279 } 280 } 281 282 /** 283 * {@inheritDoc} 284 */ 285 @Override setLogSaver(ILogSaver saver)286 public void setLogSaver(ILogSaver saver) { 287 mLogSaver = saver; 288 } 289 290 /** 291 * Create directory structure where results and logs will be written. 292 */ initializeResultDirectories()293 private void initializeResultDirectories() { 294 CLog.d("Initializing result directory"); 295 try { 296 mResultDir = mBuildHelper.getResultDir(); 297 if (mResultDir != null) { 298 mResultDir.mkdirs(); 299 } 300 } catch (FileNotFoundException e) { 301 throw new RuntimeException(e); 302 } 303 304 if (mResultDir == null) { 305 throw new RuntimeException("Result Directory was not created"); 306 } 307 if (!mResultDir.exists()) { 308 throw new RuntimeException("Result Directory was not created: " + 309 mResultDir.getAbsolutePath()); 310 } 311 312 CLog.d("Results Directory: %s", mResultDir.getAbsolutePath()); 313 314 mUploader = new ResultUploader(mResultServer, mBuildHelper.getSuiteName()); 315 try { 316 mLogDir = mBuildHelper.getInvocationLogDir(); 317 } catch (FileNotFoundException e) { 318 CLog.e(e); 319 } 320 if (mLogDir != null && mLogDir.mkdirs()) { 321 CLog.d("Created log dir %s", mLogDir.getAbsolutePath()); 322 } 323 if (mLogDir == null || !mLogDir.exists()) { 324 throw new IllegalArgumentException(String.format("Could not create log dir %s", 325 mLogDir.getAbsolutePath())); 326 } 327 // During sharding, we reach here before invocationStarted is called so the log_saver will 328 // be null at that point. 329 if (mTestLogSaver == null) { 330 mTestLogSaver = new LogFileSaver(mLogDir); 331 // Log all the early logs from before init. 332 for (LogFile earlyLog : mPreInvocationLogs.keySet()) { 333 try (InputStreamSource source = mPreInvocationLogs.get(earlyLog)) { 334 testLog(earlyLog.getPath(), earlyLog.getType(), source); 335 } 336 } 337 mPreInvocationLogs.clear(); 338 } 339 } 340 341 @Override createFormatter()342 public IFormatterGenerator createFormatter() { 343 return new CertificationResultXml( 344 createSuiteName(mBuildHelper.getSuiteName()), 345 mBuildHelper.getSuiteVersion(), 346 createSuiteVariant(), 347 mBuildHelper.getSuitePlan(), 348 mBuildHelper.getSuiteBuild(), 349 mReferenceUrl, 350 getLogUrl(), 351 mResultAttributes); 352 } 353 354 @Override preFormattingSetup(IFormatterGenerator formater)355 public void preFormattingSetup(IFormatterGenerator formater) { 356 super.preFormattingSetup(formater); 357 // Log the summary 358 TestSummary summary = getSummary(); 359 try { 360 File summaryFile = new File(mResultDir, SUMMARY_FILE); 361 FileUtil.writeToFile(summary.getSummary().toString(), summaryFile); 362 } catch (IOException e) { 363 CLog.e("Failed to save the summary."); 364 CLog.e(e); 365 } 366 367 copyDynamicConfigFiles(); 368 copyFormattingFiles(mResultDir, mBuildHelper.getSuiteName()); 369 } 370 371 @Override createResultDir()372 public File createResultDir() throws IOException { 373 return mResultDir; 374 } 375 376 @Override postFormattingStep(File resultDir, File reportFile)377 public void postFormattingStep(File resultDir, File reportFile) { 378 super.postFormattingStep(resultDir,reportFile); 379 380 createChecksum( 381 resultDir, 382 getMergedTestRunResults(), 383 getPrimaryBuildInfo().getBuildAttributes().get(BUILD_FINGERPRINT)); 384 385 File report = null; 386 File failureReport = null; 387 if (mIncludeHtml) { 388 // Create the html reports before the zip file. 389 report = createReport(reportFile); 390 failureReport = createFailureReport(reportFile); 391 } 392 File zippedResults = zipResults(mResultDir); 393 if (!mIncludeHtml) { 394 // Create html reports after zip file so extra data is not uploaded 395 report = createReport(reportFile); 396 failureReport = createFailureReport(reportFile); 397 } 398 if (report != null) { 399 CLog.i("Viewable report: %s", report.getAbsolutePath()); 400 } 401 try { 402 if (failureReport.exists()) { 403 CLog.i("Test Result: %s", failureReport.getCanonicalPath()); 404 } else { 405 CLog.i("Test Result: %s", reportFile.getCanonicalPath()); 406 } 407 Path latestLink = createLatestLinkDirectory(mResultDir.toPath()); 408 if (latestLink != null) { 409 CLog.i("Latest results link: " + latestLink.toAbsolutePath()); 410 } 411 412 latestLink = createLatestLinkDirectory(mLogDir.toPath()); 413 if (latestLink != null) { 414 CLog.i("Latest logs link: " + latestLink.toAbsolutePath()); 415 } 416 417 saveLog(reportFile, zippedResults); 418 } catch (IOException e) { 419 CLog.e("Error when handling the post processing of results file:"); 420 CLog.e(e); 421 } 422 423 uploadResult(reportFile); 424 } 425 426 /** 427 * Return the path in which log saver persists log files or null if 428 * logSaver is not enabled. 429 */ getLogUrl()430 private String getLogUrl() { 431 if (!mUseLogSaver || mLogSaver == null) { 432 return null; 433 } 434 435 return mLogSaver.getLogReportDir().getUrl(); 436 } 437 438 /** 439 * Update the "latest" symlink to the newest result directory. CTS specific. 440 */ createLatestLinkDirectory(Path directory)441 private Path createLatestLinkDirectory(Path directory) { 442 Path link = null; 443 444 Path parent = directory.getParent(); 445 446 if (parent != null) { 447 link = parent.resolve(LATEST_LINK_NAME); 448 try { 449 // if latest already exists, we have to remove it before creating 450 Files.deleteIfExists(link); 451 Files.createSymbolicLink(link, directory); 452 } catch (IOException ioe) { 453 CLog.e("Exception while attempting to create 'latest' link to: [%s]", 454 directory); 455 CLog.e(ioe); 456 return null; 457 } catch (UnsupportedOperationException uoe) { 458 CLog.e("Failed to create 'latest' symbolic link - unsupported operation"); 459 return null; 460 } 461 } 462 return link; 463 } 464 465 /** 466 * move the dynamic config files to the results directory 467 */ copyDynamicConfigFiles()468 private void copyDynamicConfigFiles() { 469 File configDir = new File(mResultDir, "config"); 470 if (!configDir.exists() && !configDir.mkdir()) { 471 CLog.w( 472 "Failed to make dynamic config directory \"%s\" in the result.", 473 configDir.getAbsolutePath()); 474 } 475 476 Set<String> uniqueModules = new HashSet<>(); 477 // Check each build of the invocation, in case of multi-device invocation. 478 for (IBuildInfo buildInfo : getInvocationContext().getBuildInfos()) { 479 CompatibilityBuildHelper helper = new CompatibilityBuildHelper(buildInfo); 480 Map<String, File> dcFiles = helper.getDynamicConfigFiles(); 481 for (String moduleName : dcFiles.keySet()) { 482 File srcFile = dcFiles.get(moduleName); 483 if (!uniqueModules.contains(moduleName)) { 484 // have not seen config for this module yet, copy into result 485 File destFile = new File(configDir, moduleName + ".dynamic"); 486 if (destFile.exists()) { 487 continue; 488 } 489 try { 490 FileUtil.copyFile(srcFile, destFile); 491 uniqueModules.add(moduleName); // Add to uniqueModules if copy succeeds 492 } catch (IOException e) { 493 CLog.w("Failure when copying config file \"%s\" to \"%s\" for module %s", 494 srcFile.getAbsolutePath(), destFile.getAbsolutePath(), moduleName); 495 CLog.e(e); 496 } 497 } 498 FileUtil.deleteFile(srcFile); 499 } 500 } 501 } 502 503 /** 504 * Copy the xml formatting files stored in this jar to the results directory. CTS specific. 505 * 506 * @param resultsDir 507 */ copyFormattingFiles(File resultsDir, String suiteName)508 private void copyFormattingFiles(File resultsDir, String suiteName) { 509 for (String resultFileName : RESULT_RESOURCES) { 510 InputStream configStream = CertificationResultXml.class.getResourceAsStream( 511 String.format("/report/%s-%s", suiteName, resultFileName)); 512 if (configStream == null) { 513 // If suite specific files are not available, fallback to common. 514 configStream = CertificationResultXml.class.getResourceAsStream( 515 String.format("/report/%s", resultFileName)); 516 } 517 if (configStream != null) { 518 File resultFile = new File(resultsDir, resultFileName); 519 try { 520 FileUtil.writeToFile(configStream, resultFile); 521 } catch (IOException e) { 522 CLog.w("Failed to write %s to file", resultFileName); 523 } 524 } else { 525 CLog.w("Failed to load %s from jar", resultFileName); 526 } 527 } 528 } 529 530 /** 531 * When enabled, save log data using log saver 532 */ saveLog(File resultFile, File zippedResults)533 private void saveLog(File resultFile, File zippedResults) throws IOException { 534 if (!mUseLogSaver) { 535 return; 536 } 537 538 FileInputStream fis = null; 539 LogFile logFile = null; 540 try { 541 fis = new FileInputStream(resultFile); 542 logFile = mLogSaver.saveLogData("log-result", LogDataType.XML, fis); 543 CLog.d("Result XML URL: %s", logFile.getUrl()); 544 logReportFiles(getConfiguration(), resultFile, resultFile.getName(), LogDataType.XML); 545 } catch (IOException ioe) { 546 CLog.e("error saving XML with log saver"); 547 CLog.e(ioe); 548 } finally { 549 StreamUtil.close(fis); 550 } 551 // Save the full results folder. 552 if (zippedResults != null) { 553 FileInputStream zipResultStream = null; 554 try { 555 zipResultStream = new FileInputStream(zippedResults); 556 logFile = mLogSaver.saveLogData("results", LogDataType.ZIP, zipResultStream); 557 CLog.d("Result zip URL: %s", logFile.getUrl()); 558 logReportFiles(getConfiguration(), zippedResults, "results", LogDataType.ZIP); 559 } finally { 560 StreamUtil.close(zipResultStream); 561 } 562 } 563 } 564 565 /** 566 * Zip the contents of the given results directory. CTS specific. 567 * 568 * @param resultsDir 569 */ zipResults(File resultsDir)570 private static File zipResults(File resultsDir) { 571 File zipResultFile = null; 572 try { 573 // create a file in parent directory, with same name as resultsDir 574 zipResultFile = new File(resultsDir.getParent(), String.format("%s.zip", 575 resultsDir.getName())); 576 ZipUtil.createZip(resultsDir, zipResultFile); 577 } catch (IOException e) { 578 CLog.w("Failed to create zip for %s", resultsDir.getName()); 579 } 580 return zipResultFile; 581 } 582 583 /** 584 * When enabled, upload the result to a server. CTS specific. 585 */ uploadResult(File resultFile)586 private void uploadResult(File resultFile) { 587 if (mResultServer != null && !mResultServer.trim().isEmpty() && !mDisableResultPosting) { 588 try { 589 CLog.d("Result Server: %d", mUploader.uploadResult(resultFile, mReferenceUrl)); 590 } catch (IOException ioe) { 591 CLog.e("IOException while uploading result."); 592 CLog.e(ioe); 593 } 594 } 595 } 596 597 /** Generate html report. */ createReport(File inputXml)598 private File createReport(File inputXml) { 599 File report = new File(inputXml.getParentFile(), HTLM_REPORT_NAME); 600 try (InputStream xslStream = 601 new FileInputStream( 602 new File(inputXml.getParentFile(), REPORT_XSL_FILE_NAME)); 603 OutputStream outputStream = new FileOutputStream(report)) { 604 Transformer transformer = 605 TransformerFactory.newInstance().newTransformer(new StreamSource(xslStream)); 606 transformer.transform(new StreamSource(inputXml), new StreamResult(outputStream)); 607 } catch (IOException | TransformerException ignored) { 608 CLog.e(ignored); 609 FileUtil.deleteFile(report); 610 return null; 611 } 612 return report; 613 } 614 615 /** 616 * Generate html report listing an failed tests. CTS specific. 617 */ createFailureReport(File inputXml)618 private File createFailureReport(File inputXml) { 619 File failureReport = new File(inputXml.getParentFile(), FAILURE_REPORT_NAME); 620 try (InputStream xslStream = ResultHandler.class.getResourceAsStream( 621 String.format("/report/%s", FAILURE_XSL_FILE_NAME)); 622 OutputStream outputStream = new FileOutputStream(failureReport)) { 623 624 Transformer transformer = TransformerFactory.newInstance().newTransformer( 625 new StreamSource(xslStream)); 626 transformer.transform(new StreamSource(inputXml), new StreamResult(outputStream)); 627 } catch (IOException | TransformerException ignored) { 628 CLog.e(ignored); 629 } 630 return failureReport; 631 } 632 633 /** 634 * Generates a checksum files based on the results. 635 */ createChecksum(File resultDir, Collection<TestRunResult> results, String buildFingerprint)636 private void createChecksum(File resultDir, Collection<TestRunResult> results, 637 String buildFingerprint) { 638 CertificationChecksumHelper.tryCreateChecksum(resultDir, results, buildFingerprint); 639 } 640 641 /** Re-log a result file to all reporters so they are aware of it. */ logReportFiles( IConfiguration configuration, File resultFile, String dataName, LogDataType type)642 private void logReportFiles( 643 IConfiguration configuration, File resultFile, String dataName, LogDataType type) { 644 if (configuration == null) { 645 return; 646 } 647 ILogSaver saver = configuration.getLogSaver(); 648 List<ITestInvocationListener> listeners = configuration.getTestInvocationListeners(); 649 try (FileInputStreamSource source = new FileInputStreamSource(resultFile)) { 650 LogFile loggedFile = null; 651 try (InputStream stream = source.createInputStream()) { 652 loggedFile = saver.saveLogData(dataName, type, stream); 653 } catch (IOException e) { 654 CLog.e(e); 655 } 656 for (ITestInvocationListener listener : listeners) { 657 if (listener.equals(this)) { 658 // Avoid logging agaisnt itself 659 continue; 660 } 661 listener.testLog(dataName, type, source); 662 if (loggedFile != null) { 663 if (listener instanceof ILogSaverListener) { 664 ((ILogSaverListener) listener).logAssociation(dataName, loggedFile); 665 } 666 } 667 } 668 } 669 } 670 createSuiteName(String originalSuiteName)671 private String createSuiteName(String originalSuiteName) { 672 if (mCtsOnGsiVariant) { 673 String commandLine = getConfiguration().getCommandLine(); 674 // SubprocessConfigBuilder is added to support ATS current way of running things. 675 // It won't be needed after the R release. 676 if (commandLine.startsWith("cts-on-gsi") 677 || commandLine.startsWith( 678 SubprocessConfigBuilder.createConfigName("cts-on-gsi"))) { 679 return "VTS"; 680 } 681 } 682 return originalSuiteName; 683 } 684 createSuiteVariant()685 private String createSuiteVariant() { 686 IConfiguration currentConfig = getConfiguration(); 687 String commandLine = currentConfig.getCommandLine(); 688 for (SuiteVariant var : SuiteVariant.values()) { 689 if (commandLine.startsWith(var.getConfigName() + " ") 690 || commandLine.equals(var.getConfigName())) { 691 return var.getReportDisplayName(); 692 } 693 } 694 return null; 695 } 696 } 697