1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import java.io.IOException;
22 import java.util.Map.Entry;
23 import java.util.Properties;
24 import java.util.Set;
25
26 import org.apache.commons.cli.CommandLine;
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.conf.Configuration;
31 import org.apache.hadoop.hbase.chaos.factories.MonkeyConstants;
32 import org.apache.hadoop.hbase.chaos.factories.MonkeyFactory;
33 import org.apache.hadoop.hbase.chaos.monkies.ChaosMonkey;
34 import org.apache.hadoop.hbase.util.AbstractHBaseTool;
35 import org.junit.After;
36 import org.junit.Before;
37
38
39
40
41
42
43
44
45
46 public abstract class IntegrationTestBase extends AbstractHBaseTool {
47
48 public static final String NO_CLUSTER_CLEANUP_LONG_OPT = "noClusterCleanUp";
49 public static final String MONKEY_LONG_OPT = "monkey";
50 public static final String CHAOS_MONKEY_PROPS = "monkeyProps";
51 private static final Log LOG = LogFactory.getLog(IntegrationTestBase.class);
52
53 protected IntegrationTestingUtility util;
54 protected ChaosMonkey monkey;
55 protected String monkeyToUse;
56 protected Properties monkeyProps;
57 protected boolean noClusterCleanUp = false;
58
59 public IntegrationTestBase() {
60 this(null);
61 }
62
63 public IntegrationTestBase(String monkeyToUse) {
64 this.monkeyToUse = monkeyToUse;
65 }
66
67 @Override
68 protected void addOptions() {
69 addOptWithArg("m", MONKEY_LONG_OPT, "Which chaos monkey to run");
70 addOptNoArg("ncc", NO_CLUSTER_CLEANUP_LONG_OPT,
71 "Don't clean up the cluster at the end");
72 addOptWithArg(CHAOS_MONKEY_PROPS, "The properties file for specifying chaos "
73 + "monkey properties.");
74 }
75
76
77
78
79
80
81
82
83 protected void processBaseOptions(CommandLine cmd) {
84 if (cmd.hasOption(MONKEY_LONG_OPT)) {
85 monkeyToUse = cmd.getOptionValue(MONKEY_LONG_OPT);
86 }
87 if (cmd.hasOption(NO_CLUSTER_CLEANUP_LONG_OPT)) {
88 noClusterCleanUp = true;
89 }
90 monkeyProps = new Properties();
91
92
93
94 loadMonkeyProperties(monkeyProps, HBaseConfiguration.create());
95 if (cmd.hasOption(CHAOS_MONKEY_PROPS)) {
96 String chaosMonkeyPropsFile = cmd.getOptionValue(CHAOS_MONKEY_PROPS);
97 if (StringUtils.isNotEmpty(chaosMonkeyPropsFile)) {
98 try {
99 monkeyProps.load(this.getClass().getClassLoader()
100 .getResourceAsStream(chaosMonkeyPropsFile));
101 } catch (IOException e) {
102 LOG.warn(e);
103 System.exit(EXIT_FAILURE);
104 }
105 }
106 }
107 }
108
109
110
111
112
113 void loadMonkeyProperties(Properties props, Configuration conf) {
114 for (Entry<String,String> entry : conf) {
115 for (String prefix : MonkeyConstants.MONKEY_CONFIGURATION_KEY_PREFIXES) {
116 if (entry.getKey().startsWith(prefix)) {
117 props.put(entry.getKey(), entry.getValue());
118 break;
119 }
120 }
121 }
122 }
123
124 @Override
125 protected void processOptions(CommandLine cmd) {
126 processBaseOptions(cmd);
127 }
128
129 @Override
130 public Configuration getConf() {
131 Configuration c = super.getConf();
132 if (c == null && util != null) {
133 conf = util.getConfiguration();
134 c = conf;
135 }
136 return c;
137 }
138
139 @Override
140 protected int doWork() throws Exception {
141 ChoreService choreService = null;
142
143
144
145
146 final ScheduledChore authChore = AuthUtil.getAuthChore(conf);
147 if (authChore != null) {
148 choreService = new ChoreService("INTEGRATION_TEST");
149 choreService.scheduleChore(authChore);
150 }
151
152 setUp();
153 int result = -1;
154 try {
155 result = runTestFromCommandLine();
156 } finally {
157 cleanUp();
158 }
159
160 if (choreService != null) {
161 choreService.shutdown();
162 }
163
164 return result;
165 }
166
167 @Before
168 public void setUp() throws Exception {
169 setUpCluster();
170 setUpMonkey();
171 }
172
173 @After
174 public void cleanUp() throws Exception {
175 cleanUpMonkey();
176 cleanUpCluster();
177 }
178
179 public void setUpMonkey() throws Exception {
180 util = getTestingUtil(getConf());
181 MonkeyFactory fact = MonkeyFactory.getFactory(monkeyToUse);
182 if (fact == null) {
183 fact = getDefaultMonkeyFactory();
184 }
185 monkey = fact.setUtil(util)
186 .setTableName(getTablename())
187 .setProperties(monkeyProps)
188 .setColumnFamilies(getColumnFamilies()).build();
189 startMonkey();
190 }
191
192 protected MonkeyFactory getDefaultMonkeyFactory() {
193
194 return MonkeyFactory.getFactory(
195 util.isDistributedCluster() ? MonkeyFactory.CALM : MonkeyFactory.SLOW_DETERMINISTIC);
196 }
197
198 protected void startMonkey() throws Exception {
199 monkey.start();
200 }
201
202 public void cleanUpMonkey() throws Exception {
203 cleanUpMonkey("Ending test");
204 }
205
206 protected void cleanUpMonkey(String why) throws Exception {
207 if (monkey != null && !monkey.isStopped()) {
208 monkey.stop(why);
209 monkey.waitForStop();
210 }
211 }
212
213 protected IntegrationTestingUtility getTestingUtil(Configuration conf) {
214 if (this.util == null) {
215 if (conf == null) {
216 this.util = new IntegrationTestingUtility();
217 this.setConf(util.getConfiguration());
218 } else {
219 this.util = new IntegrationTestingUtility(conf);
220 }
221 }
222 return util;
223 }
224
225 public abstract void setUpCluster() throws Exception;
226
227 public void cleanUpCluster() throws Exception {
228 if (util.isDistributedCluster() && (monkey == null || !monkey.isDestructive())) {
229 noClusterCleanUp = true;
230 }
231 if (noClusterCleanUp) {
232 LOG.debug("noClusterCleanUp is set, skip restoring the cluster");
233 return;
234 }
235 LOG.debug("Restoring the cluster");
236 util.restoreCluster();
237 LOG.debug("Done restoring the cluster");
238 }
239
240 public abstract int runTestFromCommandLine() throws Exception;
241
242
243
244
245
246 public abstract TableName getTablename();
247
248
249
250
251
252 protected abstract Set<String> getColumnFamilies();
253 }