Search in sources :

Example 1 with TestReturn

use of io.github.microcks.domain.TestReturn in project microcks by microcks.

the class SoapUITestStepsRunner method runOperationTestSteps.

/**
 * Run all the Operation test steps defined into the SoapUI project and having the name
 * contained into testStepNames (if not null nor empty).
 * @param operation The operation to run tests for
 * @param testResult TestResults that aggregate results within.
 * @param endpointUrl The URL of the endpoint to use for request test steps.
 * @param testStepNames A list of test step names to execute
 * @return A list of TestReturn wrapper objects (one by executed test step)
 */
public List<TestReturn> runOperationTestSteps(Operation operation, TestResult testResult, String endpointUrl, List<String> testStepNames) {
    // Remember to force no proxy otherwise SoapUI will use system settings and will
    // make them generally applied to everything going out through Apache Http Client
    // (and maybe also JDK HttpURLConnection ?).
    ProxyUtils.setProxyEnabled(false);
    String operationName = operation.getName();
    List<TestReturn> results = new ArrayList<TestReturn>();
    for (TestSuite testSuite : project.getTestSuiteList()) {
        for (TestCase testCase : testSuite.getTestCaseList()) {
            // Depending on testCase type build an accurate runner.
            TestCaseRunner testCaseRunner = buildTestCaseRunner(testCase);
            if (testCaseRunner != null) {
                for (TestStep testStep : testCase.getTestStepList()) {
                    if (testStep instanceof HttpRequestTestStep && testStep instanceof OperationTestStep && (testStepNames == null || testStepNames.contains(testStep.getName()))) {
                        log.debug("Looking up for testStep for operation '{}'", operationName);
                        if (operationName.equals(((OperationTestStep) testStep).getOperation().getName())) {
                            log.debug("Picking up step '{}' for running SoapUI test", testStep.getName());
                            // Set the endpointUrl using this common interface for Soap and Rest requests.
                            ((HttpRequestTestStep) testStep).getHttpRequest().setEndpoint(endpointUrl);
                            // Add or override existing headers with test specific ones for operation and globals.
                            if (testResult.getOperationsHeaders() != null) {
                                Set<Header> headers = new HashSet<>();
                                if (testResult.getOperationsHeaders().getGlobals() != null) {
                                    headers.addAll(testResult.getOperationsHeaders().getGlobals());
                                }
                                if (testResult.getOperationsHeaders().get(operationName) != null) {
                                    headers.addAll(testResult.getOperationsHeaders().get(operationName));
                                }
                                if (headers.size() > 0) {
                                    StringToStringsMap headersMap = new StringToStringsMap();
                                    for (Header header : headers) {
                                        headersMap.put(header.getName(), new ArrayList<>(header.getValues()));
                                    }
                                    ((HttpRequestTestStep) testStep).getHttpRequest().setRequestHeaders(headersMap);
                                }
                            }
                            // Running tests also checks linked assertions.
                            TestStepResult result = testStep.run(testCaseRunner, testCaseRunner.getRunContext());
                            log.debug("SoapUI test result is " + result.getStatus());
                            results.add(extractTestReturn(testStep.getName(), result));
                        }
                    }
                }
            }
        }
    }
    return results;
}
Also used : TestStepResult(com.eviware.soapui.model.testsuite.TestStepResult) HttpRequestTestStep(com.eviware.soapui.impl.support.http.HttpRequestTestStep) TestReturn(io.github.microcks.domain.TestReturn) ArrayList(java.util.ArrayList) WsdlTestCaseRunner(com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner) StringToStringsMap(com.eviware.soapui.support.types.StringToStringsMap) WsdlTestCase(com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase) HttpRequestTestStep(com.eviware.soapui.impl.support.http.HttpRequestTestStep) HashSet(java.util.HashSet)

Example 2 with TestReturn

use of io.github.microcks.domain.TestReturn in project microcks by microcks.

the class SoapUITestStepsRunner method extractTestReturn.

/**
 */
