Introduce support for JSON as a test result type, including sample test case.
Change-Id: If2e0454e30b62f52311e156beed0024f615669ce
Reviewed-on: http://fulliautomatix.ics.uci.edu:8443/92
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <westmann@gmail.com>
diff --git a/asterix-app/src/test/java/edu/uci/ics/asterix/test/dml/DmlTest.java b/asterix-app/src/test/java/edu/uci/ics/asterix/test/dml/DmlTest.java
index 0f2aeb8..7efca6f 100644
--- a/asterix-app/src/test/java/edu/uci/ics/asterix/test/dml/DmlTest.java
+++ b/asterix-app/src/test/java/edu/uci/ics/asterix/test/dml/DmlTest.java
@@ -65,7 +65,8 @@
         }
         asterixLoad.execute();
         File enlistFile = new File(ENLIST_FILE);
-        String resultFileName = TestsUtils.aqlExtToResExt(enlistFile.getName());
+        int dot = enlistFile.getName().lastIndexOf('.');
+        String resultFileName = enlistFile.getName().substring(0, dot + 1) + ".adm";
         File expectedFile = new File(PATH_EXPECTED + SEPARATOR + resultFileName);
         File actualFile = new File(PATH_ACTUAL + SEPARATOR + resultFileName);
         // Khurram
diff --git a/asterix-app/src/test/resources/runtimets/queries/json/int01/int01.1.query.aql b/asterix-app/src/test/resources/runtimets/queries/json/int01/int01.1.query.aql
new file mode 100644
index 0000000..3b8e816
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/json/int01/int01.1.query.aql
@@ -0,0 +1 @@
+[ 1, 2 ]
diff --git a/asterix-app/src/test/resources/runtimets/results/json/int01/int01.1.json b/asterix-app/src/test/resources/runtimets/results/json/int01/int01.1.json
new file mode 100644
index 0000000..3448068
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/json/int01/int01.1.json
@@ -0,0 +1,7 @@
+{ "orderedlist": [ { "int32":
+1
+}
+, { "int32":
+2
+}
+ ] }
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 6344bc1..50f5ce2 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -5117,4 +5117,11 @@
       </compilation-unit>
     </test-case>
   </test-group>
+  <test-group name="json">
+    <test-case FilePath="json">
+      <compilation-unit name="int01">
+        <output-dir compare="JSON">int01</output-dir>
+      </compilation-unit>
+    </test-case>
+  </test-group>
 </test-suite>
diff --git a/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java b/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
index 0bbbca3..db37237 100644
--- a/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
+++ b/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
@@ -51,12 +51,13 @@
 
 import edu.uci.ics.asterix.common.config.GlobalConfig;
 import edu.uci.ics.asterix.testframework.context.TestCaseContext;
+import edu.uci.ics.asterix.testframework.context.TestCaseContext.OutputFormat;
 import edu.uci.ics.asterix.testframework.context.TestFileContext;
+import edu.uci.ics.asterix.testframework.xml.ComparisonEnum;
 import edu.uci.ics.asterix.testframework.xml.TestCase.CompilationUnit;
 
 public class TestsUtils {
 
-    private static final String EXTENSION_AQL_RESULT = "adm";
     private static final Logger LOGGER = Logger.getLogger(TestsUtils.class.getName());
     private static Method managixExecuteMethod = null;
 
@@ -152,11 +153,6 @@
         return true;
     }
 
-    public static String aqlExtToResExt(String fname) {
-        int dot = fname.lastIndexOf('.');
-        return fname.substring(0, dot + 1) + EXTENSION_AQL_RESULT;
-    }
-
     private static void writeResultsToFile(File actualFile, InputStream resultStream) throws Exception {
         BufferedWriter writer = new BufferedWriter(new FileWriter(actualFile));
         try {
@@ -194,7 +190,7 @@
     }
 
     // Executes Query and returns results as JSONArray
-    public static InputStream executeQuery(String str) throws Exception {
+    public static InputStream executeQuery(String str, OutputFormat fmt) throws Exception {
         InputStream resultStream = null;
 
         final String url = "http://localhost:19002/query";
@@ -206,6 +202,12 @@
         GetMethod method = new GetMethod(url);
         method.setQueryString(new NameValuePair[] { new NameValuePair("query", str) });
 
+        // For now, ADM means "default", which is what is returned when no
+        // explicit Accept: header is specified.
+        if (fmt == OutputFormat.JSON) {
+            method.setRequestHeader("Accept", "application/json");
+        }
+
         // Provide custom retry handler is necessary
         method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
 
@@ -397,22 +399,18 @@
                                         + File.separator + "stop_and_start.sh");
                             }
 
-                            resultStream = executeQuery(statement);
+                            resultStream = executeQuery(statement, OutputFormat.forCompilationUnit(cUnit));
                             if (queryCount >= expectedResultFileCtxs.size()) {
                                 throw new IllegalStateException("no result file for " + testFile.toString());
                             }
                             expectedResultFile = expectedResultFileCtxs.get(queryCount).getFile();
 
-                            File actualFile = new File(actualPath + File.separator
-                                    + testCaseCtx.getTestCase().getFilePath().replace(File.separator, "_") + "_"
-                                    + cUnit.getName() + ".adm");
-                            TestsUtils.writeResultsToFile(actualFile, resultStream);
-
                             File actualResultFile = testCaseCtx.getActualResultFile(cUnit, new File(actualPath));
                             actualResultFile.getParentFile().mkdirs();
+                            TestsUtils.writeResultsToFile(actualResultFile, resultStream);
 
                             TestsUtils.runScriptAndCompareWithResult(testFile, new PrintWriter(System.err),
-                                    expectedResultFile, actualFile);
+                                    expectedResultFile, actualResultFile);
                             LOGGER.info("[TEST]: " + testCaseCtx.getTestCase().getFilePath() + "/" + cUnit.getName()
                                     + " PASSED ");
 
