diff options
author | Sanket Chinchalkar <schinchalkar@google.com> | 2021-07-28 22:53:19 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-07-28 22:53:19 +0000 |
commit | 2a47e047fd0c5242b074d201292c5268e166f798 (patch) | |
tree | 9f5ca6c233a8d43ea32eb2e1aa9bf894fc202730 | |
parent | d5578b1a212970694245fdfc6693b5d2eae9a091 (diff) | |
parent | 4b309934216e7b0ef057e4d4ed12b9bba0e2013f (diff) | |
download | suite_harness-2a47e047fd0c5242b074d201292c5268e166f798.tar.gz |
Merge "Test Metrics JSON Result Reporter"
2 files changed, 685 insertions, 0 deletions
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/TestMetricsJsonResultReporter.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/TestMetricsJsonResultReporter.java new file mode 100644 index 00000000..81b25b7a --- /dev/null +++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/TestMetricsJsonResultReporter.java @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.compatibility.common.tradefed.result.suite; + +import com.android.annotations.VisibleForTesting; + +import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; +import com.android.compatibility.common.tradefed.util.CollectorUtil; +import com.android.compatibility.common.util.MetricsReportLog; +import com.android.compatibility.common.util.ResultType; +import com.android.compatibility.common.util.ResultUnit; + +import com.android.ddmlib.Log.LogLevel; + +import com.android.tradefed.build.IBuildInfo; +import com.android.tradefed.config.Option; +import com.android.tradefed.config.OptionClass; +import com.android.tradefed.invoker.IInvocationContext; + +import com.android.tradefed.log.LogUtil.CLog; + +import com.android.tradefed.metrics.proto.MetricMeasurement.Metric; + +import com.android.tradefed.result.ITestInvocationListener; +import com.android.tradefed.result.TestDescription; + +import com.android.tradefed.testtype.suite.ModuleDefinition; + +import com.android.tradefed.util.FileUtil; +import com.android.tradefed.util.proto.TfMetricProtoUtil; + +import java.io.File; +import java.io.IOException; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** TestMetricsJsonResultReporter writes performance test metrics to a Json file. */ +@OptionClass(alias = "test-metrics-json-reporter") +public class TestMetricsJsonResultReporter implements ITestInvocationListener { + + private static final String PRODUCT_CPU_ABI_KEY = "ro.product.cpu.abi"; + + private CompatibilityBuildHelper mBuildHelper; + private IInvocationContext mContext; + private IInvocationContext mModuleContext; + private IBuildInfo mBuildInfo; + + @Option( + name = "dest-dir", + description = + "The directory under the result to store the files. " + + "Default to 'report-log-files'.") + private String mDestDir = "report-log-files"; + + private String mTempReportFolder = "temp-report-logs"; + + @Option(name = "report-log-name", description = "Name of the JSON report file.") + private String mReportLogName = null; + + @Option( + name = "report-test-name-mapping", + description = "Mapping for test name to use in report.") + private Map<String, String> mReportTestNameMap = new HashMap<String, String>(); + + @Option( + name = "report-all-metrics", + description = "Report all the generated metrics. Default to 'true'.") + private boolean mReportAllMetrics = true; + + @Option( + name = "report-metric-key-mapping", + description = + "Mapping for Metric Keys to be reported. " + + "Only report the keys provided in the mapping.") + private Map<String, String> mReportMetricKeyMap = new HashMap<String, String>(); + + public TestMetricsJsonResultReporter() { + // Default Constructor + // Nothing to do + } + + /** + * Return the primary build info that was reported via {@link + * #invocationStarted(IInvocationContext)}. Primary build is the build returned by the first + * build provider of the running configuration. Returns null if there is no context (no build to + * test case). + */ + private IBuildInfo getPrimaryBuildInfo() { + if (mContext == null) { + return null; + } else { + return mContext.getBuildInfos().get(0); + } + } + + /** Create Build Helper */ + @VisibleForTesting + CompatibilityBuildHelper createBuildHelper() { + return new CompatibilityBuildHelper(getPrimaryBuildInfo()); + } + + /** Get Device ABI Information */ + @VisibleForTesting + String getAbiInfo() { + CLog.logAndDisplay(LogLevel.INFO, "Getting ABI Information."); + if (mModuleContext == null) { + // Return Empty String + return ""; + } + List<String> abis = mModuleContext.getAttributes().get(ModuleDefinition.MODULE_ABI); + if (abis == null || abis.isEmpty()) { + // Return Empty String + return ""; + } + if (abis.size() > 1) { + CLog.logAndDisplay( + LogLevel.WARN, + String.format( + "More than one ABI name specified (using first one): %s", + abis.toString())); + } + return abis.get(0); + } + + /** Initialize configurations for Result Reporter */ + private void initializeReporterConfig() { + CLog.logAndDisplay(LogLevel.INFO, "Initializing Test Metrics Result Reporter Config."); + // Initialize Build Info + mBuildInfo = getPrimaryBuildInfo(); + + // Initialize Build Helper + if (mBuildHelper == null) { + mBuildHelper = createBuildHelper(); + } + + // Initialize Report Log Name + // Use test tag as the report name if not provided + if (mReportLogName == null) { + mReportLogName = mContext.getTestTag(); + } + } + + /** Write Test Metrics to JSON */ + private void writeTestMetrics( + TestDescription testDescription, HashMap<String, Metric> metrics) { + // Class Method Name + String classMethodName = testDescription.toString(); + + // Use class method name as stream name if mapping is not provided + String streamName = classMethodName; + if (mReportTestNameMap != null && mReportTestNameMap.containsKey(classMethodName)) { + streamName = mReportTestNameMap.get(classMethodName); + } + + // Get ABI Info + String abiName = getAbiInfo(); + + // Initialize Metrics Report Log + // TODO: b/194103027 [Remove MetricsReportLog dependency as it is being deprecated]. + MetricsReportLog reportLog = + new MetricsReportLog( + mBuildInfo, abiName, classMethodName, mReportLogName, streamName); + + // Write Test Metrics in the Log + if (mReportAllMetrics) { + // Write all the metrics to the report + writeAllMetrics(reportLog, metrics); + } else { + // Write metrics for given keys to the report + writeMetricsForGivenKeys(reportLog, metrics); + } + + // Submit Report Log + reportLog.submit(); + } + + /** Write all the metrics to JSON Report */ + private void writeAllMetrics(MetricsReportLog reportLog, HashMap<String, Metric> metrics) { + CLog.logAndDisplay(LogLevel.INFO, "Writing all the metrics to JSON report."); + Map<String, String> metricsMap = TfMetricProtoUtil.compatibleConvert(metrics); + for (String key : metricsMap.keySet()) { + try { + double value = Double.parseDouble(metricsMap.get(key)); + reportLog.addValue(key, value, ResultType.NEUTRAL, ResultUnit.NONE); + } catch (NumberFormatException exception) { + CLog.logAndDisplay( + LogLevel.ERROR, + String.format( + "Unable to parse value '%s' for '%s' metric key.", + metricsMap.get(key), key)); + } + } + CLog.logAndDisplay( + LogLevel.INFO, "Successfully completed writing the metrics to JSON report."); + } + + /** Write given set of metrics to JSON Report */ + private void writeMetricsForGivenKeys( + MetricsReportLog reportLog, HashMap<String, Metric> metrics) { + CLog.logAndDisplay(LogLevel.INFO, "Writing given set of metrics to JSON report."); + if (mReportMetricKeyMap == null || mReportMetricKeyMap.isEmpty()) { + CLog.logAndDisplay( + LogLevel.WARN, "Skip reporting metrics. Metric keys are not provided."); + return; + } + for (String key : mReportMetricKeyMap.keySet()) { + if (!metrics.containsKey(key) || metrics.get(key) == null) { + CLog.logAndDisplay(LogLevel.WARN, String.format("%s metric key is missing.", key)); + continue; + } + Map<String, String> metricsMap = TfMetricProtoUtil.compatibleConvert(metrics); + try { + double value = Double.parseDouble(metricsMap.get(key)); + reportLog.addValue( + mReportMetricKeyMap.get(key), value, ResultType.NEUTRAL, ResultUnit.NONE); + } catch (NumberFormatException exception) { + CLog.logAndDisplay( + LogLevel.ERROR, + String.format( + "Unable to parse value '%s' for '%s' metric key.", + metricsMap.get(key), key)); + } + } + CLog.logAndDisplay( + LogLevel.INFO, "Successfully completed writing the metrics to JSON report."); + } + + /** Copy the report generated at temporary path to the given destination path in Results */ + private void copyGeneratedReportToResultsDirectory() { + CLog.logAndDisplay(LogLevel.INFO, "Copying the report log to results directory."); + // Copy report log files to results dir. + try { + // Get Result Directory + File resultDir = mBuildHelper.getResultDir(); + // Create a directory ( if it does not exist ) in results for report logs + if (mDestDir != null) { + resultDir = new File(resultDir, mDestDir); + } + if (!resultDir.exists()) { + resultDir.mkdirs(); + } + if (!resultDir.isDirectory()) { + CLog.logAndDisplay( + LogLevel.ERROR, + String.format("%s is not a directory", resultDir.getAbsolutePath())); + return; + } + // Temp directory for report logs + final File hostReportDir = FileUtil.createNamedTempDir(mTempReportFolder); + if (!hostReportDir.isDirectory()) { + CLog.logAndDisplay( + LogLevel.ERROR, + String.format("%s is not a directory", hostReportDir.getAbsolutePath())); + return; + } + // Copy the report logs from temp directory and to the results directory + CollectorUtil.pullFromHost(hostReportDir, resultDir); + CollectorUtil.reformatRepeatedStreams(resultDir); + CLog.logAndDisplay(LogLevel.INFO, "Copying the report log completed successfully."); + } catch (IOException exception) { + CLog.logAndDisplay(LogLevel.ERROR, exception.getMessage()); + } + } + + /** {@inheritDoc} */ + @Override + public void invocationStarted(IInvocationContext context) { + mContext = context; + initializeReporterConfig(); + } + + /** {@inheritDoc} */ + @Override + public void invocationEnded(long elapsedTime) { + // Copy the generated report to Results Directory + copyGeneratedReportToResultsDirectory(); + } + + /** Overrides parent to explicitly add test metrics to JSON */ + @Override + public void testEnded(TestDescription testDescription, HashMap<String, Metric> metrics) { + // If available, write Test Metrics to JSON + if (!metrics.isEmpty()) { + writeTestMetrics(testDescription, metrics); + } + } + + /** {@inheritDoc} */ + @Override + public void testModuleStarted(IInvocationContext moduleContext) { + mModuleContext = moduleContext; + } + + /** {@inheritDoc} */ + @Override + public void testModuleEnded() { + mModuleContext = null; + } +} diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/TestMetricsJsonResultReporterTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/TestMetricsJsonResultReporterTest.java new file mode 100644 index 00000000..6fdb3647 --- /dev/null +++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/TestMetricsJsonResultReporterTest.java @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.compatibility.common.tradefed.result.suite; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; + +import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; +import com.android.tradefed.build.BuildInfo; +import com.android.tradefed.build.IBuildInfo; +import com.android.tradefed.config.ConfigurationDef; +import com.android.tradefed.config.OptionSetter; +import com.android.tradefed.invoker.IInvocationContext; +import com.android.tradefed.invoker.InvocationContext; +import com.android.tradefed.metrics.proto.MetricMeasurement.Metric; +import com.android.tradefed.result.TestDescription; +import com.android.tradefed.util.FileUtil; +import com.android.tradefed.util.proto.TfMetricProtoUtil; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.io.File; + +import java.util.Map; +import java.util.HashMap; + +/** Unit tests for {@link TestMetricsJsonResultReporter}. */ +@RunWith(JUnit4.class) +public class TestMetricsJsonResultReporterTest { + private TestMetricsJsonResultReporter mResultReporter; + + private OptionSetter mOptionSetter; + + private CompatibilityBuildHelper mBuildHelper; + + private IInvocationContext mContext; + + private File mResultDir; + private File mFakeDir; + + private static final String DESTINATION_DIR = "report-log-files"; + private static final String REPORT_FILE_SUFFIX = "reportlog.json"; + private static final String TEST_TAG = "testTag"; + + @Before + public void setUp() throws Exception { + mFakeDir = FileUtil.createTempDir("result-dir"); + mResultDir = new File(mFakeDir, "android-cts/results"); + mResultDir.mkdirs(); + + IBuildInfo info = new BuildInfo(); + info.addBuildAttribute(CompatibilityBuildHelper.ROOT_DIR, mFakeDir.getAbsolutePath()); + info.addBuildAttribute( + CompatibilityBuildHelper.START_TIME_MS, Long.toString(System.currentTimeMillis())); + + mBuildHelper = + new CompatibilityBuildHelper(info) { + @Override + public String getSuiteName() { + return "CTS"; + } + + @Override + public String getSuiteVersion() { + return "version"; + } + + @Override + public String getSuitePlan() { + return "cts"; + } + + @Override + public String getSuiteBuild() { + return "R1"; + } + }; + + mContext = new InvocationContext(); + mContext.addDeviceBuildInfo(ConfigurationDef.DEFAULT_DEVICE_NAME, info); + mContext.setTestTag(TEST_TAG); + + mResultReporter = + new TestMetricsJsonResultReporter() { + @Override + CompatibilityBuildHelper createBuildHelper() { + return mBuildHelper; + } + + @Override + String getAbiInfo() { + return "testABI"; + } + }; + + mOptionSetter = new OptionSetter(mResultReporter); + } + + @After + public void tearDown() throws Exception { + FileUtil.recursiveDelete(mFakeDir); + } + + /** Check that results file is not generated if test metrics are not available. */ + @Test + public void testReportLogFileNotGenerated() throws Exception { + mResultReporter.invocationStarted(mContext); + mResultReporter.invocationEnded(500L); + File reportLogDir = new File(mBuildHelper.getResultDir(), DESTINATION_DIR); + File reportLogFile = + new File(reportLogDir, String.format("%s.%s", TEST_TAG, REPORT_FILE_SUFFIX)); + assertFalse(reportLogFile.exists()); + } + + /** + * Check that results file is generated if test metrics are available. Case: If user does not + * provide the report file name, test tag is used as default file name. + */ + @Test + public void testReportLogFileIsGenerated_Default_File_Name() throws Exception { + Map<String, String> map = new HashMap<>(); + map.put("metric-1", "1.0"); + final TestDescription testId = new TestDescription("FooTest", "testFoo"); + mResultReporter.invocationStarted(mContext); + mResultReporter.testRunStarted("run", 1); + mResultReporter.testStarted(testId); + mResultReporter.testEnded(testId, TfMetricProtoUtil.upgradeConvert(map)); + mResultReporter.testRunEnded(3, new HashMap<String, Metric>()); + mResultReporter.invocationEnded(500L); + File reportLogDir = new File(mBuildHelper.getResultDir(), DESTINATION_DIR); + File reportLogFile = + new File(reportLogDir, String.format("%s.%s", TEST_TAG, REPORT_FILE_SUFFIX)); + assertTrue(reportLogFile.exists()); + } + + /** + * Check that results file is generated if test metrics are available. Case: User Provided Name + * is used as Report File Name + */ + @Test + public void testReportLogFileIsGenerated_Custom_File_Name() throws Exception { + String reportFileName = "customName"; + mOptionSetter.setOptionValue("report-log-name", reportFileName); + Map<String, String> map = new HashMap<>(); + map.put("metric-1", "1.0"); + final TestDescription testId = new TestDescription("FooTest", "testFoo"); + mResultReporter.invocationStarted(mContext); + mResultReporter.testRunStarted("run", 1); + mResultReporter.testStarted(testId); + mResultReporter.testEnded(testId, TfMetricProtoUtil.upgradeConvert(map)); + mResultReporter.testRunEnded(3, new HashMap<String, Metric>()); + mResultReporter.invocationEnded(500L); + File reportLogDir = new File(mBuildHelper.getResultDir(), DESTINATION_DIR); + File reportLogFile = + new File(reportLogDir, String.format("%s.%s", TEST_TAG, REPORT_FILE_SUFFIX)); + // Check report file with default name does not exist + assertFalse(reportLogFile.exists()); + reportLogFile = + new File(reportLogDir, String.format("%s.%s", reportFileName, REPORT_FILE_SUFFIX)); + // Check that report file with user provided name is generated + assertTrue(reportLogFile.exists()); + } + + /** + * Check that results file is generated and have expected content. Case: If Test Name mapping is + * not provided, ClassMethodName is used as default + */ + @Test + public void testReportLogValidateContent_No_Test_Name_Mapping() throws Exception { + Map<String, String> map = new HashMap<>(); + map.put("metric-1", "1.0"); + final TestDescription testId = new TestDescription("FooTest", "testFoo"); + mResultReporter.invocationStarted(mContext); + mResultReporter.testRunStarted("run", 1); + mResultReporter.testStarted(testId); + mResultReporter.testEnded(testId, TfMetricProtoUtil.upgradeConvert(map)); + mResultReporter.testRunEnded(3, new HashMap<String, Metric>()); + mResultReporter.invocationEnded(500L); + File reportLogDir = new File(mBuildHelper.getResultDir(), DESTINATION_DIR); + File reportLogFile = + new File(reportLogDir, String.format("%s.%s", TEST_TAG, REPORT_FILE_SUFFIX)); + // Check that report file is generated + assertTrue(reportLogFile.exists()); + // Validate Report Content + String content = FileUtil.readStringFromFile(reportLogFile); + assertTrue(content.contains("FooTest#testFoo")); + } + + /** + * Check that results file is generated and have expected content. Case: Test Name Mapping + * Present + */ + @Test + public void testReportLogValidateContent_Test_Name_Mapping_Provided() throws Exception { + mOptionSetter.setOptionValue( + "report-test-name-mapping", "FooTest#testFoo", "foo_test_metric"); + Map<String, String> map = new HashMap<>(); + map.put("metric-1", "1.0"); + final TestDescription testId = new TestDescription("FooTest", "testFoo"); + mResultReporter.invocationStarted(mContext); + mResultReporter.testRunStarted("run", 1); + mResultReporter.testStarted(testId); + mResultReporter.testEnded(testId, TfMetricProtoUtil.upgradeConvert(map)); + mResultReporter.testRunEnded(3, new HashMap<String, Metric>()); + mResultReporter.invocationEnded(500L); + File reportLogDir = new File(mBuildHelper.getResultDir(), DESTINATION_DIR); + File reportLogFile = + new File(reportLogDir, String.format("%s.%s", TEST_TAG, REPORT_FILE_SUFFIX)); + // Check that report file is generated + assertTrue(reportLogFile.exists()); + // Validate Report Content + String content = FileUtil.readStringFromFile(reportLogFile); + assertFalse(content.contains("FooTest#testFoo")); + assertTrue(content.contains("foo_test_metric")); + } + + /** Check that results file is generated and have expected content. Case: Report All Metrics */ + @Test + public void testReportLogValidateContent_Report_All_Metrics() throws Exception { + Map<String, String> testMetricsMap = new HashMap<>(); + testMetricsMap.put("testMetric-1", "1.0"); + testMetricsMap.put("testMetric-2", "1.0"); + final TestDescription testId = new TestDescription("FooTest", "testFoo"); + mResultReporter.invocationStarted(mContext); + mResultReporter.testRunStarted("run", 1); + mResultReporter.testStarted(testId); + mResultReporter.testEnded(testId, TfMetricProtoUtil.upgradeConvert(testMetricsMap)); + mResultReporter.testRunEnded(3, new HashMap<String, Metric>()); + mResultReporter.invocationEnded(500L); + File reportLogDir = new File(mBuildHelper.getResultDir(), DESTINATION_DIR); + File reportLogFile = + new File(reportLogDir, String.format("%s.%s", TEST_TAG, REPORT_FILE_SUFFIX)); + // Check that report file is generated + assertTrue(reportLogFile.exists()); + // Validate Report Content + String content = FileUtil.readStringFromFile(reportLogFile); + assertTrue(content.contains("testMetric-1")); + assertTrue(content.contains("testMetric-2")); + } + + /** + * Check that results file is generated and have expected content. Case: Report Metrics for + * Given Keys + */ + @Test + public void testReportLogValidateContent_Report_Metrics_For_Given_Keys() throws Exception { + mOptionSetter.setOptionValue("report-all-metrics", "false"); + mOptionSetter.setOptionValue( + "report-metric-key-mapping", "testMetric-1", "custom-metric-name-1"); + Map<String, String> testMetricsMap = new HashMap<>(); + testMetricsMap.put("testMetric-1", "1.0"); + testMetricsMap.put("testMetric-2", "1.0"); + final TestDescription testId = new TestDescription("FooTest", "testFoo"); + mResultReporter.invocationStarted(mContext); + mResultReporter.testRunStarted("run", 1); + mResultReporter.testStarted(testId); + mResultReporter.testEnded(testId, TfMetricProtoUtil.upgradeConvert(testMetricsMap)); + mResultReporter.testRunEnded(3, new HashMap<String, Metric>()); + mResultReporter.invocationEnded(500L); + File reportLogDir = new File(mBuildHelper.getResultDir(), DESTINATION_DIR); + File reportLogFile = + new File(reportLogDir, String.format("%s.%s", TEST_TAG, REPORT_FILE_SUFFIX)); + // Check that report file is generated + assertTrue(reportLogFile.exists()); + // Validate Report Content + String content = FileUtil.readStringFromFile(reportLogFile); + assertFalse(content.contains("testMetric-1")); + assertFalse(content.contains("testMetric-2")); + assertTrue(content.contains("custom-metric-name-1")); + } + + /** + * Check that results file is generated and have expected content. Case: Report Metrics for + * Given Keys [ Some Keys are Missing from Generated Metrics ] + */ + @Test + public void testReportLogValidateContent_Missing_Keys() throws Exception { + mOptionSetter.setOptionValue("report-all-metrics", "false"); + mOptionSetter.setOptionValue( + "report-metric-key-mapping", "testMetric-1", "custom-metric-name-1"); + mOptionSetter.setOptionValue( + "report-metric-key-mapping", "testMetric-3", "custom-metric-name-3"); + Map<String, String> testMetricsMap = new HashMap<>(); + testMetricsMap.put("testMetric-1", "1.0"); + testMetricsMap.put("testMetric-2", "1.0"); + final TestDescription testId = new TestDescription("FooTest", "testFoo"); + mResultReporter.invocationStarted(mContext); + mResultReporter.testRunStarted("run", 1); + mResultReporter.testStarted(testId); + mResultReporter.testEnded(testId, TfMetricProtoUtil.upgradeConvert(testMetricsMap)); + mResultReporter.testRunEnded(3, new HashMap<String, Metric>()); + mResultReporter.invocationEnded(500L); + File reportLogDir = new File(mBuildHelper.getResultDir(), DESTINATION_DIR); + File reportLogFile = + new File(reportLogDir, String.format("%s.%s", TEST_TAG, REPORT_FILE_SUFFIX)); + // Check that report file is generated + assertTrue(reportLogFile.exists()); + // Validate Report Content + String content = FileUtil.readStringFromFile(reportLogFile); + assertFalse(content.contains("testMetric-1")); + assertFalse(content.contains("testMetric-2")); + assertTrue(content.contains("custom-metric-name-1")); + assertFalse(content.contains("custom-metric-name-3")); + } + + /** Check that results file is generated and have expected content. Case: Multiple Tests Runs */ + @Test + public void testReportLogValidateContent_Multiple_Tests() throws Exception { + mOptionSetter.setOptionValue( + "report-test-name-mapping", "FooTest#testFoo", "foo_test_metric"); + mOptionSetter.setOptionValue( + "report-test-name-mapping", "BarTest#testBar", "bar_test_metric"); + mOptionSetter.setOptionValue("report-all-metrics", "false"); + mOptionSetter.setOptionValue( + "report-metric-key-mapping", "testMetric-foo-1", "foo-custom-metric-name-1"); + mOptionSetter.setOptionValue( + "report-metric-key-mapping", "testMetric-bar-1", "bar-custom-metric-name-1"); + Map<String, String> fooTestMetricsMap = new HashMap<>(); + fooTestMetricsMap.put("testMetric-foo-1", "1.0"); + fooTestMetricsMap.put("testMetric-foo-2", "1.0"); + Map<String, String> barTestMetricsMap = new HashMap<>(); + barTestMetricsMap.put("testMetric-bar-1", "1.0"); + barTestMetricsMap.put("testMetric-bar-2", "1.0"); + final TestDescription fooTestId = new TestDescription("FooTest", "testFoo"); + final TestDescription barTestId = new TestDescription("BarTest", "testBar"); + mResultReporter.invocationStarted(mContext); + mResultReporter.testRunStarted("run", 1); + mResultReporter.testStarted(fooTestId); + mResultReporter.testEnded(fooTestId, TfMetricProtoUtil.upgradeConvert(fooTestMetricsMap)); + mResultReporter.testStarted(barTestId); + mResultReporter.testEnded(barTestId, TfMetricProtoUtil.upgradeConvert(barTestMetricsMap)); + mResultReporter.testRunEnded(3, new HashMap<String, Metric>()); + mResultReporter.invocationEnded(500L); + File reportLogDir = new File(mBuildHelper.getResultDir(), DESTINATION_DIR); + File reportLogFile = + new File(reportLogDir, String.format("%s.%s", TEST_TAG, REPORT_FILE_SUFFIX)); + // Check that report file is generated + assertTrue(reportLogFile.exists()); + // Validate Report Content + String content = FileUtil.readStringFromFile(reportLogFile); + assertFalse(content.contains("FooTest#testFoo")); + assertTrue(content.contains("foo_test_metric")); + assertFalse(content.contains("testMetric-foo-1")); + assertFalse(content.contains("testMetric-foo-2")); + assertTrue(content.contains("foo-custom-metric-name-1")); + assertFalse(content.contains("BarTest#testBar")); + assertTrue(content.contains("bar_test_metric")); + assertFalse(content.contains("testMetric-bar-1")); + assertFalse(content.contains("testMetric-bar-2")); + assertTrue(content.contains("bar-custom-metric-name-1")); + } +} |