private void forkTest()

in src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined/JUnitLauncherTask.java [254:363]


    private void forkTest(final TestDefinition test, final ForkDefinition forkDefinition,
                          final ForkedRepresentation forkedRepresentation,
                          final Optional<Long> deadlineNanos) {
        // create launch command
        final CommandlineJava commandlineJava = forkDefinition.generateCommandLine(this);
        if (this.classPath != null) {
            commandlineJava.createClasspath(getProject()).createPath().append(this.classPath);
        }
        final java.nio.file.Path projectPropsPath;
        try {
            projectPropsPath = dumpProjectProperties();
        } catch (IOException e) {
            throw new BuildException("Could not create the necessary properties file while forking a process" +
                    " for a test", e);
        }
        // --properties <path-to-properties-file>
        commandlineJava.createArgument().setValue(Constants.ARG_PROPERTIES);
        commandlineJava.createArgument().setValue(projectPropsPath.toAbsolutePath().toString());

        final java.nio.file.Path launchDefXmlPath = newLaunchDefinitionXml();
        try (final OutputStream os = Files.newOutputStream(launchDefXmlPath)) {
            final XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(os, "UTF-8");
            try {
                writer.writeStartDocument();
                writer.writeStartElement(LD_XML_ELM_LAUNCH_DEF);
                if (this.printSummary) {
                    writer.writeAttribute(LD_XML_ATTR_PRINT_SUMMARY, "true");
                }
                if (this.haltOnFailure) {
                    writer.writeAttribute(LD_XML_ATTR_HALT_ON_FAILURE, "true");
                }
                if (this.includeTags.size() > 0) {
                    writer.writeAttribute(LD_XML_ATTR_INCLUDE_TAGS, commaSeparatedListElements(includeTags));
                }
                if (this.excludeTags.size() > 0) {
                    writer.writeAttribute(LD_XML_ATTR_EXCLUDE_TAGS, commaSeparatedListElements(excludeTags));
                }
                // task level listeners
                for (final ListenerDefinition listenerDef : this.listeners) {
                    if (!listenerDef.shouldUse(getProject())) {
                        continue;
                    }
                    // construct the listener definition argument
                    listenerDef.toForkedRepresentation(writer);
                }
                // test definition as XML
                forkedRepresentation.write(this, writer);
                writer.writeEndElement();
                writer.writeEndDocument();
            } finally {
                writer.close();
            }
        } catch (Exception e) {
            throw new BuildException("Failed to construct command line for test", e);
        }
        // --launch-definition <xml-file-path>
        commandlineJava.createArgument().setValue(Constants.ARG_LAUNCH_DEFINITION);
        commandlineJava.createArgument().setValue(launchDefXmlPath.toAbsolutePath().toString());

        // launch the process and wait for process to complete
        final int exitCode = executeForkedTest(forkDefinition, commandlineJava, deadlineNanos);
        switch (exitCode) {
            case Constants.FORK_EXIT_CODE_SUCCESS: {
                // success
                break;
            }
            case Constants.FORK_EXIT_CODE_EXCEPTION: {
                // process failed with some exception
                throw new BuildException("Forked test(s) failed with an exception");
            }
            case Constants.FORK_EXIT_CODE_TESTS_FAILED: {
                // test has failure(s)
                try {
                    if (test.getFailureProperty() != null) {
                        // if there are test failures and the test is configured to set a property in case
                        // of failure, then set the property to true
                        this.getProject().setNewProperty(test.getFailureProperty(), "true");
                    }
                } finally {
                    if (test.isHaltOnFailure()) {
                        // if the test is configured to halt on test failures, throw a build error
                        final String errorMessage;
                        if (test instanceof NamedTest) {
                            errorMessage = "Test " + ((NamedTest) test).getName() + " has failure(s)";
                        } else {
                            errorMessage = "Some test(s) have failure(s)";
                        }
                        throw new BuildException(errorMessage);
                    }
                }
                break;
            }
            case Constants.FORK_EXIT_CODE_TIMED_OUT: {
                // test has failure(s)
                try {
                    if (test.getFailureProperty() != null) {
                        // if there are test failures and the test is configured to set a property in case
                        // of failure, then set the property to true
                        this.getProject().setNewProperty(test.getFailureProperty(), "true");
                    }
                } finally {
                    if (test.isHaltOnFailure()) {
                        throw new BuildException(new TimeoutException("Forked test(s) timed out"));
                    } else {
                        log("Timeout occurred. Please note the time in the report does not reflect the time until the timeout.");
                    }
                }
            }
        }
    }