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