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