@VisibleForTesting
  boolean parseArguments(String[] args) throws IOException {
    Options opts = new Options();
    opts.addOption(Option.builder("h").build());
    opts.addOption(Option.builder("help").build());
    opts.addOption(Option.builder("input")
        .desc("Input class path. Defaults to the default classpath.")
        .hasArg().build());
    opts.addOption(Option.builder("whitelist")
        .desc(
            "Regex specifying the full path of jars to include in the" +
                " framework tarball. Default is a hardcoded set of jars" +
                " considered necessary to include")
        .hasArg().build());
    opts.addOption(Option.builder("blacklist")
        .desc(
            "Regex specifying the full path of jars to exclude in the" +
                " framework tarball. Default is a hardcoded set of jars" +
                " considered unnecessary to include")
        .hasArg().build());
    opts.addOption(Option.builder("fs")
        .desc(
            "Target file system to upload to." +
            " Example: hdfs://foo.com:8020")
        .hasArg().build());
    opts.addOption(Option.builder("target")
        .desc(
            "Target file to upload to with a reference name." +
                " Example: /usr/mr-framework.tar.gz#mr-framework")
        .hasArg().build());
    opts.addOption(Option.builder("initialReplication")
        .desc(
            "Desired initial replication count. Default 3.")
        .hasArg().build());
    opts.addOption(Option.builder("finalReplication")
        .desc(
            "Desired final replication count. Default 10.")
        .hasArg().build());
    opts.addOption(Option.builder("acceptableReplication")
        .desc(
            "Desired acceptable replication count. Default 9.")
        .hasArg().build());
    opts.addOption(Option.builder("timeout")
        .desc(
            "Desired timeout for the acceptable" +
                " replication in seconds. Default 10")
        .hasArg().build());
    opts.addOption(Option.builder("nosymlink")
        .desc("Ignore symlinks into the same directory")
        .build());
    GenericOptionsParser parser = new GenericOptionsParser(opts, args);
    if (parser.getCommandLine().hasOption("help") ||
        parser.getCommandLine().hasOption("h")) {
      printHelp(opts);
      return false;
    }
    input = parser.getCommandLine().getOptionValue(
        "input", System.getProperty("java.class.path"));
    whitelist = parser.getCommandLine().getOptionValue(
        "whitelist", DefaultJars.DEFAULT_MR_JARS);
    blacklist = parser.getCommandLine().getOptionValue(
        "blacklist", DefaultJars.DEFAULT_EXCLUDED_MR_JARS);
    initialReplication =
        Short.parseShort(parser.getCommandLine().getOptionValue(
            "initialReplication", "3"));
    finalReplication =
        Short.parseShort(parser.getCommandLine().getOptionValue(
            "finalReplication", "10"));
    acceptableReplication =
        Short.parseShort(
            parser.getCommandLine().getOptionValue(
                "acceptableReplication", "9"));
    timeout =
        Integer.parseInt(
            parser.getCommandLine().getOptionValue("timeout", "10"));
    if (parser.getCommandLine().hasOption("nosymlink")) {
      ignoreSymlink = true;
    }
    String fs = parser.getCommandLine()
        .getOptionValue("fs", null);
    String path = parser.getCommandLine().getOptionValue("target",
        "/usr/lib/mr-framework.tar.gz#mr-framework");
    boolean isFullPath =
        path.startsWith("hdfs://") ||
        path.startsWith("file://");

    if (fs == null) {
      fs = conf.getTrimmed(FS_DEFAULT_NAME_KEY);
      if (fs == null && !isFullPath) {
        LOG.error("No filesystem specified in either fs or target.");
        printHelp(opts);
        return false;
      } else {
        LOG.info(String.format(
            "Target file system not specified. Using default %s", fs));
      }
    }
    if (path.isEmpty()) {
      LOG.error("Target directory not specified");
      printHelp(opts);
      return false;
    }
    StringBuilder absolutePath = new StringBuilder();
    if (!isFullPath) {
      absolutePath.append(fs);
      absolutePath.append(path.startsWith("/") ? "" : "/");
    }
    absolutePath.append(path);
    target = absolutePath.toString();

    if (parser.getRemainingArgs().length > 0) {
      LOG.warn("Unexpected parameters");
      printHelp(opts);
      return false;
    }
    return true;
  }
@Test
  void testHelp() throws IOException {
    String[] args = new String[]{"-help"};
    FrameworkUploader uploader = new FrameworkUploader();
    boolean success = uploader.parseArguments(args);
    assertFalse(success, "Expected to print help");
    assertThat(uploader.input)
        .withFailMessage("Expected ignore run")
        .isNull();
    assertThat(uploader.whitelist)
        .withFailMessage("Expected ignore run")
        .isNull();
    assertThat(uploader.target)
        .withFailMessage("Expected ignore run")
        .isNull();
  }