diff --git a/hbase-it/src/test/java/org/apache/hadoop/hbase/chaos/utils/ChaosMonkeyRunner.java b/hbase-it/src/test/java/org/apache/hadoop/hbase/chaos/utils/ChaosMonkeyRunner.java new file mode 100644 index 0000000..3256cb8 --- /dev/null +++ b/hbase-it/src/test/java/org/apache/hadoop/hbase/chaos/utils/ChaosMonkeyRunner.java @@ -0,0 +1,127 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.chaos.utils; + +import java.util.Set; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.IntegrationTestBase; +import org.apache.hadoop.hbase.IntegrationTestingUtility; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.util.ToolRunner; + +import com.google.common.collect.Sets; + +public class ChaosMonkeyRunner extends IntegrationTestBase { + private static final Log LOG = LogFactory.getLog(ChaosMonkeyRunner.class); + + /** option to specify how much time to run the chaos monkeys */ + public static final String RUN_TIME_LONG_OPT = "monkeyRunTime"; + public static final String TABLE_NAME_OPT = "tableName"; + public static final String FAMILY_NAME_OPT = "familyName"; + + protected int NUM_SLAVES_BASE = 3; // number of slaves when running test with mini cluster + + private long monkeysRunTime = 1800000L;// 30 min + private String tableName = "ChaosMonkeyRunner.tableName"; + private String familyName = "ChaosMonkeyRunner.familyName"; + + @Override + public void addOptions() { + super.addOptions(); + addOptWithArg("t", RUN_TIME_LONG_OPT, + "How much milliseconds to run the chaos monkey, 1800000 by default"); + addOptWithArg(TABLE_NAME_OPT, "Table name in the test to run chaos monkey against"); + addOptWithArg(FAMILY_NAME_OPT, "Family name in the test to run chaos monkey against"); + } + + @Override + protected void processBaseOptions(CommandLine cmd) { + super.processBaseOptions(cmd); + if (cmd.hasOption(RUN_TIME_LONG_OPT)) { + String runTimeValue = cmd.getOptionValue(RUN_TIME_LONG_OPT); + try { + this.monkeysRunTime = Long.parseLong(runTimeValue); + } catch (NumberFormatException e) { + String errorMessage = + "Passed by value [" + runTimeValue + "] for option [" + RUN_TIME_LONG_OPT + + "] is not a valid long"; + throw new IllegalArgumentException(errorMessage, e); + } + } + if (cmd.hasOption(TABLE_NAME_OPT)) { + this.tableName = cmd.getOptionValue(TABLE_NAME_OPT); + } + if (cmd.hasOption(FAMILY_NAME_OPT)) { + this.familyName = cmd.getOptionValue(FAMILY_NAME_OPT); + } + } + + @Override + public void setUpCluster() throws Exception { + util = getTestingUtil(getConf()); + boolean isDistributed = util.isDistributedCluster(); + util.initializeCluster(isDistributed ? 1 : this.NUM_SLAVES_BASE); + if (!isDistributed) { + util.startMiniMapReduceCluster(); + } + this.setConf(util.getConfiguration()); + } + + /** + * Monkey thread is started in {@link IntegrationTestBase#setUpMonkey()}, so we do nothing in the + * main thread here but just sleep + */ + @Override + public int runTestFromCommandLine() throws Exception { + long startTime = System.currentTimeMillis(); + try { + Thread.sleep(monkeysRunTime); + } catch (InterruptedException e) { + if (monkeysRunTime != Long.MAX_VALUE) { + long actualRunTime = System.currentTimeMillis() - startTime; + LOG.error("Monkeys thread interrupted, expected to run " + monkeysRunTime + + " ms but actually run " + actualRunTime + " ms"); + return -1; + } + } + return 0; + } + + @Override + public TableName getTablename() { + return TableName.valueOf(tableName); + } + + @Override + protected Set getColumnFamilies() { + return Sets.newHashSet(familyName); + } + + public static void main(String[] args) throws Exception { + Configuration conf = HBaseConfiguration.create(); + IntegrationTestingUtility.setUseDistributedCluster(conf); + int ret = ToolRunner.run(conf, new ChaosMonkeyRunner(), args); + System.exit(ret); + } + +}