use of org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.TestContainer in project legend-engine by finos.
the class ServiceTestRunner method executeSingleExecutionTest.
private RichServiceTestResult executeSingleExecutionTest(PureSingleExecution execution, String testData, List<TestContainer> asserts, String noAssertMessage, PureModelContextData pureModelContextData, PureModel pureModel, Scope scope) throws IOException, JavaCompileException {
if (asserts == null || asserts.isEmpty()) {
scope.span().log(noAssertMessage);
return new RichServiceTestResult(service.getPath(), Collections.emptyMap(), Collections.emptyMap(), null, null, null);
} else {
Runtime testRuntime = ServiceTestGenerationHelper.buildTestRuntime(execution.runtime, execution.mapping, testData, pureModelContextData, pureModel);
RichIterable<? extends String> sqlStatements = extractSetUpSQLFromTestRuntime(testRuntime);
PureSingleExecution testPureSingleExecution = shallowCopySingleExecution(execution);
testPureSingleExecution.runtime = testRuntime;
ExecutionPlan executionPlan = generatePlan(testPureSingleExecution);
SingleExecutionPlan singleExecutionPlan = (SingleExecutionPlan) executionPlan;
compilePlan(singleExecutionPlan);
return executeTestAsserts(singleExecutionPlan, asserts, sqlStatements, scope);
}
}
use of org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.TestContainer in project legend-engine by finos.
the class ServiceTestRunner method executeTestAsserts.
@Prometheus(name = "service test execute", doc = "Execution duration summary within service test execution")
private RichServiceTestResult executeTestAsserts(SingleExecutionPlan executionPlan, List<TestContainer> asserts, RichIterable<? extends String> sqlStatements, Scope scope) throws IOException {
long start = System.currentTimeMillis();
if (ExecutionNodeTDSResultHelper.isResultTDS(executionPlan.rootExecutionNode) || (executionPlan.rootExecutionNode.isResultPrimitiveType() && "String".equals(executionPlan.rootExecutionNode.getDataTypeResultType()))) {
// Java
String packageName = "org.finos.legend.tests.generated";
String className = "TestSuite";
String javaCode = ServiceTestGenerationHelper.generateJavaForAsserts(asserts, this.service, this.pureModel, packageName, className);
Class<?> assertsClass;
RichServiceTestResult testRun;
try {
assertsClass = compileJavaForAsserts(packageName, className, javaCode);
} catch (JavaCompileException e) {
MetricsHandler.incrementErrorCount("test_execute", 0);
throw new RuntimeException("Error compiling test asserts for " + this.service.getPath(), e);
}
scope.span().log("Java asserts generated and compiled");
TestExecutionScope execScope = null;
try {
// Setup test database if needed
if (sqlStatements != null) {
execScope = TestExecutionScope.setupTestServer(sqlStatements, scope);
}
// Run tests
Map<String, TestResult> results = Maps.mutable.empty();
Map<String, Exception> assertExceptions = Maps.mutable.empty();
for (Pair<TestContainer, Integer> tc : LazyIterate.zipWithIndex(asserts)) {
// Build Param Map
Map<String, Result> parameters = Maps.mutable.empty();
if (this.service.execution instanceof PureExecution) {
parameters = ListIterate.zip(((PureExecution) this.service.execution).func.parameters, tc.getOne().parametersValues).toMap(p -> p.getOne().name, p -> // Condition evoked in case of studio-flow
p.getTwo() instanceof Collection ? new ConstantResult(ListIterate.collect(((Collection) p.getTwo()).values, v -> v.accept(new ValueSpecificationToResultVisitor()).getValue())) : // Condition evoked in case of pureIDE-flow
p.getTwo() instanceof PureList ? new ConstantResult(ListIterate.collect(((PureList) p.getTwo()).values, v -> v.accept(new ValueSpecificationToResultVisitor()).getValue())) : p.getTwo().accept(new ValueSpecificationToResultVisitor()));
}
// Execute Plan
ExecutionState testExecutionState = new ExecutionState(parameters, Lists.mutable.withAll(executionPlan.templateFunctions), Lists.mutable.with(new RelationalStoreExecutionState(new RelationalStoreState(execScope == null ? -1 : execScope.getPort())), new InMemoryStoreExecutionState(new InMemoryStoreState()), new ServiceStoreExecutionState(new ServiceStoreState())));
Result result = this.executor.execute(executionPlan, testExecutionState, null, null);
org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.Result<Object> pureResult = result.accept(new ResultToPureResultVisitor());
// Execute Assert
String testName = ServiceTestGenerationHelper.getAssertMethodName(tc.getTwo());
scope.span().setTag(testName, resultToString(pureResult, this.pureModel.getExecutionSupport()));
TestResult testResult;
try {
Boolean assertResult = (Boolean) assertsClass.getMethod(testName, org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.Result.class, ExecutionSupport.class).invoke(null, pureResult, pureModel.getExecutionSupport());
testResult = assertResult ? TestResult.SUCCESS : TestResult.FAILURE;
scope.span().setTag(testName + "_assert", assertResult);
} catch (Exception e) {
StringWriter out = new StringWriter();
PrintWriter writer = new PrintWriter(out);
e.printStackTrace(writer);
e.printStackTrace();
testResult = TestResult.ERROR;
assertExceptions.put(testName, e);
scope.span().setTag(testName + "_assert", out.toString());
}
results.put(testName, testResult);
}
testRun = new RichServiceTestResult(service.getPath(), results, assertExceptions, null, executionPlan, javaCode);
scope.span().log("Finished running tests " + results);
MetricsHandler.observeServerOperation("test_execute", metricsContext, start, System.currentTimeMillis());
} catch (Exception e) {
LOGGER.error("Error running tests", e);
MetricsHandler.incrementErrorCount("test_execute", 0);
throw (e instanceof RuntimeException) ? (RuntimeException) e : new RuntimeException(e);
} finally {
if (execScope != null) {
execScope.close();
}
MetricsHandler.observe("service test execute", start, System.currentTimeMillis());
}
return testRun;
} else {
return new RichServiceTestResult(this.service.getPath(), Collections.emptyMap(), Collections.emptyMap(), null, executionPlan, "");
}
}
use of org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.TestContainer in project legend-engine by finos.
the class ServiceTestGenerationHelper method generateJavaForAsserts.
// Java
public static String generateJavaForAsserts(List<TestContainer> asserts, Service service, PureModel pureModel, String packageName, String className) {
CompileContext compileContext = pureModel.getContext(service);
ProcessorSupport processorSupport = pureModel.getExecutionSupport().getProcessorSupport();
ProcessorContext processorContext = new ProcessorContext(processorSupport, false);
processorContext.setInLineAllLambda(true);
return "package " + packageName + ";\n" + "\n" + "import org.eclipse.collections.api.RichIterable;\n" + "import org.eclipse.collections.api.list.ListIterable;\n" + "import org.eclipse.collections.impl.factory.Lists;\n" + "import org.eclipse.collections.api.map.MutableMap;\n" + "import org.eclipse.collections.impl.map.mutable.UnifiedMap;\n" + "import org.eclipse.collections.impl.factory.Maps;\n" + "import org.finos.legend.pure.generated.*;\n" + "import org.finos.legend.pure.m3.execution.ExecutionSupport;\n" + "import org.finos.legend.pure.runtime.java.compiled.generation.processors.support.CompiledSupport;\n" + "import org.finos.legend.pure.runtime.java.compiled.generation.processors.support.function.*;\n" + "import java.util.Map;" + "" + "public class " + className + "\n" + "{\n" + " private static Map localLambdas = UnifiedMap.newMap();\n" + LazyIterate.collect(asserts, tc -> (InstanceValue) tc._assert.accept(new ValueSpecificationBuilder(compileContext, Lists.mutable.empty(), new ProcessingContext("")))).collect(vs -> ValueSpecificationProcessor.createFunctionForLambda(null, (CoreInstance) vs._values().getAny(), processorSupport, processorContext)).zipWithIndex().collect(tuple -> " public static boolean " + getAssertMethodName(tuple.getTwo()) + "(org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.Result _res, ExecutionSupport es)\n" + " {\n" + " return " + tuple.getOne() + ".value(_res, es);\n" + " }\n").makeString("", "\n", "}");
}
use of org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.TestContainer in project legend-engine by finos.
the class ServiceTestRunner method executeTests.
public List<RichServiceTestResult> executeTests() throws IOException, JavaCompileException {
Execution serviceExecution = this.service.execution;
if (serviceExecution instanceof PureMultiExecution) {
List<RichServiceTestResult> results = Lists.mutable.empty();
try (Scope scope = GlobalTracer.get().buildSpan("Generate Tests And Run For MultiExecution Service").startActive(true)) {
MutableMap<String, KeyedExecutionParameter> executionsByKey = Iterate.groupByUniqueKey(((PureMultiExecution) serviceExecution).executionParameters, e -> e.key);
for (KeyedSingleExecutionTest es : ((MultiExecutionTest) service.test).tests) {
List<TestContainer> asserts = es.asserts;
KeyedExecutionParameter e = executionsByKey.get(es.key);
PureMultiExecution pureExecution = (PureMultiExecution) service.execution;
PureSingleExecution pureSingleExecution = new PureSingleExecution();
pureSingleExecution.func = pureExecution.func;
pureSingleExecution.mapping = e.mapping;
pureSingleExecution.runtime = e.runtime;
pureSingleExecution.executionOptions = e.executionOptions;
String noAssertMessage = "No test assert found for key - " + es.key + "!!";
RichServiceTestResult richServiceTestResult = executeSingleExecutionTest(pureSingleExecution, es.data, asserts, noAssertMessage, pureModelContextData, pureModel, scope);
richServiceTestResult.setOptionalMultiExecutionKey(es.key);
results.add(richServiceTestResult);
}
return results;
}
} else if (serviceExecution instanceof PureSingleExecution) {
try (Scope scope = GlobalTracer.get().buildSpan("Generate Single Pure Tests And Run").startActive(true)) {
List<TestContainer> asserts = ((SingleExecutionTest) service.test).asserts;
String noAssertMessage = "No test assert found !!";
return Collections.singletonList(executeSingleExecutionTest((PureSingleExecution) service.execution, ((SingleExecutionTest) service.test).data, asserts, noAssertMessage, pureModelContextData, pureModel, scope));
}
} else {
try (Scope scope = GlobalTracer.get().buildSpan("Generate Extra Service Execution Tests and Run").startActive(true)) {
MutableList<ServiceExecutionExtension> serviceExecutionExtensions = Lists.mutable.withAll(ServiceLoader.load(ServiceExecutionExtension.class));
Pair<ExecutionPlan, RichIterable<? extends String>> testExecutor = getExtraServiceExecutionPlan(serviceExecutionExtensions, serviceExecution, ((Root_meta_legend_service_metamodel_SingleExecutionTest) this.pureService._test())._data());
ExecutionPlan executionPlan = testExecutor.getOne();
Assert.assertTrue(executionPlan instanceof SingleExecutionPlan, () -> "Only Single Execution Plan supported");
List<TestContainer> containers = getExtraServiceTestContainers(serviceExecutionExtensions, service.test);
return Collections.singletonList(executeTestAsserts((SingleExecutionPlan) executionPlan, containers, testExecutor.getTwo(), scope));
}
}
}
use of org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.TestContainer in project legend-engine by finos.
the class ServiceParseTreeWalker method visitTestContainer.
private TestContainer visitTestContainer(ServiceParserGrammar.TestAssertContext ctx) {
TestContainer testContainer = new TestContainer();
testContainer.sourceInformation = walkerSourceInformation.getSourceInformation(ctx);
testContainer.parametersValues = this.visitTestParameters(ctx.testParameters());
testContainer._assert = this.visitLambda(ctx.combinedExpression());
return testContainer;
}
Aggregations