private TestReturn extractTestReturn(String testStepName, TestStepResult result) {
    int code = TestReturn.FAILURE_CODE;
    if (result.getStatus() == TestStepStatus.OK) {
        code = TestReturn.SUCCESS_CODE;
    }
    String message = null;
    // Re-build request and response.
    Request request = new Request();
    request.setName(testStepName);
    Response response = new Response();
    // SoapUI step result class do not implement a common interface...
    if (result instanceof WsdlTestRequestStepResult) {
        WsdlTestRequestStepResult wtrsr = (WsdlTestRequestStepResult) result;
        request.setContent(wtrsr.getRequestContent());
        request.setHeaders(buildHeaders(wtrsr.getRequestHeaders()));
        response.setContent(wtrsr.getResponseContent());
        response.setHeaders(buildHeaders(wtrsr.getResponseHeaders()));
        message = buildConsolidatedMessage(wtrsr.getMessages());
    }
    if (result instanceof RestRequestStepResult) {
        RestRequestStepResult rrsr = (RestRequestStepResult) result;
        request.setContent(rrsr.getRequestContent());
        request.setHeaders(buildHeaders(rrsr.getRequestHeaders()));
        response.setContent(rrsr.getResponseContent());
        response.setHeaders(buildHeaders(rrsr.getResponseHeaders()));
        message = buildConsolidatedMessage(rrsr.getMessages());
        // or if endpoint is not reached. Consider 404 as a failure in our case.
        if (result.getStatus() == TestStepStatus.UNKNOWN) {
            if (rrsr.getResponse().getStatusCode() == 404) {
                code = TestReturn.FAILURE_CODE;
            } else {
                code = TestReturn.SUCCESS_CODE;
            }
        }
    }
    return new TestReturn(code, result.getTimeTaken(), message, request, response);
}
Also used : TestReturn(io.github.microcks.domain.TestReturn) WsdlTestRequestStepResult(com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStepResult) RestRequestStepResult(com.eviware.soapui.impl.wsdl.teststeps.RestRequestStepResult)

Example 3 with TestReturn

use of io.github.microcks.domain.TestReturn in project microcks by microcks.

the class HttpTestRunner method runTest.

@Override
public List<TestReturn> runTest(Service service, Operation operation, TestResult testResult, List<Request> requests, String endpointUrl, HttpMethod method) throws URISyntaxException, IOException {
    if (log.isDebugEnabled()) {
        log.debug("Launching test run on " + endpointUrl + " for " + requests.size() + " request(s)");
    }
    if (requests.isEmpty()) {
        return null;
    }
    // Initialize result container.
    List<TestReturn> result = new ArrayList<TestReturn>();
    for (Request request : requests) {
        // Reset status code, message and request each time.
        int code = TestReturn.SUCCESS_CODE;
        String message = null;
        String customizedEndpointUrl = endpointUrl;
        if (service.getType().equals(ServiceType.REST)) {
            String operationName = operation.getName();
            // Name may start with verb, remove it if present.
            if (operationName.indexOf(' ') > 0 && operationName.indexOf(' ') < operationName.length()) {
                operationName = operationName.split(" ")[1];
            }
            customizedEndpointUrl += URIBuilder.buildURIFromPattern(operationName, request.getQueryParameters());
            log.debug("Using customized endpoint url: " + customizedEndpointUrl);
        }
        ClientHttpRequest httpRequest = clientHttpRequestFactory.createRequest(new URI(customizedEndpointUrl), method);
        // Set headers to request if any. Start with those coming from request itself.
        // Add or override existing headers with test specific ones for operation and globals.
        Set<Header> headers = new HashSet<>();
        if (request.getHeaders() != null) {
            headers.addAll(request.getHeaders());
        }
        if (testResult.getOperationsHeaders() != null) {
            if (testResult.getOperationsHeaders().getGlobals() != null) {
                headers.addAll(testResult.getOperationsHeaders().getGlobals());
            }
            if (testResult.getOperationsHeaders().get(operation.getName()) != null) {
                headers.addAll(testResult.getOperationsHeaders().get(operation.getName()));
            }
        }
        if (headers.size() > 0) {
            for (Header header : headers) {
                log.debug("Adding header " + header.getName() + " to request");
                httpRequest.getHeaders().add(header.getName(), buildValue(header.getValues()));
            }
            // Update request headers for traceability of possibly added ones.
            request.setHeaders(headers);
        }
        // Now manage specific authorization headers if there's a secret.
        if (secret != null) {
            addAuthorizationHeadersFromSecret(httpRequest, request, secret);
        }
        // Allow extensions to realize some pre-processing of request.
        prepareRequest(request);
        // If there's input content, add it to request.
        if (request.getContent() != null) {
            // Update request content with rendered body if necessary.
            request.setContent(TestRunnerCommons.renderRequestContent(request, headers));
            log.trace("Sending following request content: " + request.getContent());
            httpRequest.getBody().write(request.getContent().getBytes());
        }
        // Actually execute request.
        long startTime = System.currentTimeMillis();
        ClientHttpResponse httpResponse = null;
        try {
            httpResponse = httpRequest.execute();
        } catch (IOException ioe) {
            log.error("IOException while executing request " + request.getName() + " on " + endpointUrl, ioe);
            code = TestReturn.FAILURE_CODE;
            message = ioe.getMessage();
        }
        long duration = System.currentTimeMillis() - startTime;
        // Extract and store response body so that stream may not be consumed more than o1 time ;-)
        String responseContent = null;
        if (httpResponse != null) {
            StringWriter writer = new StringWriter();
            IOUtils.copy(httpResponse.getBody(), writer);
            responseContent = writer.toString();
        }
        // If still in success, check if http code is out of correct ranges (20x and 30x).
        if (code == TestReturn.SUCCESS_CODE) {
            code = extractTestReturnCode(service, operation, request, httpResponse, responseContent);
            message = extractTestReturnMessage(service, operation, request, httpResponse);
        }
        // Create a Response object for returning.
        Response response = new Response();
        if (httpResponse != null) {
            response.setContent(responseContent);
            response.setStatus(String.valueOf(httpResponse.getRawStatusCode()));
            log.debug("Response Content-Type: " + httpResponse.getHeaders().getContentType());
            if (httpResponse.getHeaders().getContentType() != null) {
                response.setMediaType(httpResponse.getHeaders().getContentType().toString());
            }
            headers = buildHeaders(httpResponse);
            if (headers != null) {
                response.setHeaders(headers);
            }
            httpResponse.close();
        }
        result.add(new TestReturn(code, duration, message, request, response));
    }
    return result;
}
Also used : TestReturn(io.github.microcks.domain.TestReturn) ArrayList(java.util.ArrayList) ClientHttpRequest(org.springframework.http.client.ClientHttpRequest) Request(io.github.microcks.domain.Request) IOException(java.io.IOException) ClientHttpRequest(org.springframework.http.client.ClientHttpRequest) URI(java.net.URI) Response(io.github.microcks.domain.Response) ClientHttpResponse(org.springframework.http.client.ClientHttpResponse) Header(io.github.microcks.domain.Header) StringWriter(java.io.StringWriter) ClientHttpResponse(org.springframework.http.client.ClientHttpResponse) HashSet(java.util.HashSet)

