/* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * */ /** * @test * @bug 6545058 6611182 8016209 8139986 8162746 * @summary Validate and test -?, -h and --help flags. All tools should take * the same flags to display the help message. * @compile HelpCheck.java * @run main HelpCheck */ import java.io.File; import java.io.FileFilter; import java.util.Map; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.HashSet; import java.util.Set; public class HelpCheck extends TestHelper { // Tools that do not accept -?. static final String[] BLACKLIST_QOPTION = { "appletviewer", // deprecated, don't test "idlj", // none, prints help message anyways. "jabswitch", // /?, prints help message anyways, win only "jaccessinspector", // gui, don't test, win only "jaccesswalker", // gui, don't test, win only "jaotc", // --help //"jar", // -?, -h, --help //"jarsigner", // -?, -h, --help, -help accepted but not documented. //"java", // -?, -h, --help //"javac", // -?, --help, -h is already taken for "native header output directory". //"javadoc", // -?, -h, --help //"javah", // -?, -h, --help //"javap", // -?, -h, --help, -help accepted but not documented. //"javaw", // -?, -h, --help, win only //"jcmd", // -?, -h, --help, -help accepted but not documented. "jconsole", // gui, don't test //"jdb", // -?, -h, --help, -help accepted but not documented. //"jdeprscan", // -?, -h, --help "jdeps", // none, prints help message anyways. "jhsdb", // none, prints help message anyways. "jimage", // -h, --help //"jinfo", // -?, -h, --help, -help accepted but not documented. "jjs", // -h, --help, return code 100 "jlink", // -h, --help "jmap", // none, prints help message anyways. "jmod", // -h, --help //"jps", // -?, -h, --help, -help accepted but not documented. //"jrunscript", // -?, -help, Displays help message if no arguments are given or if -h, --help. //"jshell", // -?, -h, --help "jstack", // -h, prints help message anyways. //"jstat", // -?, -h, --help, -help accepted but not documented. "jstatd", // All work, none documented, return code 1. "keytool", // none, prints help message anyways. "kinit", // none, interactive, asks for password, don't test, win only "klist", // none, prints help message anyways, win only "ktab", // none, prints help message anyways, win only "orbd", // Throws exceptions on all three flags //"pack200", // -? -h --help, return code '1' "policytool", // none, prints help message anyways. "rmic", // none, prints help message anyways. "rmid", // none, prints help message anyways. "rmiregistry", // none, prints help message anyways. "schemagen", // -help, prints help message anyways. "serialver", // none, prints help message anyways. "servertool", // none. Shell, don't test. "tnameserv", // Throws exceptions on all three flags //"unpack200", // -? -h --help, return code '1' "wsgen", // -help, prints help message anyways. "wsimport", // -help, exception on other flags "xjc", // -help, prints help message anyways. }; // Tools that do not accept -h. static final String[] BLACKLIST_HOPTION = { "appletviewer", // deprecated, don't test "idlj", // none, prints help message anyways. "jabswitch", // win: /?, prints help message anyways. "jaccessinspector", // win: gui, don't test "jaccesswalker", // win: gui, don't test "jaotc", // --help //"jar", // -h, --help //"jarsigner", // -h, --help, not in help message -- fixed //"java", // -?, -h, --help "javac", // --help, -h is already taken for "native header output directory". -- fixed -? "javadoc", // --help //"javah", // -?, -h, --help //"javap", // -?, --help -- fixed //"javaw", // win: -?, -h, --help //"jcmd", // -h, but exits with return code "jconsole", // gui, don't test //"jdb", // -help -- fixed: all //"jdeprscan", // -h, --help, return code 1 //"jdeps", // none, prints help message anyways. "jhsdb", // Strange ... //"jimage", // -h, --help //"jinfo", // Displays help message if no arguments are given or wrong ones. Documents -h. -- fixed. //"jjs", // -h, return code 100 //"jlink", // -h, --help "jmap", // none, prints help message anyways. //"jmod", // -h, --help //"jps", // -?, not documented -- fixed "jrunscript", // -?, -help, Displays help message if no arguments are given or if -h, --help. //"jshell", // -h, --help, -h not documented. -- fixed //"jstack", // -h, prints help message anyways. //"jstat", // All work, -help documented -- fixed "jstatd", // All work, none documented, return code 1. "keytool", // none, prints help message anyways. "kinit", // win: none, interactive, asks for password, don't test "klist", // win: none, prints help message anyways. "ktab", // win: none, prints help message anyways. "orbd", // Throws exceptions on all three flags //"pack200", // -? -h --help documented, but return code '1' "policytool", // none, prints help message anyways. "rmic", // none, prints help message anyways. "rmid", // none, prints help message anyways. "rmiregistry", // none, prints help message anyways. "schemagen", // -help, prints help message anyways. "serialver", // none, prints help message anyways. "servertool", // none. Shell, don't test. "tnameserv", // Throws exceptions on all three flags //"unpack200", // -? -h --help documented, but return code '1' "wsgen", // -help, prints help message anyways. "wsimport", // -help, exception on other flags "xjc", // -help, prints help message anyways. }; // Tools that do not accept --help. static final String[] BLACKLIST_HELPOPTION = { "appletviewer", // deprecated, don't test "idlj", // none, prints help message anyways. "jabswitch", // win: /?, prints help message anyways. "jaccessinspector", // win: gui, don't test "jaccesswalker", // win: gui, don't test //"jaotc", // --help //"jar", // -h, --help //"jarsigner", // -h, --help, not in help message -- fixed //"java", // -?, -h, --help //"javac", // --help, -h is already taken for "native header output directory". -- fixed -? //"javadoc", // --help //"javah", // -?, -h, --help //"javap", // -?, --help -- fixed //"javaw", // win: -?, -h, --help //"jcmd", // -h, but exits with return code -- fixed "jconsole", // gui, don't test //"jdb", // -help -- fixed: all //"jdeprscan", // -h, --help, return code 1 "jdeps", // none, prints help message anyways. "jhsdb", // Strange ... //"jimage", // -h, --help //"jinfo", // Displays help message if no arguments are given or wrong ones. Documents -h. -- fixed. //"jjs", // -h, return code 100 -- fixed --help //"jlink", // -h, --help "jmap", // none, prints help message anyways. //"jmod", // -h, --help "jps", // -?, not documented -- fixed "jrunscript", // -?, -help, Displays help message if no arguments are given or if -h, --help. //"jshell", // -h, --help, -h not documented. -- fixed "jstack", // -h, prints help message anyways. //"jstat", // All work, -help documented -- fixed "jstatd", // All work, none documented, return code 1. "keytool", // none, prints help message anyways. "kinit", // win: none, interactive, asks for password, don't test "klist", // win: none, prints help message anyways. "ktab", // win: none, prints help message anyways. "orbd", // Throws exceptions on all three flags //"pack200", // -? -h --help documented, but return code '1' "policytool", // none, prints help message anyways. "rmic", // none, prints help message anyways. "rmid", // none, prints help message anyways. "rmiregistry", // none, prints help message anyways. "schemagen", // -help, prints help message anyways. "serialver", // none, prints help message anyways. "servertool", // none. Shell, don't test. "tnameserv", // Throws exceptions on all three flags //"unpack200", // -? -h --help documented, but return code '1' "wsgen", // -help, prints help message anyways. "wsimport", // -help, exception on other flags "xjc", // -help, prints help message anyways. }; // Tools that exit with a return code != 0 after accepting the // flag and printing the help message. static final String[] ERROR_CODE_ACCEPTABLE = { "appletviewer", // deprecated, don't test //"idlj", // none, prints help message anyways. //"jabswitch", // win: /?, prints help message anyways. //"jaccessinspector", // win: gui, don't test //"jaccesswalker", // win: gui, don't test //"jaotc", // --help //"jar", // -h, --help //"jarsigner", // -h, --help, not in help message -- fixed //"java", // -?, -h, --help //"javac", // --help //"javadoc", // --help //"javah", // -?, -h, --help //"javap", // -?, --help //"javaw", // win: -?, -h, --help //"jcmd", // -h, but exits with return code //"jconsole", // gui, don't test "jdb", // -help "jdeprscan", // -h, --help, return code 1 -- fixed //"jdeps", // none, prints help message anyways. //"jhsdb", // Strange ... //"jimage", // -h, --help //"jinfo", // Displays help message if no arguments are given or wrong ones. Documents -h. "jjs", // -h, return code 100 //"jlink", // -h, --help //"jmap", // none, prints help message anyways. //"jmod", // -h, --help //"jps", // -?, not documented -- fixed //"jrunscript", // -?, -help, Displays help message if no arguments are given or if -h, --help. //"jshell", // -h, --help, -h not documented. -- fixed //"jstack", // -h with return code 0. //"jstat", // All work, -help documented -- fixed "jstatd", // All work, none documented, return code 1. //"keytool", // none, prints help message anyways. //"kinit", // win: none, interactive, asks for password, don't test //"klist", // win: none, prints help message anyways. //"ktab", // win: none, prints help message anyways. //"orbd", // Throws exceptions on all three flags "pack200", // -? -h --help documented, but return code '1' //"policytool", // none, prints help message anyways. //"rmic", // none, prints help message anyways. //"rmid", // none, prints help message anyways. //"rmiregistry", // none, prints help message anyways. //"schemagen", // -help, prints help message anyways. //"serialver", // none, prints help message anyways. //"servertool", // none. Shell, don't test. //"tnameserv", // Throws exceptions on all three flags "unpack200", // -? -h --help documented, but return code '1' //"wsgen", // -help, prints help message anyways. //"wsimport", // -help, exception on other flags //"xjc", // -help, prints help message anyways. }; // Returns true if tool is listed in ERROR_CODE_ACCEPTABLE. static boolean errorCodeAcceptable(String tool) { for (String x : ERROR_CODE_ACCEPTABLE) { if (tool.toLowerCase().startsWith(x)) return true; } return false; } /* * Checks if the tools accept the option and that the * exit code is zero. * The output of the tools run with is verified to * contain the flag string, i.e. it's checked that the help flag * itself is documented. */ static String testHelpOption(String flag, String[] blacklist) { System.out.println("=== test " + flag + " option === "); Set failed = new HashSet<>(); Set helpTextFailed = new HashSet<>(); for (File f : new File(JAVA_BIN).listFiles(new ToolFilter(blacklist))) { String x = f.getAbsolutePath(); TestResult tr = doExec(x, flag); System.out.println("Testing " + f.getName()); System.out.println("#> " + x + " " + flag); tr.testOutput.forEach(System.out::println); System.out.println("#> echo $?"); System.out.println(tr.exitValue); if (!tr.isOK() && !errorCodeAcceptable(f.getName())) { System.out.println("failed"); failed.add(f.getName()); } boolean foundFlag = false; for (String y : tr.testOutput) { // Some tools say 'Unknown option "-?"'. Skip that. foundFlag |= (y.contains(flag) && !y.contains("nknown")); } if (!foundFlag) { helpTextFailed.add(f.getName()); } } if (failed.isEmpty() && helpTextFailed.isEmpty()) { System.out.println("testing flag '" + flag + "' passed"); return ""; } else { System.out.println("testing flag '" + flag + "' failed"); String res = ""; if (!failed.isEmpty()) { res = "\nHelp flag '" + flag + "' not accepted by: " + failed + "."; } if (!helpTextFailed.isEmpty()) { res += "\nHelp flag '" + flag + "' not documented for: " + helpTextFailed + "."; } return res; } } public static void main(String[] args) { String errorMessage = ""; errorMessage += testHelpOption("-?", BLACKLIST_QOPTION); errorMessage += testHelpOption("-h", BLACKLIST_HOPTION); errorMessage += testHelpOption("--help", BLACKLIST_HELPOPTION); if (errorMessage.isEmpty()) { System.out.println("All help string tests: PASS"); } else { throw new AssertionError("HelpCheck failed: " + errorMessage); } } static class ToolFilter implements FileFilter { final Iterable exclude; protected ToolFilter(String... exclude) { List tlist = new ArrayList<>(); this.exclude = tlist; for (String x : exclude) { String str = x + ((isWindows) ? EXE_FILE_EXT : ""); tlist.add(str.toLowerCase()); } } @Override public boolean accept(File pathname) { if (!pathname.isFile() || !pathname.canExecute()) { return false; } String name = pathname.getName().toLowerCase(); if (isWindows && !name.endsWith(EXE_FILE_EXT)) { return false; } for (String x : exclude) { if (name.endsWith(x)) { return false; } } return true; } } }