Add an optional external reference URL to result reporter.

bug:16680794
Change-Id: I417c3853eb485e3a1073fa3c07604527d3b44598
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
index f6e10d0..956f1b1 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
@@ -29,6 +29,7 @@
 import com.android.tradefed.config.Option.Importance;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.ITestSummaryListener;
 import com.android.tradefed.result.InputStreamSource;
 import com.android.tradefed.result.LogDataType;
 import com.android.tradefed.result.LogFileSaver;
@@ -45,6 +46,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -56,7 +58,7 @@
  * <p/>
  * Outputs xml in format governed by the cts_result.xsd
  */
-public class CtsXmlResultReporter implements ITestInvocationListener {
+public class CtsXmlResultReporter implements ITestInvocationListener, ITestSummaryListener {
     private static final String LOG_TAG = "CtsXmlResultReporter";
 
     static final String TEST_RESULT_FILE_NAME = "testResult.xml";
@@ -100,6 +102,7 @@
     private ResultReporter mReporter;
     private File mLogDir;
     private String mSuiteName;
+    private String mReferenceUrl;
 
     private static final Pattern mCtsLogPattern = Pattern.compile("(.*)\\+\\+\\+\\+(.*)");
 
@@ -313,7 +316,7 @@
         zipResults(mReportDir);
 
         try {
-            mReporter.reportResult(reportFile);
+            mReporter.reportResult(reportFile, mReferenceUrl);
         } catch (IOException e) {
             CLog.e(e);
         }
@@ -472,4 +475,17 @@
     public TestSummary getSummary() {
         return null;
     }
+
+    /**
+     * {@inheritDoc}
+     */
+     @Override
+     public void putSummary(List<TestSummary> summaries) {
+         // By convention, only store the first summary that we see as the summary URL.
+         if (summaries.isEmpty()) {
+             return;
+         }
+
+         mReferenceUrl = summaries.get(0).getSummary().getString();
+     }
 }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java
index 199cbc5..39969d3 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java
@@ -21,6 +21,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+import javax.annotation.Nullable;
+
 /**
  * Class that sends a HTTP POST multipart/form-data request containing
  * the test result XML.
@@ -37,7 +39,7 @@
         mSuiteName = suiteName;
     }
 
-    public void reportResult(File reportFile) throws IOException {
+    public void reportResult(File reportFile, @Nullable String referenceUrl) throws IOException {
         if (isEmpty(mServerUrl)) {
             return;
         }
@@ -45,16 +47,19 @@
         InputStream input = new FileInputStream(reportFile);
         try {
             byte[] data = IssueReporter.getBytes(input, RESULT_XML_BYTES);
-            new MultipartForm(mServerUrl)
+            MultipartForm multipartForm = new MultipartForm(mServerUrl)
                     .addFormValue("suite", mSuiteName)
-                    .addFormFile("resultXml", "testResult.xml.gz", data)
-                    .submit();
+                    .addFormFile("resultXml", "testResult.xml.gz", data);
+            if (!isEmpty(referenceUrl)) {
+                multipartForm.addFormValue("referenceUrl", referenceUrl);
+            }
+            multipartForm.submit();
         } finally {
             input.close();
         }
     }
 
-    private boolean isEmpty(String value) {
+    private static boolean isEmpty(String value) {
         return value == null || value.trim().isEmpty();
     }
 }
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
index 5776568..26cf39c 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
@@ -21,6 +21,7 @@
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.build.IFolderBuildInfo;
 import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.TestSummary;
 import com.android.tradefed.result.XmlResultReporter;
 import com.android.tradefed.util.FileUtil;
 
@@ -32,7 +33,10 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -40,6 +44,8 @@
  */
 public class CtsXmlResultReporterTest extends TestCase {
 
+    private static final List<TestSummary> SUMMARY_LIST =
+            new ArrayList<>(Arrays.asList(new TestSummary("TEST_SUMMARY_URL")));
     private CtsXmlResultReporter mResultReporter;
     private ByteArrayOutputStream mOutputStream;
     private File mReportDir;
@@ -116,6 +122,7 @@
         mResultReporter.testEnded(testId, emptyMap);
         mResultReporter.testRunEnded(3000, emptyMap);
         mResultReporter.invocationEnded(1);
+        mResultReporter.putSummary(SUMMARY_LIST);
         String output =  getOutput();
         CLog.d("Actual output: %s", output);
         System.out.println(output);