Update interface for TestRecord loading
Add a reporter to dump the results as a proto too.
Test: See other CL in topic
run cts-unit-tests
test a retry
Bug: 110265525
Change-Id: I9afb7a1530c70018708037911ed9e856ea706d6a
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CompatibilityProtoResultReporter.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CompatibilityProtoResultReporter.java
new file mode 100644
index 0000000..17da43a
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/CompatibilityProtoResultReporter.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 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.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.invoker.IInvocationContext;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.proto.ProtoResultReporter;
+import com.android.tradefed.result.proto.TestRecordProto.TestRecord;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Proto reporter that will drop a {@link TestRecord} protobuf in the result directory.
+ */
+public class CompatibilityProtoResultReporter extends ProtoResultReporter {
+
+ public static final String PROTO_FILE_NAME = "test-record.pb";
+
+ private CompatibilityBuildHelper mBuildHelper;
+
+ /** The directory containing the results */
+ private File mResultDir = null;
+
+ @Override
+ public void processStartInvocation(
+ TestRecord invocationStartRecord, IInvocationContext invocationContext) {
+
+ if (mBuildHelper == null) {
+ mBuildHelper = new CompatibilityBuildHelper(invocationContext.getBuildInfos().get(0));
+ }
+ if (mResultDir == null) {
+ initializeResultDirectories();
+ }
+ }
+
+ @Override
+ public void processFinalProto(TestRecord finalRecord) {
+ super.processFinalProto(finalRecord);
+
+ File protoFile = new File(mResultDir, PROTO_FILE_NAME);
+ try {
+ finalRecord.writeDelimitedTo(new FileOutputStream(protoFile));
+ } catch (IOException e) {
+ CLog.e(e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void initializeResultDirectories() {
+ CLog.d("Initializing result directory");
+
+ try {
+ mResultDir = mBuildHelper.getResultDir();
+ if (mResultDir != null) {
+ mResultDir.mkdirs();
+ }
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+
+ if (mResultDir == null) {
+ throw new RuntimeException("Result Directory was not created");
+ }
+ if (!mResultDir.exists()) {
+ throw new RuntimeException("Result Directory was not created: " +
+ mResultDir.getAbsolutePath());
+ }
+
+ CLog.d("Results Directory: %s", mResultDir.getAbsolutePath());
+ }
+}
\ No newline at end of file
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/PreviousResultLoader.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/PreviousResultLoader.java
index 1e4289a..2059109 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/PreviousResultLoader.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/suite/PreviousResultLoader.java
@@ -21,11 +21,18 @@
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.invoker.IInvocationContext;
+import com.android.tradefed.invoker.InvocationContext;
import com.android.tradefed.invoker.TestInvocation;
-import com.android.tradefed.result.suite.SuiteResultHolder;
+import com.android.tradefed.invoker.proto.InvocationContext.Context;
+import com.android.tradefed.result.proto.TestRecordProto.TestRecord;
import com.android.tradefed.testtype.suite.retry.ITestSuiteResultLoader;
+import com.google.protobuf.InvalidProtocolBufferException;
+
+import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.List;
/**
@@ -41,27 +48,35 @@
mandatory = true)
private Integer mRetrySessionId = null;
- private SuiteResultHolder mPreviousResults;
+ private TestRecord mTestRecord;
@Override
public void init(IInvocationContext context) {
IBuildInfo info = context.getBuildInfos().get(0);
CompatibilityBuildHelper helperBuild = new CompatibilityBuildHelper(info);
- CertificationResultXml loader = new CertificationResultXml();
try {
- mPreviousResults = loader.parseResults(
- ResultHandler.getResultDirectory(helperBuild.getResultsDir(), mRetrySessionId));
+ File resultDir = ResultHandler.getResultDirectory(
+ helperBuild.getResultsDir(), mRetrySessionId);
+ try (InputStream stream = new FileInputStream(
+ new File(resultDir, CompatibilityProtoResultReporter.PROTO_FILE_NAME))) {
+ mTestRecord = TestRecord.parseDelimitedFrom(stream);
+ }
} catch (IOException e) {
throw new RuntimeException(e);
}
- if (mPreviousResults == null) {
- throw new RuntimeException("Failed to load the previous results.");
- }
}
@Override
public String getCommandLine() {
- List<String> command = mPreviousResults.context.getAttributes().get(
+ Context context = null;
+ try {
+ context = mTestRecord.getDescription().unpack(Context.class);
+ } catch (InvalidProtocolBufferException e) {
+ throw new RuntimeException(e);
+ }
+ IInvocationContext invocContext = InvocationContext.fromProto(context);
+
+ List<String> command = invocContext.getAttributes().get(
TestInvocation.COMMAND_ARGS_KEY);
if (command == null) {
throw new RuntimeException("Couldn't find the command line arg.");
@@ -70,7 +85,7 @@
}
@Override
- public SuiteResultHolder loadPreviousResults() {
- return mPreviousResults;
+ public TestRecord loadPreviousRecord() {
+ return mTestRecord;
}
}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/PreviousResultLoaderTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/PreviousResultLoaderTest.java
index 8bb9dd5..f5c6587 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/PreviousResultLoaderTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/suite/PreviousResultLoaderTest.java
@@ -22,12 +22,16 @@
import com.android.tradefed.build.DeviceBuildInfo;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.ConfigurationDef;
+import com.android.tradefed.config.ConfigurationDescriptor;
import com.android.tradefed.config.OptionSetter;
import com.android.tradefed.invoker.IInvocationContext;
import com.android.tradefed.invoker.InvocationContext;
-import com.android.tradefed.result.suite.SuiteResultHolder;
+import com.android.tradefed.invoker.TestInvocation;
+import com.android.tradefed.result.proto.TestRecordProto.TestRecord;
import com.android.tradefed.util.FileUtil;
+import com.google.protobuf.Any;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -35,6 +39,7 @@
import org.junit.runners.JUnit4;
import java.io.File;
+import java.io.FileOutputStream;
/**
* Unit tests for {@link PreviousResultLoader}.
@@ -45,6 +50,7 @@
private PreviousResultLoader mLoader;
private IInvocationContext mContext;
private File mRootDir;
+ private File mProtoFile;
@Before
public void setUp() throws Exception {
@@ -52,6 +58,9 @@
OptionSetter setter = new OptionSetter(mLoader);
setter.setOptionValue("retry", "0");
mContext = new InvocationContext();
+ mContext.setConfigurationDescriptor(new ConfigurationDescriptor());
+ mContext.addInvocationAttribute(TestInvocation.COMMAND_ARGS_KEY,
+ "cts -m CtsGesture --skip-all-system-status-check");
}
@After
@@ -65,12 +74,16 @@
@Test
public void testReloadTests_failed() throws Exception {
mContext.addDeviceBuildInfo(ConfigurationDef.DEFAULT_DEVICE_NAME, createFakeBuild(""));
+ // Delete the proto file
+ mProtoFile.delete();
try {
mLoader.init(mContext);
fail("Should have thrown an exception.");
} catch (RuntimeException expected) {
// expected
- assertEquals("Failed to load the previous results.", expected.getMessage());
+ assertEquals(
+ String.format("java.io.FileNotFoundException: %s (No such file or directory)",
+ mProtoFile.getAbsolutePath()), expected.getMessage());
}
}
@@ -83,8 +96,7 @@
createFakeBuild(createBasicResults()));
mLoader.init(mContext);
assertEquals("cts -m CtsGesture --skip-all-system-status-check", mLoader.getCommandLine());
- SuiteResultHolder results = mLoader.loadPreviousResults();
- assertEquals(2, results.totalModules);
+ mLoader.loadPreviousRecord();
}
private IBuildInfo createFakeBuild(String resultContent) throws Exception {
@@ -101,6 +113,12 @@
File testResult = new File(new CompatibilityBuildHelper(build).getResultDir(),
"test_result.xml");
testResult.createNewFile();
+ // Populate a proto result
+ mProtoFile = new File(new CompatibilityBuildHelper(build).getResultDir(),
+ CompatibilityProtoResultReporter.PROTO_FILE_NAME);
+ TestRecord.Builder builder = TestRecord.newBuilder();
+ builder.setDescription(Any.pack(mContext.toProto()));
+ builder.build().writeDelimitedTo(new FileOutputStream(mProtoFile));
FileUtil.writeToFile(resultContent, testResult);
return build;
}
diff --git a/tools/cts-tradefed/res/config/cts-suite.xml b/tools/cts-tradefed/res/config/cts-suite.xml
index ca2cb2c..080f8f1 100644
--- a/tools/cts-tradefed/res/config/cts-suite.xml
+++ b/tools/cts-tradefed/res/config/cts-suite.xml
@@ -65,5 +65,6 @@
<template-include name="metadata-reporters" default="empty" />
<result_reporter class="com.android.compatibility.common.tradefed.result.ConsoleReporter" />
+ <result_reporter class="com.android.compatibility.common.tradefed.result.suite.CompatibilityProtoResultReporter" />
<result_reporter class="com.android.compatibility.common.tradefed.result.suite.CertificationSuiteResultReporter" />
</configuration>