blob: 8ef942624d542325517be67af8f82cedc984ebf5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.vxquery.xtest;
import static org.apache.vxquery.rest.Constants.HttpHeaderValues.CONTENT_TYPE_JSON;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.bind.JAXBException;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.vxquery.app.util.RestUtils;
import org.apache.vxquery.exceptions.ErrorCode;
import org.apache.vxquery.exceptions.SystemException;
import org.apache.vxquery.rest.request.QueryRequest;
import org.apache.vxquery.rest.response.APIResponse;
import org.apache.vxquery.rest.response.ErrorResponse;
import org.apache.vxquery.rest.response.SyncQueryResponse;
import org.codehaus.jackson.map.ObjectMapper;
public class TestRunner {
private static final Pattern EMBEDDED_SYSERROR_PATTERN = Pattern.compile("(\\p{javaUpperCase}{4}\\d{4})");
private XTestOptions opts;
public TestRunner(XTestOptions opts) throws UnknownHostException {
this.opts = opts;
}
public void open() throws Exception {
}
public TestCaseResult run(final TestCase testCase) {
TestCaseResult res = new TestCaseResult(testCase);
runQueries(testCase, res);
return res;
}
public void runQuery(TestCase testCase, TestCaseResult res) {
if (opts.verbose) {
System.err.println("Starting " + testCase.getXQueryDisplayName());
}
long start = System.currentTimeMillis();
try {
String query = FileUtils.readFileToString(testCase.getXQueryFile(), "UTF-8");
if (opts.showQuery) {
System.err.println("***Query for " + testCase.getXQueryDisplayName() + ": ");
System.err.println(query);
}
QueryRequest request = createQueryRequest(opts, query);
APIResponse response = sendQueryRequest(request, testCase.getSourceFileMap());
if (response instanceof SyncQueryResponse) {
res.result = ((SyncQueryResponse) response).getResults();
} else {
System.err.println("Error response: Failure when running the query");
ErrorResponse errorResponse = (ErrorResponse) response;
Matcher m = EMBEDDED_SYSERROR_PATTERN.matcher(errorResponse.getError().getMessage());
Exception e = new RuntimeException("Failed to run the query");
if (m.find()) {
String eCode = m.group(1);
throw new SystemException(ErrorCode.valueOf(eCode), e);
} else {
throw e;
}
}
} catch (Throwable e) {
res.error = e;
} finally {
try {
res.compare();
} catch (Exception e) {
System.err.println("Framework error");
e.printStackTrace();
}
long end = System.currentTimeMillis();
res.time = end - start;
}
if (opts.showResult) {
if (res.result == null) {
System.err.println("***Error: ");
System.err.println("Message: " + res.error.getMessage());
res.error.printStackTrace();
} else {
System.err.println("***Result: ");
System.err.println(res.result);
}
}
}
private static QueryRequest createQueryRequest(XTestOptions opts, String query) {
QueryRequest request = new QueryRequest(query);
request.setCompileOnly(opts.compileOnly);
request.setOptimization(opts.optimizationLevel);
request.setFrameSize(opts.frameSize);
request.setShowAbstractSyntaxTree(opts.showAST);
request.setShowTranslatedExpressionTree(opts.showTET);
request.setShowOptimizedExpressionTree(opts.showOET);
request.setShowRuntimePlan(opts.showRP);
request.setAsync(false);
return request;
}
private static APIResponse sendQueryRequest(QueryRequest request, Map<String, File> sourceFileMap)
throws IOException, URISyntaxException {
URI uri = RestUtils.buildQueryURI(request, TestClusterUtil.localClusterUtil.getIpAddress(),
TestClusterUtil.localClusterUtil.getRestPort());
CloseableHttpClient httpClient = HttpClients.custom().build();
try {
HttpPost httpRequest = new HttpPost(uri);
httpRequest.setHeader(HttpHeaders.ACCEPT, CONTENT_TYPE_JSON);
ObjectMapper mapper = new ObjectMapper();
String fileMap = mapper.writeValueAsString(sourceFileMap);
httpRequest.setEntity(new StringEntity(fileMap, StandardCharsets.UTF_8));
try (CloseableHttpResponse httpResponse = httpClient.execute(httpRequest)) {
HttpEntity entity = httpResponse.getEntity();
String response = RestUtils.readEntity(entity);
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
return RestUtils.mapEntity(response, SyncQueryResponse.class, CONTENT_TYPE_JSON);
} else {
return RestUtils.mapEntity(response, ErrorResponse.class, CONTENT_TYPE_JSON);
}
} catch (IOException e) {
System.err.println("Error occurred when reading entity: " + e.getMessage());
} catch (JAXBException e) {
System.err.println("Error occurred when mapping query response: " + e.getMessage());
}
} finally {
HttpClientUtils.closeQuietly(httpClient);
}
return null;
}
public void runQueries(TestCase testCase, TestCaseResult res) {
runQuery(testCase, res);
}
public void close() throws Exception {
// TODO add a close statement for the hyracks connection.
}
}