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