blob: 7e9b08fff894a89bbf4718e0044ca0bdac3a2d2f [file] [log] [blame]
package edu.uci.ics.asterix.test.aql;
import static org.junit.Assert.fail;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.logging.Logger;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import edu.uci.ics.asterix.testframework.context.TestCaseContext;
import edu.uci.ics.asterix.testframework.context.TestFileContext;
import edu.uci.ics.asterix.testframework.xml.TestCase.CompilationUnit;
import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
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;
/**
* Probably does not work well with symlinks.
*/
public static boolean deleteRec(File path) {
if (path.isDirectory()) {
for (File f : path.listFiles()) {
if (!deleteRec(f)) {
return false;
}
}
}
return path.delete();
}
public static void runScriptAndCompareWithResult(File scriptFile,
PrintWriter print, File expectedFile, File actualFile)
throws Exception {
BufferedReader readerExpected = new BufferedReader(
new InputStreamReader(new FileInputStream(expectedFile),
"UTF-8"));
BufferedReader readerActual = new BufferedReader(new InputStreamReader(
new FileInputStream(actualFile), "UTF-8"));
String lineExpected, lineActual;
int num = 1;
try {
while ((lineExpected = readerExpected.readLine()) != null) {
lineActual = readerActual.readLine();
// Assert.assertEquals(lineExpected, lineActual);
if (lineActual == null) {
if (lineExpected.isEmpty()) {
continue;
}
throw new Exception("Result for " + scriptFile
+ " changed at line " + num + ":\n< "
+ lineExpected + "\n> ");
}
if (!equalStrings(lineExpected.split("Timestamp")[0],
lineActual.split("Timestamp")[0])) {
fail("Result for " + scriptFile + " changed at line " + num
+ ":\n< " + lineExpected + "\n> " + lineActual);
}
++num;
}
lineActual = readerActual.readLine();
// Assert.assertEquals(null, lineActual);
if (lineActual != null) {
throw new Exception("Result for " + scriptFile
+ " changed at line " + num + ":\n< \n> " + lineActual);
}
// actualFile.delete();
} finally {
readerExpected.close();
readerActual.close();
}
}
private static boolean equalStrings(String s1, String s2) {
String[] rowsOne = s1.split("\n");
String[] rowsTwo = s2.split("\n");
for (int i = 0; i < rowsOne.length; i++) {
String row1 = rowsOne[i];
String row2 = rowsTwo[i];
if (row1.equals(row2))
continue;
String[] fields1 = row1.split(" ");
String[] fields2 = row2.split(" ");
for (int j = 0; j < fields1.length; j++) {
if (fields1[j].equals(fields2[j])) {
continue;
} else if (fields1[j].indexOf('.') < 0) {
return false;
} else {
fields1[j] = fields1[j].split(",")[0];
fields2[j] = fields2[j].split(",")[0];
Double double1 = Double.parseDouble(fields1[j]);
Double double2 = Double.parseDouble(fields2[j]);
float float1 = (float) double1.doubleValue();
float float2 = (float) double2.doubleValue();
if (Math.abs(float1 - float2) == 0)
continue;
else {
return false;
}
}
}
}
return true;
}
public static String aqlExtToResExt(String fname) {
int dot = fname.lastIndexOf('.');
return fname.substring(0, dot + 1) + EXTENSION_AQL_RESULT;
}
public static void writeResultsToFile(File actualFile, JSONObject result)
throws IOException, JSONException {
BufferedWriter writer = new BufferedWriter(new FileWriter(actualFile));
Results res = new Results(result);
for (String line : res) {
writer.write(line);
writer.newLine();
}
writer.close();
}
public static class Results implements Iterable<String> {
private final JSONArray chunks;
public Results(JSONObject result) throws JSONException {
chunks = result.getJSONArray("results");
}
public Iterator<String> iterator() {
return new ResultIterator(chunks);
}
}
public static class ResultIterator implements Iterator<String> {
private final JSONArray chunks;
private int chunkCounter = 0;
private int recordCounter = 0;
public ResultIterator(JSONArray chunks) {
this.chunks = chunks;
}
@Override
public boolean hasNext() {
JSONArray resultArray;
try {
resultArray = chunks.getJSONArray(chunkCounter);
if (resultArray.getString(recordCounter) != null) {
return true;
}
} catch (JSONException e) {
return false;
}
return false;
}
@Override
public String next() throws NoSuchElementException {
JSONArray resultArray;
String item = "";
try {
resultArray = chunks.getJSONArray(chunkCounter);
item = resultArray.getString(recordCounter);
if (item == null) {
throw new NoSuchElementException();
}
item = item.trim();
recordCounter++;
if (recordCounter >= resultArray.length()) {
chunkCounter++;
recordCounter = 0;
}
} catch (JSONException e) {
throw new NoSuchElementException(e.getMessage());
}
return item;
}
@Override
public void remove() {
throw new NotImplementedException();
}
}
// Executes Query and returns results as JSONArray
public static JSONObject executeQuery(String str) throws Exception {
final String url = "http://localhost:19101/query";
// Create an instance of HttpClient.
HttpClient client = new HttpClient();
// Create a method instance.
GetMethod method = new GetMethod(url);
method.setQueryString(new NameValuePair[] { new NameValuePair("query",
str) });
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
JSONObject result = null;
try {
// Execute the method.
int statusCode = client.executeMethod(method);
// Check if the method was executed successfully.
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
// Read the response body as String.
String responseBody = method.getResponseBodyAsString();
result = new JSONObject(responseBody);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
return result;
}
// To execute Update statements
// Insert and Delete statements are executed here
public static void executeUpdate(String str) throws Exception {
final String url = "http://localhost:19101/update";
// Create an instance of HttpClient.
HttpClient client = new HttpClient();
// Create a method instance.
GetMethod method = new GetMethod(url);
method.setQueryString(new NameValuePair[] { new NameValuePair(
"statements", str) });
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
// Execute the method.
int statusCode = client.executeMethod(method);
// Check if the method was executed successfully.
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
}
// To execute DDL and Update statements
// create type statement
// create dataset statement
// create index statement
// create dataverse statement
// create function statement
public static void executeDDL(String str) throws Exception {
final String url = "http://localhost:19101/ddl";
// Create an instance of HttpClient.
HttpClient client = new HttpClient();
// Create a method instance.
GetMethod method = new GetMethod(url);
method.setQueryString(new NameValuePair[] { new NameValuePair("ddl",
str) });
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
// Execute the method.
int statusCode = client.executeMethod(method);
// Check if the method was executed successfully.
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
}
// Method that reads a DDL/Update/Query File
// and returns the contents as a string
// This string is later passed to REST API for execution.
public static String readTestFile(File testFile) throws Exception {
BufferedReader reader = new BufferedReader(new FileReader(testFile));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
return stringBuilder.toString();
}
public static void executeManagixCommand(String command)
throws ClassNotFoundException, NoSuchMethodException,
SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (managixExecuteMethod == null) {
Class clazz = Class
.forName("edu.uci.ics.asterix.installer.test.AsterixInstallerIntegrationUtil");
managixExecuteMethod = clazz.getMethod("executeCommand",
String.class);
}
managixExecuteMethod.invoke(null, command);
}
public static void executeTest(String actualPath,
TestCaseContext testCaseCtx) throws Exception {
File testFile;
File expectedResultFile;
String statement;
List<TestFileContext> expectedResultFileCtxs;
List<TestFileContext> testFileCtxs;
int queryCount = 0;
JSONObject result;
List<CompilationUnit> cUnits = testCaseCtx.getTestCase()
.getCompilationUnit();
for (CompilationUnit cUnit : cUnits) {
LOGGER.info("[TEST]: " + testCaseCtx.getTestCase().getFilePath()
+ "/" + cUnit.getName());
testFileCtxs = testCaseCtx.getTestFiles(cUnit);
expectedResultFileCtxs = testCaseCtx.getExpectedResultFiles(cUnit);
for (TestFileContext ctx : testFileCtxs) {
testFile = ctx.getFile();
statement = TestsUtils.readTestFile(testFile);
try {
switch (ctx.getType()) {
case "ddl":
TestsUtils.executeDDL(statement);
break;
case "update":
TestsUtils.executeUpdate(statement);
break;
case "query":
result = TestsUtils.executeQuery(statement);
if (!cUnit.getExpectedError().isEmpty()) {
if (!result.has("error")) {
throw new Exception("Test \"" + testFile
+ "\" FAILED!");
}
} else {
expectedResultFile = expectedResultFileCtxs.get(
queryCount).getFile();
File actualFile = new File(actualPath
+ File.separator
+ testCaseCtx.getTestCase().getFilePath()
.replace(File.separator, "_") + "_"
+ cUnit.getName() + ".adm");
File actualResultFile = testCaseCtx
.getActualResultFile(cUnit, new File(
actualPath));
actualResultFile.getParentFile().mkdirs();
TestsUtils.writeResultsToFile(actualFile, result);
TestsUtils.runScriptAndCompareWithResult(testFile,
new PrintWriter(System.err),
expectedResultFile, actualFile);
}
queryCount++;
break;
case "mgx":
executeManagixCommand(statement);
break;
default:
throw new IllegalArgumentException(
"No statements of type " + ctx.getType());
}
} catch (Exception e) {
if (cUnit.getExpectedError().isEmpty()) {
throw new Exception(
"Test \"" + testFile + "\" FAILED!", e);
}
}
}
}
}
}