001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.util;
019
020import static org.apache.hadoop.hbase.util.AbstractHBaseTool.EXIT_FAILURE;
021import static org.apache.hadoop.hbase.util.AbstractHBaseTool.EXIT_SUCCESS;
022import static org.junit.Assert.assertEquals;
023import static org.junit.Assert.assertFalse;
024import static org.junit.Assert.assertNull;
025import static org.junit.Assert.assertTrue;
026
027import java.util.ArrayList;
028import java.util.List;
029import org.apache.hadoop.hbase.HBaseConfiguration;
030import org.junit.Before;
031import org.junit.Test;
032
033import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;
034import org.apache.hbase.thirdparty.org.apache.commons.cli.Option;
035
036public class AbstractHBaseToolTest {
037  static final class Options {
038    static final Option REQUIRED = new Option(null, "required", true, "");
039    static final Option OPTIONAL = new Option(null, "optional", true, "");
040    static final Option BOOLEAN = new Option(null, "boolean", false, "");
041  }
042
043  /**
044   * Simple tool to test options parsing. 3 options: required, optional, and boolean 2 deprecated
045   * options to test backward compatibility: -opt (old version of --optional) and -bool (old version
046   * of --boolean).
047   */
048  private static class TestTool extends AbstractHBaseTool {
049    String requiredValue;
050    String optionalValue;
051    boolean booleanValue;
052
053    @Override
054    protected void addOptions() {
055      addRequiredOption(Options.REQUIRED);
056      addOption(Options.OPTIONAL);
057      addOption(Options.BOOLEAN);
058    }
059
060    @Override
061    protected void processOptions(CommandLine cmd) {
062      requiredValue = cmd.getOptionValue(Options.REQUIRED.getLongOpt());
063      if (cmd.hasOption(Options.OPTIONAL.getLongOpt())) {
064        optionalValue = cmd.getOptionValue(Options.OPTIONAL.getLongOpt());
065      }
066      booleanValue = booleanValue || cmd.hasOption(Options.BOOLEAN.getLongOpt());
067    }
068
069    @Override
070    protected void processOldArgs(List<String> args) {
071      List<String> invalidArgs = new ArrayList<>();
072      while (args.size() > 0) {
073        String cmd = args.remove(0);
074        if (cmd.equals("-opt")) {
075          optionalValue = args.remove(0);
076        } else if (cmd.equals("-bool")) {
077          booleanValue = true;
078        } else {
079          invalidArgs.add(cmd);
080        }
081      }
082      args.addAll(invalidArgs);
083    }
084
085    @Override
086    protected int doWork() throws Exception {
087      return EXIT_SUCCESS;
088    }
089  }
090
091  TestTool tool;
092
093  @Before
094  public void setup() {
095    tool = new TestTool();
096    tool.setConf(HBaseConfiguration.create());
097  }
098
099  @Test
100  public void testAllOptionsSet() throws Exception {
101    String[] args = new String[] { "--required=foo", "--optional=bar", "--boolean" };
102    int returnValue = tool.run(args);
103    assertEquals(EXIT_SUCCESS, returnValue);
104    assertEquals("foo", tool.requiredValue);
105    assertEquals("bar", tool.optionalValue);
106    assertTrue(tool.booleanValue);
107  }
108
109  @Test
110  public void testOptionsNotSet() throws Exception {
111    String[] args = new String[] { "--required=foo" };
112    int returnValue = tool.run(args);
113    assertEquals(EXIT_SUCCESS, returnValue);
114    assertEquals("foo", tool.requiredValue);
115    assertNull(tool.optionalValue);
116    assertFalse(tool.booleanValue);
117  }
118
119  @Test
120  public void testMissingRequiredOption() throws Exception {
121    String[] args = new String[0];
122    int returnValue = tool.run(args);
123    assertEquals(EXIT_FAILURE, returnValue);
124  }
125
126  @Test
127  public void testFailureOnUnrecognizedOption() throws Exception {
128    String[] args = new String[] { "--required=foo", "-asdfs" };
129    int returnValue = tool.run(args);
130    assertEquals(EXIT_FAILURE, returnValue);
131  }
132
133  @Test
134  public void testOldOptionsWork() throws Exception {
135    String[] args = new String[] { "--required=foo", "-opt", "bar", "-bool" };
136    int returnValue = tool.run(args);
137    assertEquals(EXIT_SUCCESS, returnValue);
138    assertEquals("foo", tool.requiredValue);
139    assertEquals("bar", tool.optionalValue);
140    assertTrue(tool.booleanValue);
141  }
142
143  @Test
144  public void testNewOptionOverridesOldOption() throws Exception {
145    String[] args = new String[] { "--required=foo", "--optional=baz", "-opt", "bar", "-bool" };
146    int returnValue = tool.run(args);
147    assertEquals(EXIT_SUCCESS, returnValue);
148    assertEquals("foo", tool.requiredValue);
149    assertEquals("baz", tool.optionalValue);
150    assertTrue(tool.booleanValue);
151  }
152}