| /* |
| * Copyright 2015-2016 IBM Corporation |
| * |
| * Licensed 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 common; |
| |
| import static org.junit.Assert.assertTrue; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.FileReader; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.text.SimpleDateFormat; |
| import java.util.Collections; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| |
| import org.junit.rules.TestWatcher; |
| import org.junit.runner.Description; |
| |
| import com.google.gson.JsonArray; |
| import com.google.gson.JsonElement; |
| import com.google.gson.JsonObject; |
| import com.google.gson.JsonParser; |
| |
| import junit.runner.Version; |
| |
| /** |
| * Miscellaneous utilities used in whisk test suite |
| */ |
| public class TestUtils { |
| protected static final Logger logger = Logger.getLogger("basic"); |
| |
| public static final int SUCCESS_EXIT = 0; |
| public static final int ERROR_EXIT = 1; |
| public static final int MISUSE_EXIT = 2; |
| public static final int DONTCARE_EXIT = -1; // any value is ok |
| public static final int ANY_ERROR_EXIT = -2; // any non-zero value is ok |
| |
| public static final int ACCEPTED = 202; // 202 |
| public static final int BAD_REQUEST = 144; // 400 - 256 = 144 |
| public static final int UNAUTHORIZED = 145; // 401 - 256 = 145 |
| public static final int FORBIDDEN = 147; // 403 - 256 = 147 |
| public static final int NOT_FOUND = 148; // 404 - 256 = 148 |
| public static final int NOT_ALLOWED = 149; // 405 - 256 = 149 |
| public static final int CONFLICT = 153; // 409 - 256 = 153 |
| public static final int TOO_LARGE = 157; // 413 - 256 = 157 |
| public static final int THROTTLED = 173; // 429 (TOO_MANY_REQUESTS) - 256 = 173 |
| public static final int TIMEOUT = 246; // 502 (GATEWAY_TIMEOUT) - 256 = 246 |
| |
| private static final File catalogDir = WhiskProperties.getFileRelativeToWhiskHome("catalog"); |
| private static final File testActionsDir = WhiskProperties.getFileRelativeToWhiskHome("tests/dat/actions"); |
| private static final File testApiGwDir = WhiskProperties.getFileRelativeToWhiskHome("tests/dat/apigw"); |
| private static final File vcapFile = WhiskProperties.getVCAPServicesFile(); |
| private static final String envServices = System.getenv("VCAP_SERVICES"); |
| private static final String loggerLevel = System.getProperty("LOG_LEVEL", Level.WARNING.toString()); |
| |
| static { |
| logger.setLevel(Level.parse(loggerLevel.trim())); |
| System.out.println("JUnit version is: " + Version.id()); |
| } |
| |
| /** |
| * Gets path to file relative to catalog directory. |
| * |
| * (@)deprecated this method will be removed in future version; use {@link #getTestActionFilename()} instead |
| * @param name relative filename |
| */ |
| public static String getCatalogFilename(String name) { |
| return new File(catalogDir, name).toString(); |
| } |
| |
| /** |
| * Gets path to test action file relative to test catalog directory. |
| * |
| * @param name the filename of the test action |
| * @return |
| */ |
| public static String getTestActionFilename(String name) { return new File(testActionsDir, name).toString(); } |
| |
| /** |
| * Gets path to test apigw file relative to test catalog directory. |
| * |
| * @param name the filename of the test action |
| * @return |
| */ |
| public static String getTestApiGwFilename(String name) { return new File(testApiGwDir, name).toString(); } |
| |
| /** |
| * Gets the value of VCAP_SERVICES. |
| * |
| * @return VCAP_SERVICES as a JSON object |
| */ |
| public static JsonObject getVCAPServices() { |
| try { |
| if (envServices != null) { |
| return new JsonParser().parse(envServices).getAsJsonObject(); |
| } else { |
| return new JsonParser().parse(new FileReader(vcapFile)).getAsJsonObject(); |
| } |
| } catch (Throwable t) { |
| System.out.println("failed to parse VCAP" + t); |
| return new JsonObject(); |
| } |
| } |
| |
| /** |
| * Gets a VCAP_SERVICES credentials. |
| * |
| * @return VCAP credentials as a <String, String> map for each <property, |
| * value> pair in credentials |
| */ |
| public static Map<String, String> getVCAPcredentials(String vcapService) { |
| try { |
| JsonObject credentials = getCredentials(vcapService); |
| Map<String, String> map = new HashMap<String, String>(); |
| for (Map.Entry<String, JsonElement> entry : credentials.entrySet()) { |
| map.put(entry.getKey(), credentials.get(entry.getKey()).getAsString()); |
| } |
| |
| return map; |
| } catch (Throwable t) { |
| System.out.println("failed to parse VCAP" + t); |
| return Collections.emptyMap(); |
| } |
| } |
| |
| /** |
| * Gets a VCAP_SERVICES credentials as the json objects. |
| * |
| * @return VCAP credentials as a json object. |
| */ |
| public static JsonObject getCredentials(String vcapService) { |
| JsonArray vcapArray = getVCAPServices().get(vcapService).getAsJsonArray(); |
| JsonObject vcapObject = vcapArray.get(0).getAsJsonObject(); |
| JsonObject credentials = vcapObject.get("credentials").getAsJsonObject(); |
| return credentials; |
| } |
| |
| /** |
| * Creates a JUnit test watcher. Use with @rule. |
| * @return a junit {@link TestWatcher} that prints a message when each test starts and ends |
| */ |
| public static TestWatcher makeTestWatcher() { |
| return new TestWatcher() { |
| protected void starting(Description description) { |
| System.out.format("\nStarting test %s at %s\n", description.getMethodName(), getDateTime()); |
| } |
| |
| protected void finished(Description description) { |
| System.out.format("Finished test %s at %s\n\n", description.getMethodName(), getDateTime()); |
| } |
| }; |
| } |
| |
| /** |
| * @return a formatted string representing the date and time |
| */ |
| public static String getDateTime() { |
| Date date = new Date(); |
| SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); |
| return sdf.format(date); |
| } |
| |
| /** |
| * @return a formatted string representing the time of day |
| */ |
| public static String getTime() { |
| Date date = new Date(); |
| SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); |
| return sdf.format(date); |
| } |
| |
| /** |
| * Encapsulates the result of running a native command, providing: |
| * exitCode the exit code of the process |
| * stdout the messages printed to standard out |
| * stderr the messages printed to standard error |
| */ |
| public static class RunResult { |
| public final int exitCode; |
| public final String stdout; |
| public final String stderr; |
| |
| private RunResult(int exitCode, String stdout, String stderr) { |
| this.exitCode = exitCode; |
| this.stdout = stdout; |
| this.stderr = stderr; |
| } |
| |
| public Pair<String, String> logs() { |
| return Pair.make(stdout, stderr); |
| } |
| |
| public void validateExitCode(int expectedExitCode) { |
| if (expectedExitCode == TestUtils.DONTCARE_EXIT) |
| return; |
| boolean ok = (exitCode == expectedExitCode) || (expectedExitCode == TestUtils.ANY_ERROR_EXIT && exitCode != 0); |
| if (!ok) { |
| System.out.format("expected exit code = %d\n%s", expectedExitCode, toString()); |
| assertTrue("Exit code:" + exitCode, exitCode == expectedExitCode); |
| } |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder fmt = new StringBuilder(); |
| fmt.append(String.format("exit code = %d\n", exitCode)); |
| fmt.append(String.format("stdout: %s\n", stdout)); |
| fmt.append(String.format("stderr: %s\n", stderr)); |
| return fmt.toString(); |
| } |
| } |
| |
| /** |
| * Runs a command in another process. |
| * |
| * @param expectedExitCode the expected exit code for the process |
| * @param dir the working directory the command runs with |
| * @param params the parameters (including executable) to run |
| * @return RunResult instance |
| * @throws IOException |
| */ |
| public static RunResult runCmd(int expectedExitCode, File dir, String... params) throws IOException { |
| return runCmd(expectedExitCode, dir, logger, null, params); |
| } |
| |
| /** |
| * Runs a command in another process. |
| * |
| * @param expectedExitCode the exit code expected from the command when it exists |
| * @param dir the working directory the command runs with |
| * @param logger the object to manage logging message |
| * @param env an environment map |
| * @param params the parameters (including executable) to run |
| * @return RunResult instance |
| * @throws IOException |
| */ |
| public static RunResult runCmd(int expectedExitCode, File dir, Logger logger, Map<String, String> env, String... params) throws IOException { |
| ProcessBuilder pb = new ProcessBuilder(params); |
| pb.directory(dir); |
| if (env != null) { |
| pb.environment().putAll(env); |
| } |
| Process p = pb.start(); |
| |
| String stdout = inputStreamToString(p.getInputStream()); |
| String stderr = inputStreamToString(p.getErrorStream()); |
| |
| try { |
| p.waitFor(); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| RunResult rr = new RunResult(p.exitValue(), stdout, stderr); |
| if (logger != null) { |
| logger.info("RunResult: " + rr); |
| } |
| rr.validateExitCode(expectedExitCode); |
| return rr; |
| } |
| |
| private static String inputStreamToString(InputStream in) throws IOException { |
| BufferedReader reader = new BufferedReader(new InputStreamReader(in)); |
| StringBuilder builder = new StringBuilder(); |
| String line = null; |
| while ((line = reader.readLine()) != null) { |
| builder.append(line); |
| builder.append(System.getProperty("line.separator")); |
| } |
| return builder.toString(); |
| } |
| } |