--- /dev/null 2016-10-21 14:00:12.000000000 -0700 +++ new/test/lib/testlibrary/jdk/testlibrary/tasks/Task.java 2016-10-21 14:00:12.000000000 -0700 @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.testlibrary.tasks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * The supertype for tasks. + * Complex operations are modeled by building and running a "Task" object. + * Tasks are typically configured in a fluent series of calls. + */ +public interface Task { + /** + * {@code ALL-UNNAMED} + */ + public static final String ALL_UNNAMED = "ALL-UNNAMED"; + + /** The platform line separator. */ + static final String lineSeparator = System.getProperty("line.separator"); + /** + * Returns the name of the task. + * @return the name of the task + */ + String name(); + + /** + * Executes the task as currently configured. + * @return a Result object containing the results of running the task + * @throws TaskError if the outcome of the task was not as expected + */ + Result run() throws TaskError; + + /** + * Exception thrown by {@code Task.run} when the outcome is not as + * expected. + */ + public static class TaskError extends Error { + /** + * Creates a TaskError object with the given message. + * @param message the message + */ + public TaskError(String message) { + super(message); + } + } + + /** + * An enum to indicate the mode a task should use it is when executed. + */ + public enum Mode { + /** + * The task should use the interface used by the command + * line launcher for the task. + * For example, for javac: com.sun.tools.javac.Main.compile + */ + //next mode is commented out until there is a use for it + //CMDLINE, + /** + * The task should use a publicly defined API for the task. + * For example, for javac: javax.tools.JavaCompiler + */ + //next mode is commented out until there is a use for it + //API, + /** + * The task should use the standard launcher for the task. + * For example, $JAVA_HOME/bin/javac + */ + EXEC + } + + /** + * An enum to indicate the expected success or failure of executing a task. + */ + public enum Expect { + /** It is expected that the task will complete successfully. */ + SUCCESS, + /** It is expected that the task will not complete successfully. */ + FAIL + } + + /** + * An enum to identify the streams that may be written by a {@code Task}. + */ + public enum OutputKind { + /** Identifies output written to {@code System.out} or {@code stdout}. */ + STDOUT, + /** Identifies output written to {@code System.err} or {@code stderr}. */ + STDERR + /** Identifies output written to a stream provided directly to the task. */ + //next output kind is commented out until there is a use for it + //,DIRECT + }; + + /** + * The results from running a {@link Task}. + * The results contain the exit code returned when the tool was invoked, + * and a map containing the output written to any streams during the + * execution of the tool. + * All tools support "stdout" and "stderr". + * Tools that take an explicit PrintWriter save output written to that + * stream as "main". + */ + public static class Result { + final Task task; + final int exitCode; + final Map outputMap; + final List command; + + Result(Task task, int exitCode, Map outputMap, + List command) { + this.task = task; + this.exitCode = exitCode; + this.outputMap = outputMap; + this.command = command; + } + + Result(Task task, int exitCode, Map outputMap) { + this(task, exitCode, outputMap, Collections.EMPTY_LIST); + } + + /** + * Returns the exit code. + * @return the exit code. + */ + public int getExitCode() { + return exitCode; + } + + /** + * Returns the exit code. + * @return the exit code. + */ + public List getCommand() { + return command; + } + + /** + * Returns the content of a specified stream. + * @param outputKind the kind of the selected stream + * @return the content that was written to that stream when the tool + * was executed. + */ + public String getOutput(OutputKind outputKind) { + return outputMap.get(outputKind); + } + + /** + * Returns the content of named streams as a list of lines. + * @param outputKinds the kinds of the selected streams + * @return the content that was written to the given streams when the tool + * was executed. + */ + public List getOutputLines(OutputKind... outputKinds) { + List result = new ArrayList<>(); + for (OutputKind outputKind : outputKinds) { + result.addAll(Arrays.asList(outputMap.get(outputKind).split(lineSeparator))); + } + return result; + } + + /** + * Writes the content of the specified stream to the log. + * @param kind the kind of the selected stream + * @return this Result object + */ + public Result write(OutputKind kind) { + String text = getOutput(kind); + if (text == null || text.isEmpty()) + System.out.println("[" + task.name() + ":" + kind + "]: empty"); + else { + System.out.println("[" + task.name() + ":" + kind + "]:"); + System.out.print(text); + } + return this; + } + + /** + * Writes the content of all streams with any content to the log. + * @return this Result object + */ + public Result writeAll() { + outputMap.forEach((name, text) -> { + if (!text.isEmpty()) { + System.out.println("[" + name + "]:"); + System.out.print(text); + } + }); + return this; + } + + /** + * Verify that the specified output contains the string + * + * @param kind the output kind + * @param expectedString String that buffer should contain + * @throws RuntimeException If the string was not found + */ + public void shouldContain(OutputKind kind, String expectedString) { + if (!getOutput(kind).contains(expectedString)) + throw new RuntimeException("'" + expectedString + + "' missing from " + kind.name()); + } + + /** + * Verify that either stdout or stderr contains the string + * + * @param expectedString String that buffer should contain + * @throws RuntimeException If the string was not found + */ + public void shouldContain(String expectedString) { + for (OutputKind kind : OutputKind.values()) { + if (getOutput(kind).contains(expectedString)) + return; + } + throw new RuntimeException("'" + expectedString + + "' missing from output"); + } + } +} +