/* * $Id$ * * Copyright (c) 2001, 2009, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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 com.sun.javatest; import java.io.*; import java.nio.charset.StandardCharsets; import java.util.Iterator; import com.sun.javatest.util.I18NResourceBundle; import com.sun.javatest.util.Properties; import com.sun.javatest.util.StringArray; /** * An implementation of Parameters, using data read from a .jtp file. */ public class FileParameters extends BasicParameters implements Parameters.LegacyEnvParameters { /** * Determine if the specified file is a parameter file, * as determined by whether its extension is .jtp or not. * @param file the file to be checked * @return true if the specified file is a parameter file, * and false otherwise */ public static boolean isParameterFile(File file) { return file.getPath().endsWith(PARAMFILE_EXTN); } /** * Create an empty FileParameters object. */ public FileParameters() { } /** * Create a FileParameters object, based on data read from a parameter file. * @param file the file to be read to initialize this object * @throws FileNotFoundException if the file does not exist * @throws IOException if there is a problem reading the file */ public FileParameters(File file) throws FileNotFoundException, IOException { Properties p = new Properties(); Reader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); p.load(in); in.close(); setTestSuite(adjustPath(p.getProperty("javasoft.sqe.javatest.selection.testSuite"))); setWorkDirectory(p.getProperty("javasoft.sqe.javatest.results.workDir")); setTests(p.getProperty("javasoft.sqe.javatest.selection.tests")); setExcludeFiles(p.getProperty("javasoft.sqe.javatest.selection.excludeList")); String keywordOp = p.getProperty("javasoft.sqe.javatest.selection.keywordOp"); String keywords = p.getProperty("javasoft.sqe.javatest.selection.keywords"); setKeywords(keywordOp, keywords); String statusOp = p.getProperty("javasoft.sqe.javatest.selection.status"); String[] statusTests = new String[Status.NUM_STATES]; statusTests[Status.PASSED] = p.getProperty("javasoft.sqe.javatest.selection.prev.passed"); statusTests[Status.FAILED] = p.getProperty("javasoft.sqe.javatest.selection.prev.failed"); statusTests[Status.ERROR] = p.getProperty("javasoft.sqe.javatest.selection.prev.error"); statusTests[Status.NOT_RUN] = p.getProperty("javasoft.sqe.javatest.selection.prev.notRun"); setPriorStatusValues(statusOp, statusTests); setEnvFiles(p.getProperty("javasoft.sqe.javatest.execution.envFiles")); setEnvName(p.getProperty("javasoft.sqe.javatest.execution.environment")); setConcurrency(p.getProperty("javasoft.sqe.javatest.execution.concurrency")); setTimeoutFactor(p.getProperty("javasoft.sqe.javatest.execution.timeFactor")); setReportDir(p.getProperty("javasoft.sqe.javatest.results.reportDir")); } /** * Create a FileParameters object, based on command-line-like args. * The args that are accepted are: *
*
-t testsuite
-testsuite testsuite *
Specify the test suite *
-keywords expr *
Specify a keyword expression, used to filter the tests to be run. *
-status status-list *
Specify the status values used to select tests at runtime. * status-list should be a comma-separated list of words from * the following list: * passed, * failed, * error, * notRun *
-exclude exclude-list-file *
Specify an exclude-list file containing a list of tests to * be excluded from the test run. * The option can be specified more than once, with different files. *
-envFile environment-file *
Specify an environment file, containing environment entries * providing details on how to run tests. * The option can be specified more than once, with different files. *
-env environment-name *
Specify the name of the environment to be used from the * set of environment files. *
-concurrency number *
Specify how many tests JT Harness may run at once. The default * is 1. *
-timeoutFactor number *
Specify a scale factor to be used to multiply the timeout * value for each test, to allow for running on slow CPUs. *
-report report-dir
-r report-dir *
Specify a directory in which to write reports at the end of the test run. *
-workDir work-dir
-w work-dir *
Specify a directory in which to write the results of the individual tests. *
initial-files *
Trailing file arguments are treated as initial files, used to select * which parts of the test suite should be run. *
* The test suite, work directory and report directory are evaluated * relative to the user's current directory, unless the location specified * is an absolute path. The exclude list and environment files are located * relative to the test suite location, unless they are absolute paths. * @param args The args used to initialize the FileParameters object. * @throws IllegalArgumentException If an unrecognized argument is found. */ public FileParameters(String[] args) { String testSuiteArg = null; String workDirArg = null; String testsArgs = null; String exclFilesArgs = null; String keywordsExprArg = null; String priorStatusValuesArg = null; String envFilesArgs = null; String envNameArg = null; String concurrencyArg = null; String timeoutFactorArg = null; String reportDirArg = null; for (int i = 0; i < args.length; i++) { if ("-testSuite".equalsIgnoreCase(args[i]) || "-t".equalsIgnoreCase(args[i])) testSuiteArg = args[++i]; else if ("-keywords".equalsIgnoreCase(args[i])) keywordsExprArg = args[++i]; else if ("-status".equalsIgnoreCase(args[i])) priorStatusValuesArg = args[++i].toLowerCase(); else if ("-exclude".equalsIgnoreCase(args[i])) { if (exclFilesArgs == null) exclFilesArgs = args[++i]; else exclFilesArgs += " " + args[++i]; } else if ("-envFile".equalsIgnoreCase(args[i])) { if (envFilesArgs == null) envFilesArgs = args[++i]; else envFilesArgs += " " + args[++i]; } else if ("-env".equalsIgnoreCase(args[i])) envNameArg = args[++i]; else if ("-concurrency".equalsIgnoreCase(args[i])) concurrencyArg = args[++i]; else if ("-timeoutFactor".equalsIgnoreCase(args[i])) timeoutFactorArg = args[++i]; else if ("-report".equalsIgnoreCase(args[i]) || "-r".equalsIgnoreCase(args[i])) reportDirArg = args[++i]; else if ("-workDir".equalsIgnoreCase(args[i]) || "-w".equalsIgnoreCase(args[i])) workDirArg = args[++i]; else if (args[i].startsWith("-")) throw new IllegalArgumentException(args[i]); else { String[] tests = new String[args.length - i]; System.arraycopy(args, i, tests, 0, tests.length); testsArgs = StringArray.join(tests); i = args.length; } } setTestSuite(adjustPath(testSuiteArg)); setWorkDirectory(adjustPath(workDirArg)); setTests(testsArgs); setExcludeFiles(exclFilesArgs); setKeywords("expr", keywordsExprArg); setPriorStatusValues(priorStatusValuesArg); setEnvFiles(envFilesArgs); setEnvName(envNameArg); setConcurrency(concurrencyArg); setTimeoutFactor(timeoutFactorArg); setReportDir(adjustPath(reportDirArg)); } //--------------------------------------------------------------------- public Parameters.EnvParameters getEnvParameters() { return this; } public File[] getEnvFiles() { return envFiles; } public File[] getAbsoluteEnvFiles() { updateAbsoluteEnvFiles(); return cachedAbsEnvFiles; } public void setEnvFiles(File[] files) { envFiles = files; } private void setEnvFiles(String files) { String[] f = StringArray.split(files); File[] ff = new File[f.length]; // legacy behavior requires that paths be relative to the testSuite // location specified in the JTE or on the cmd line for (int i = 0; i < ff.length; i++) { ff[i] = new File(makeLegacyTsRelative(f[i])); } setEnvFiles(ff); } public String getEnvName() { return envName; } public void setEnvName(String name) { envName = name; } /** * Get an object containing the environments read from the environment files. * @return an object containing all the environments read from the environment files. * @see #setEnvFiles * @see #setEnvName */ public TestEnvContext getEnvTable() { updateEnvTable(); return cachedEnvTable; } public TestEnvironment getEnv() { updateEnv(); return cachedEnv; } private void updateAbsoluteEnvFiles() { TestSuite ts = getTestSuite(); File base = (ts == null ? null : ts.getRootDir()); if (cachedAbsEnvFiles == null || cachedAbsEnvFiles_base != base || cachedAbsEnvFiles_envFiles != envFiles) { cachedAbsEnvFiles = getAbsoluteFiles(base, envFiles); } } private void updateEnvTable() { updateAbsoluteEnvFiles(); File[] absEnvFiles = cachedAbsEnvFiles; if (cachedEnvTable == null || !equal(absEnvFiles, cachedEnvTable_absEnvFiles)) { try { cachedEnvTable = new TestEnvContext(absEnvFiles); cachedEnvTable_absEnvFiles = absEnvFiles; envTableError = null; } catch (TestEnvContext.Fault e) { cachedEnvTable = null; envTableError = e.getMessage(); } } } private void updateEnv() { TestEnvContext envTable = getEnvTable(); if (envTable == null) { cachedEnv = null; envError = i18n.getString("fp.noEnvs", envName); return; } TestEnvironment env; try { if (envName == null) envName = ""; env = envTable.getEnv(envName); if (env == null) { // note envName==null is always a valid environment cachedEnv = null; envError = i18n.getString("fp.envNotFound", envName); return; } for (Iterator i = env.elements().iterator(); i.hasNext(); ) { TestEnvironment.Element entry = i.next(); if (entry.value.indexOf("VALUE_NOT_DEFINED") >= 0) { String eText = ( (entry.definedInEnv == null ? "" : "env." + entry.definedInEnv + ".") + entry.key + "=" + entry.value); cachedEnv = null; envError = i18n.getString("fp.undefinedEntry", new Object[] {eText, entry.definedInFile}); return; } } } catch (TestEnvironment.Fault e) { cachedEnv = null; envError = i18n.getString("fp.badEnv", new Object[] {envName, e.getMessage()}); return; } cachedEnv = env; envError = null; } private boolean isEnvOK() { updateEnv(); return (envTableError == null && envError == null); } private File[] envFiles; private File[] cachedAbsEnvFiles; private File cachedAbsEnvFiles_base; private File[] cachedAbsEnvFiles_envFiles; private String envName; private TestEnvContext cachedEnvTable; private File[] cachedEnvTable_absEnvFiles; private String envTableError; private TestEnvironment cachedEnv; private TestEnvContext cachedEnv_envTable; private String cachedEnv_envName; private String envError; //--------------------------------------------------------------------- public boolean isValid() { return ( super.isValid() && isEnvOK() ); } public String getErrorMessage() { String basicError = super.getErrorMessage(); return (basicError != null ? basicError : envTableError != null ? envTableError : null); } //--------------------------------------------------------------------- private void setTestSuite(String path) { legacyTsPath = path; File p = (path == null ? null : new File(path)); // we assume that the path has already be made non-relative // i.e. absolute if (p != null && p.isFile()) legacyTsPath = p.getParent(); // this strange arrangement of checks is here because we // are trying to ensure that users playing around with legacy // configurations get reasonable results if (p == null || TestSuite.isTestSuite(p)) { setTestSuite(p); } else { File parent = p.getParentFile(); // fallback check, check parent of specified location if (parent != null && TestSuite.isTestSuite(parent)) { setTestSuite(parent); } else { // must do this to ensure proper errors occur setTestSuite(p); } } } //--------------------------------------------------------------------- private void setWorkDirectory(String path) { setWorkDirectory(path == null ? null : new File(path)); } //--------------------------------------------------------------------- private void setTests(String tests) { setTests(StringArray.split(tests)); } //--------------------------------------------------------------------- private void setExcludeFiles(String files) { String[] f = StringArray.split(files); File[] ff = new File[f.length]; // legacy behavior requires that paths be relative to the testSuite // location specified in the JTE or on the cmd line for (int i = 0; i < ff.length; i++) { ff[i] = new File(makeLegacyTsRelative(f[i])); } setExcludeFiles(ff); } //--------------------------------------------------------------------- private void setKeywords(String op, String value) { if (op == null || op.equals("ignore") ) setKeywordsMode(NO_KEYWORDS); else if (op.equals("expr")) setKeywords(EXPR, value); else if (op.equals("allOf")) setKeywords(ALL_OF, value); else if (op.equals("anyOf")) setKeywords(ANY_OF, value); else setKeywordsMode(NO_KEYWORDS); } //--------------------------------------------------------------------- private void setPriorStatusValues(String op, String[] values) { if (op == null || !op.equals("allOf")) setPriorStatusValues((boolean[]) null); else { boolean[] b = new boolean[Status.NUM_STATES]; for (int i = 0; i < values.length; i++) b[i] = "true".equals(values[i]); setPriorStatusValues(b); } } private void setPriorStatusValues(String values) { if (values == null || values.length() == 0) setPriorStatusValues((boolean[]) null); else { boolean[] b = new boolean[Status.NUM_STATES]; b[Status.PASSED] = (values.indexOf("pass") != -1); b[Status.FAILED] = (values.indexOf("fail") != -1); b[Status.ERROR] = (values.indexOf("erro") != -1); b[Status.NOT_RUN] = (values.indexOf("notr") != -1); setPriorStatusValues(b); } } //--------------------------------------------------------------------- private void setConcurrency(String conc) { if (conc == null) setConcurrency(1); else { try { setConcurrency(Integer.parseInt(conc)); } catch (NumberFormatException e) { concurrencyError = i18n.getString("fp.badConcurrency", conc); } } } //--------------------------------------------------------------------- private void setTimeoutFactor(String tf) { if (tf == null) setTimeoutFactor(1); else { try { setTimeoutFactor(Float.parseFloat(tf)); } catch (NumberFormatException e) { timeoutFactorError = i18n.getString("fp.badTimeoutFactor", tf); } } } //--------------------------------------------------------------------- /** * Get the report directory given in the parameters. * @return the report directory * @see #setReportDir */ public File getReportDir() { return reportDir; } /** * Set the report directory. * @param dir the report directory * @see #getReportDir */ public void setReportDir(File dir) { // check report dir exists? reportDir = dir; } private void setReportDir(String dir) { if (dir == null) setReportDir((File) (null)); else setReportDir(new File(dir)); } private File reportDir; //--------------------------------------------------------------------- /** * Makes the given path relative to the user's CWD if it is a * relative value. So "tests" may be turned into * /home/me/mytck/tests. */ private String adjustPath(String path) { if (path == null) return path; File p = new File(path); if (p.isAbsolute()) return path; else { String userDir = System.getProperty("user.dir"); if (userDir == null) return path; else return userDir + File.separator + path; } } private String makeLegacyTsRelative(String path) { if (path == null) return path; File p = new File(path); if (p.isAbsolute()) return path; else { if (legacyTsPath == null) return path; else return legacyTsPath + File.separator + path; } } private String legacyTsPath; // always a directory private static final String PARAMFILE_EXTN = ".jtp"; private static final I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(FileParameters.class); }