@@ -422,7 +420,7 @@
                             executeManagixCommand(statement);
                             break;
                         case "txnqbc": //qbc represents query before crash
-                            resultStream = executeQuery(statement);
+                            resultStream = executeQuery(statement, OutputFormat.forCompilationUnit(cUnit));
                             qbcFile = new File(actualPath + File.separator
                                     + testCaseCtx.getTestCase().getFilePath().replace(File.separator, "_") + "_"
                                     + cUnit.getName() + "_qbc.adm");
@@ -430,7 +428,7 @@
                             TestsUtils.writeResultsToFile(qbcFile, resultStream);
                             break;
                         case "txnqar": //qar represents query after recovery
-                            resultStream = executeQuery(statement);
+                            resultStream = executeQuery(statement, OutputFormat.forCompilationUnit(cUnit));
                             qarFile = new File(actualPath + File.separator
                                     + testCaseCtx.getTestCase().getFilePath().replace(File.separator, "_") + "_"
                                     + cUnit.getName() + "_qar.adm");
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/json/AListPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/json/AListPrinter.java
index f55e450..1acedbd 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/json/AListPrinter.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/json/AListPrinter.java
@@ -31,9 +31,9 @@
  * APrintVisitor.
  */
 class AListPrinter {
-    private static String BEGIN = "{ unorderedlist: [";
-    private static String BEGIN_ORDERED = "{ orderedlist: [";
-    private static String END = " ]}";
+    private static String BEGIN = "{ \"unorderedlist\": [ ";
+    private static String BEGIN_ORDERED = "{ \"orderedlist\": [ ";
+    private static String END = " ] }";
     private static String COMMA = ", ";
 
     private final Pair<PrintStream, ATypeTag> itemVisitorArg = new Pair<PrintStream, ATypeTag>(null, null);
diff --git a/asterix-test-framework/src/main/java/edu/uci/ics/asterix/testframework/context/TestCaseContext.java b/asterix-test-framework/src/main/java/edu/uci/ics/asterix/testframework/context/TestCaseContext.java
index 8cca085..b3e4de9e 100644
--- a/asterix-test-framework/src/main/java/edu/uci/ics/asterix/testframework/context/TestCaseContext.java
+++ b/asterix-test-framework/src/main/java/edu/uci/ics/asterix/testframework/context/TestCaseContext.java
@@ -28,6 +28,47 @@
 import edu.uci.ics.asterix.testframework.xml.TestSuiteParser;
 
 public class TestCaseContext {
+
+    /**
+     * For specifying the desired output formatting of results.
+     */
+    public enum OutputFormat {
+        NONE  ("", ""),
+        ADM   ("adm", "application/adm"),
+        JSON  ("json", "application/json");
+
+        private final String extension;
+        private final String mimetype;
+        OutputFormat(String ext, String mime) {
+            this.extension = ext;
+            this.mimetype = mime;
+        }
+
+        public String extension() {
+            return extension;
+        }
+
+        public String mimeType() {
+            return mimetype;
+        }
+
+        //
+        public static OutputFormat forCompilationUnit(CompilationUnit cUnit) {
+            switch (cUnit.getOutputDir().getCompare()) {
+            case TEXT:
+                return OutputFormat.ADM;
+            case JSON:
+                return OutputFormat.JSON;
+            case INSPECT:
+            case IGNORE:
+                return OutputFormat.NONE;
+            default:
+                assert false: "Unknown ComparisonEnum!";
+                return OutputFormat.NONE;
+            }
+        }
+    };
+
     public static final String DEFAULT_TESTSUITE_XML_NAME = "testsuite.xml";
 
     private File tsRoot;
@@ -108,7 +149,8 @@
         File path = actualResultsBase;
         path = new File(path, testSuite.getResultOffsetPath());
         path = new File(path, testCase.getFilePath());
-        return new File(path, cUnit.getOutputDir().getValue() + ".adm");
+        return new File(path, cUnit.getOutputDir().getValue() + "." +
+                        OutputFormat.forCompilationUnit(cUnit).extension());
     }
 
     public static class Builder {
diff --git a/asterix-test-framework/src/main/resources/Catalog.xsd b/asterix-test-framework/src/main/resources/Catalog.xsd
index 763309e..78c401e 100644
--- a/asterix-test-framework/src/main/resources/Catalog.xsd
+++ b/asterix-test-framework/src/main/resources/Catalog.xsd
@@ -186,6 +186,7 @@
          <xs:enumeration value="Text"/>

          <xs:enumeration value="Inspect"/>

          <xs:enumeration value="Ignore"/>

+         <xs:enumeration value="JSON"/>

       </xs:restriction>

    </xs:simpleType>