1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertTrue;
23
24 import java.io.File;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.PrintWriter;
28 import java.util.UUID;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.fs.FileSystem;
34 import org.apache.hadoop.fs.Path;
35 import org.apache.hadoop.hbase.HealthChecker.HealthCheckerExitStatus;
36 import org.apache.hadoop.hbase.testclassification.SmallTests;
37 import org.apache.hadoop.util.Shell;
38 import org.junit.After;
39 import org.junit.Test;
40 import org.junit.experimental.categories.Category;
41
42 @Category(SmallTests.class)
43 public class TestNodeHealthCheckChore {
44
45 private static final Log LOG = LogFactory.getLog(TestNodeHealthCheckChore.class);
46 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
47 private static final int SCRIPT_TIMEOUT = 5000;
48 private File healthScriptFile;
49 private String eol = System.getProperty("line.separator");
50
51 @After
52 public void cleanUp() throws IOException {
53
54 Path testDir = UTIL.getDataTestDir();
55 FileSystem fs = UTIL.getTestFileSystem();
56 fs.delete(testDir, true);
57 if (!fs.mkdirs(testDir)) throw new IOException("Failed mkdir " + testDir);
58 }
59
60 @Test(timeout=60000)
61 public void testHealthCheckerSuccess() throws Exception {
62 String normalScript = "echo \"I am all fine\"";
63 healthCheckerTest(normalScript, HealthCheckerExitStatus.SUCCESS);
64 }
65
66 @Test(timeout=60000)
67 public void testHealthCheckerFail() throws Exception {
68 String errorScript = "echo ERROR" + eol + "echo \"Node not healthy\"";
69 healthCheckerTest(errorScript, HealthCheckerExitStatus.FAILED);
70 }
71
72 @Test(timeout=60000)
73 public void testHealthCheckerTimeout() throws Exception {
74 String timeOutScript = "sleep 10" + eol + "echo \"I am fine\"";
75 healthCheckerTest(timeOutScript, HealthCheckerExitStatus.TIMED_OUT);
76 }
77
78 public void healthCheckerTest(String script, HealthCheckerExitStatus expectedStatus)
79 throws Exception {
80 Configuration config = getConfForNodeHealthScript();
81 config.addResource(healthScriptFile.getName());
82 String location = healthScriptFile.getAbsolutePath();
83 long timeout = config.getLong(HConstants.HEALTH_SCRIPT_TIMEOUT, SCRIPT_TIMEOUT);
84
85 HealthChecker checker = new HealthChecker();
86 checker.init(location, timeout);
87
88 createScript(script, true);
89 HealthReport report = checker.checkHealth();
90 assertEquals(expectedStatus, report.getStatus());
91
92 LOG.info("Health Status:" + report.getHealthReport());
93
94 this.healthScriptFile.delete();
95 }
96
97 @Test(timeout=60000)
98 public void testRSHealthChore() throws Exception{
99 Stoppable stop = new StoppableImplementation();
100 Configuration conf = getConfForNodeHealthScript();
101 String errorScript = "echo ERROR" + eol + " echo \"Server not healthy\"";
102 createScript(errorScript, true);
103 HealthCheckChore rsChore = new HealthCheckChore(100, stop, conf);
104 try {
105
106 rsChore.chore();
107 rsChore.chore();
108 assertFalse("Stoppable must not be stopped.", stop.isStopped());
109 rsChore.chore();
110 assertTrue("Stoppable must have been stopped.", stop.isStopped());
111 } finally {
112 stop.stop("Finished w/ test");
113 }
114 }
115
116 private void createScript(String scriptStr, boolean setExecutable)
117 throws Exception {
118 if (!this.healthScriptFile.exists()) {
119 if (!healthScriptFile.createNewFile()) {
120 throw new IOException("Failed create of " + this.healthScriptFile);
121 }
122 }
123 PrintWriter pw = new PrintWriter(new FileOutputStream(healthScriptFile));
124 try {
125 pw.println(scriptStr);
126 pw.flush();
127 } finally {
128 pw.close();
129 }
130 healthScriptFile.setExecutable(setExecutable);
131 LOG.info("Created " + this.healthScriptFile + ", executable=" + setExecutable);
132 }
133
134 private Configuration getConfForNodeHealthScript() throws IOException {
135 Configuration conf = UTIL.getConfiguration();
136 File tempDir = new File(UTIL.getDataTestDir().toString());
137 if (!tempDir.exists()) {
138 if (!tempDir.mkdirs()) {
139 throw new IOException("Failed mkdirs " + tempDir);
140 }
141 }
142 String scriptName = "HealthScript" + UUID.randomUUID().toString()
143 + (Shell.WINDOWS ? ".cmd" : ".sh");
144 healthScriptFile = new File(tempDir.getAbsolutePath(), scriptName);
145 conf.set(HConstants.HEALTH_SCRIPT_LOC, healthScriptFile.getAbsolutePath());
146 conf.setLong(HConstants.HEALTH_FAILURE_THRESHOLD, 3);
147 conf.setLong(HConstants.HEALTH_SCRIPT_TIMEOUT, SCRIPT_TIMEOUT);
148 return conf;
149 }
150
151
152
153
154 private static class StoppableImplementation implements Stoppable {
155 private volatile boolean stop = false;
156
157 @Override
158 public void stop(String why) {
159 this.stop = true;
160 }
161
162 @Override
163 public boolean isStopped() {
164 return this.stop;
165 }
166
167 }
168 }