Example 4 with TestReturn

use of io.github.microcks.domain.TestReturn in project microcks by microcks.

the class GrpcTestRunner method runTest.

@Override
public List<TestReturn> runTest(Service service, Operation operation, TestResult testResult, List<Request> requests, String endpointUrl, HttpMethod method) throws URISyntaxException, IOException {
    log.debug("Launching test run on {} for {} request(s)", endpointUrl, requests.size());
    if (requests.isEmpty()) {
        return null;
    }
    // Initialize results.
    List<TestReturn> results = new ArrayList<>();
    // Rebuild the GRPC fullMethodName.
    String fullMethodName = service.getXmlNS() + "." + service.getName() + "/" + operation.getName();
    // Build a new GRPC Channel from endpoint URL.
    URL endpoint = new URL(endpointUrl);
    ManagedChannel channel;
    if (endpointUrl.startsWith("https://") || endpoint.getPort() == 443) {
        TlsChannelCredentials.Builder tlsBuilder = TlsChannelCredentials.newBuilder();
        if (secret != null && secret.getCaCertPem() != null) {
            // Install a trust manager with custom CA certificate.
            tlsBuilder.trustManager(new ByteArrayInputStream(secret.getCaCertPem().getBytes(StandardCharsets.UTF_8)));
        } else {
            // Install a trust manager that accepts everything and does not validate certificate chains.
            tlsBuilder.trustManager(new TrustManager[] { new X509TrustManager() {

                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            } });
        }
        // Build a Channel using the TLS Builder.
        channel = Grpc.newChannelBuilderForAddress(endpoint.getHost(), endpoint.getPort(), tlsBuilder.build()).build();
    } else {
        // Build a simple Channel using plain text.
        channel = Grpc.newChannelBuilderForAddress(endpoint.getHost(), endpoint.getPort(), null).usePlaintext().build();
    }
    // In order to produce outgoing byte array, we need the Protobuf binary descriptor that should
    // have been processed while importing the .proto schema for the service.
    List<Resource> resources = resourceRepository.findByServiceIdAndType(service.getId(), ResourceType.PROTOBUF_DESCRIPTOR);
    if (resources == null || resources.size() != 1) {
        log.error("Could not found any pre-processed Protobuf binary descriptor...");
        results.add(new TestReturn(TestReturn.FAILURE_CODE, 0, "Could not found any pre-processed Protobuf binary descriptor...", null, null));
        return results;
    }
    Resource pbResource = resources.get(0);
    Descriptors.MethodDescriptor md = null;
    try {
        md = GrpcUtil.findMethodDescriptor(pbResource.getContent(), service.getName(), operation.getName());
    } catch (Exception e) {
        log.error("Protobuf descriptor cannot be read or parsed: " + e.getMessage());
        results.add(new TestReturn(TestReturn.FAILURE_CODE, 0, "Protobuf descriptor cannot be read or parsed: " + e.getMessage(), null, null));
        return results;
    }
    // Use a builder for out type with a Json parser to merge content and build outMsg.
    DynamicMessage.Builder reqBuilder = DynamicMessage.newBuilder(md.getInputType());
    DynamicMessage.Builder resBuilder = DynamicMessage.newBuilder(md.getOutputType());
    JsonFormat.Parser parser = JsonFormat.parser();
    JsonFormat.Printer printer = JsonFormat.printer();
    for (Request request : requests) {
        // Reset status code, message and request each time.
        int code = TestReturn.SUCCESS_CODE;
        String message = null;
        reqBuilder.clear();
        resBuilder.clear();
        // Now produce the request message byte array.
        parser.merge(request.getContent(), reqBuilder);
        byte[] requestBytes = reqBuilder.build().toByteArray();
        CallOptions callOptions = CallOptions.DEFAULT.withDeadline(Deadline.after(timeout, TimeUnit.MILLISECONDS));
        if (secret != null && secret.getToken() != null) {
            log.debug("Secret contains token and maybe token header, adding them as call credentials");
            callOptions.withCallCredentials(new TokenCallCredentials(secret.getToken(), secret.getTokenHeader()));
        }
        // Actually execute request.
        long startTime = System.currentTimeMillis();
        byte[] responseBytes = ClientCalls.blockingUnaryCall(channel, GrpcUtil.buildGenericUnaryMethodDescriptor(fullMethodName), callOptions, requestBytes);
        long duration = System.currentTimeMillis() - startTime;
        // Create a Response object for returning.
        Response response = new Response();
        response.setStatus("200");
        response.setMediaType("application/x-protobuf");
        response.setContent(new String(responseBytes, "UTF-8"));
        try {
            // Validate incoming message parsing a DynamicMessage.
            DynamicMessage respMsg = DynamicMessage.parseFrom(md.getOutputType(), responseBytes);
            // Now update response content with readable content.
            String respJson = printer.print(respMsg);
            response.setContent(respJson);
            results.add(new TestReturn(code, duration, message, request, response));
        } catch (InvalidProtocolBufferException ipbe) {
            log.error("Received bytes cannot be transformed in " + md.getOutputType().getFullName());
            results.add(new TestReturn(TestReturn.FAILURE_CODE, duration, "Received bytes cannot be transformed in \" + md.getOutputType().getFullName()", request, response));
        }
    }
    return results;
}
Also used : TestReturn(io.github.microcks.domain.TestReturn) ArrayList(java.util.ArrayList) DynamicMessage(com.google.protobuf.DynamicMessage) CallOptions(io.grpc.CallOptions) URL(java.net.URL) JsonFormat(com.google.protobuf.util.JsonFormat) ManagedChannel(io.grpc.ManagedChannel) Descriptors(com.google.protobuf.Descriptors) TlsChannelCredentials(io.grpc.TlsChannelCredentials) Resource(io.github.microcks.domain.Resource) Request(io.github.microcks.domain.Request) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) X509Certificate(java.security.cert.X509Certificate) URISyntaxException(java.net.URISyntaxException) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) IOException(java.io.IOException) Response(io.github.microcks.domain.Response) ByteArrayInputStream(java.io.ByteArrayInputStream) X509TrustManager(javax.net.ssl.X509TrustManager)

Example 5 with TestReturn

use of io.github.microcks.domain.TestReturn in project microcks by microcks.

the class TestRunnerService method launchTestsInternal.

/**
 * Launch tests using asynchronous/completable future pattern.
 * @param testResult TestResults to aggregate results within
 * @param service Service to test
 * @param runnerType Type of runner for launching the tests
 * @return A Future wrapping test results
 */
@Async
public CompletableFuture<TestResult> launchTestsInternal(TestResult testResult, Service service, TestRunnerType runnerType) {
    // Found next build number for this test.
    List<TestResult> older = testResultRepository.findByServiceId(service.getId(), PageRequest.of(0, 2, Sort.Direction.DESC, "testNumber"));
    if (older != null && !older.isEmpty() && older.get(0).getTestNumber() != null) {
        testResult.setTestNumber(older.get(0).getTestNumber() + 1L);
    } else {
        testResult.setTestNumber(1L);
    }
    Secret secret = null;
    if (testResult.getSecretRef() != null) {
        secret = secretRepository.findById(testResult.getSecretRef().getSecretId()).orElse(null);
        log.debug("Using a secret to test endpoint? '{}'", secret != null ? secret.getName() : "none");
    }
    // Initialize runner once as it is shared for each test.
    AbstractTestRunner<HttpMethod> testRunner = retrieveRunner(runnerType, secret, testResult.getTimeout(), service.getId());
    if (testRunner == null) {
        // Set failure and stopped flags and save before exiting.
        testResult.setSuccess(false);
        testResult.setInProgress(false);
        testResult.setElapsedTime(0);
        testResultRepository.save(testResult);
        return CompletableFuture.completedFuture(testResult);
    }
    for (TestCaseResult testCaseResult : testResult.getTestCaseResults()) {
        // Retrieve operation corresponding to testCase.
        Operation operation = service.getOperations().stream().filter(o -> o.getName().equals(testCaseResult.getOperationName())).findFirst().get();
        String testCaseId = IdBuilder.buildTestCaseId(testResult, operation);
        // Prepare collection of requests to launch.
        List<Request> requests = requestRepository.findByOperationId(IdBuilder.buildOperationId(service, operation));
        requests = cloneRequestsForTestCase(requests, testCaseId);
        List<TestReturn> results = new ArrayList<>();
        try {
            HttpMethod method = testRunner.buildMethod(operation.getMethod());
            results = testRunner.runTest(service, operation, testResult, requests, testResult.getTestedEndpoint(), method);
        } catch (URISyntaxException use) {
            log.error("URISyntaxException on endpoint {}, aborting current tests", testResult.getTestedEndpoint(), use);
            // Set flags and add to results before exiting loop.
            testCaseResult.setSuccess(false);
            testCaseResult.setElapsedTime(0);
            testResultRepository.save(testResult);
            break;
        } catch (Throwable t) {
            log.error("Throwable while testing operation {}", operation.getName(), t);
        }
        // sample request for that operation -> mark it as failed.
        if (results == null) {
            testCaseResult.setSuccess(false);
            testCaseResult.setElapsedTime(0);
            testResultRepository.save(testResult);
        } else if (!results.isEmpty()) {
            updateTestCaseResultWithReturns(testCaseResult, results, testCaseId);
            testResultRepository.save(testResult);
        }
    }
    // Update success, progress indicators and total time before saving and returning.
    updateTestResult(testResult);
    return CompletableFuture.completedFuture(testResult);
}
Also used : TestCaseResult(io.github.microcks.domain.TestCaseResult) TestReturn(io.github.microcks.domain.TestReturn) PageRequest(org.springframework.data.domain.PageRequest) Request(io.github.microcks.domain.Request) ArrayList(java.util.ArrayList) TestResult(io.github.microcks.domain.TestResult) Operation(io.github.microcks.domain.Operation) URISyntaxException(java.net.URISyntaxException) Secret(io.github.microcks.domain.Secret) HttpMethod(org.springframework.http.HttpMethod) Async(org.springframework.scheduling.annotation.Async)

Aggregations

TestReturn (io.github.microcks.domain.TestReturn)6 ArrayList (java.util.ArrayList)5 Request (io.github.microcks.domain.Request)4 Response (io.github.microcks.domain.Response)3 IOException (java.io.IOException)2 URISyntaxException (java.net.URISyntaxException)2 HashSet (java.util.HashSet)2 PageRequest (org.springframework.data.domain.PageRequest)2 HttpRequestTestStep (com.eviware.soapui.impl.support.http.HttpRequestTestStep)1 WsdlTestCase (com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase)1 WsdlTestCaseRunner (com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner)1 RestRequestStepResult (com.eviware.soapui.impl.wsdl.teststeps.RestRequestStepResult)1 WsdlTestRequestStepResult (com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStepResult)1 TestStepResult (com.eviware.soapui.model.testsuite.TestStepResult)1 StringToStringsMap (com.eviware.soapui.support.types.StringToStringsMap)1 Descriptors (com.google.protobuf.Descriptors)1 DynamicMessage (com.google.protobuf.DynamicMessage)1 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)1 JsonFormat (com.google.protobuf.util.JsonFormat)1 Header (io.github.microcks.domain.Header)1