2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
;
20 import static org
.junit
.Assert
.assertEquals
;
21 import static org
.junit
.Assert
.assertFalse
;
22 import static org
.junit
.Assert
.assertTrue
;
25 import java
.io
.FileOutputStream
;
26 import java
.io
.IOException
;
27 import java
.io
.PrintWriter
;
28 import org
.apache
.hadoop
.conf
.Configuration
;
29 import org
.apache
.hadoop
.fs
.FileSystem
;
30 import org
.apache
.hadoop
.fs
.Path
;
31 import org
.apache
.hadoop
.hbase
.HealthChecker
.HealthCheckerExitStatus
;
32 import org
.apache
.hadoop
.hbase
.testclassification
.MiscTests
;
33 import org
.apache
.hadoop
.hbase
.testclassification
.SmallTests
;
34 import org
.apache
.hadoop
.util
.Shell
;
35 import org
.junit
.After
;
36 import org
.junit
.ClassRule
;
37 import org
.junit
.Test
;
38 import org
.junit
.experimental
.categories
.Category
;
39 import org
.slf4j
.Logger
;
40 import org
.slf4j
.LoggerFactory
;
42 @Category({MiscTests
.class, SmallTests
.class})
43 public class TestNodeHealthCheckChore
{
46 public static final HBaseClassTestRule CLASS_RULE
=
47 HBaseClassTestRule
.forClass(TestNodeHealthCheckChore
.class);
49 private static final Logger LOG
= LoggerFactory
.getLogger(TestNodeHealthCheckChore
.class);
50 private static final HBaseTestingUtil UTIL
= new HBaseTestingUtil();
51 private static final int SCRIPT_TIMEOUT
= 5000;
52 private File healthScriptFile
;
53 private String eol
= System
.getProperty("line.separator");
56 public void cleanUp() throws IOException
{
57 // delete and recreate the test directory, ensuring a clean test dir between tests
58 Path testDir
= UTIL
.getDataTestDir();
59 FileSystem fs
= UTIL
.getTestFileSystem();
60 fs
.delete(testDir
, true);
61 if (!fs
.mkdirs(testDir
)) throw new IOException("Failed mkdir " + testDir
);
65 public void testHealthCheckerSuccess() throws Exception
{
66 String normalScript
= "echo \"I am all fine\"";
67 healthCheckerTest(normalScript
, HealthCheckerExitStatus
.SUCCESS
);
71 public void testHealthCheckerFail() throws Exception
{
72 String errorScript
= "echo ERROR" + eol
+ "echo \"Node not healthy\"";
73 healthCheckerTest(errorScript
, HealthCheckerExitStatus
.FAILED
);
77 public void testHealthCheckerTimeout() throws Exception
{
78 String timeOutScript
= "sleep 10" + eol
+ "echo \"I am fine\"";
79 healthCheckerTest(timeOutScript
, HealthCheckerExitStatus
.TIMED_OUT
);
82 public void healthCheckerTest(String script
, HealthCheckerExitStatus expectedStatus
)
84 Configuration config
= getConfForNodeHealthScript();
85 config
.addResource(healthScriptFile
.getName());
86 String location
= healthScriptFile
.getAbsolutePath();
87 long timeout
= config
.getLong(HConstants
.HEALTH_SCRIPT_TIMEOUT
, SCRIPT_TIMEOUT
);
89 HealthChecker checker
= new HealthChecker();
90 checker
.init(location
, timeout
);
92 createScript(script
, true);
93 HealthReport report
= checker
.checkHealth();
94 assertEquals(expectedStatus
, report
.getStatus());
96 LOG
.info("Health Status:" + report
.getHealthReport());
98 this.healthScriptFile
.delete();
102 public void testRSHealthChore() throws Exception
{
103 Stoppable stop
= new StoppableImplementation();
104 Configuration conf
= getConfForNodeHealthScript();
105 String errorScript
= "echo ERROR" + eol
+ " echo \"Server not healthy\"";
106 createScript(errorScript
, true);
107 HealthCheckChore rsChore
= new HealthCheckChore(100, stop
, conf
);
109 //Default threshold is three.
112 assertFalse("Stoppable must not be stopped.", stop
.isStopped());
114 assertTrue("Stoppable must have been stopped.", stop
.isStopped());
116 stop
.stop("Finished w/ test");
120 private void createScript(String scriptStr
, boolean setExecutable
)
122 if (!this.healthScriptFile
.exists()) {
123 if (!healthScriptFile
.createNewFile()) {
124 throw new IOException("Failed create of " + this.healthScriptFile
);
127 PrintWriter pw
= new PrintWriter(new FileOutputStream(healthScriptFile
));
129 pw
.println(scriptStr
);
134 healthScriptFile
.setExecutable(setExecutable
);
135 LOG
.info("Created " + this.healthScriptFile
+ ", executable=" + setExecutable
);
138 private Configuration
getConfForNodeHealthScript() throws IOException
{
139 Configuration conf
= UTIL
.getConfiguration();
140 File tempDir
= new File(UTIL
.getDataTestDir().toString());
141 if (!tempDir
.exists()) {
142 if (!tempDir
.mkdirs()) {
143 throw new IOException("Failed mkdirs " + tempDir
);
146 String scriptName
= "HealthScript" + UTIL
.getRandomUUID().toString()
147 + (Shell
.WINDOWS ?
".cmd" : ".sh");
148 healthScriptFile
= new File(tempDir
.getAbsolutePath(), scriptName
);
149 conf
.set(HConstants
.HEALTH_SCRIPT_LOC
, healthScriptFile
.getAbsolutePath());
150 conf
.setLong(HConstants
.HEALTH_FAILURE_THRESHOLD
, 3);
151 conf
.setLong(HConstants
.HEALTH_SCRIPT_TIMEOUT
, SCRIPT_TIMEOUT
);
156 * Simple helper class that just keeps track of whether or not its stopped.
158 private static class StoppableImplementation
implements Stoppable
{
159 private volatile boolean stop
= false;
162 public void stop(String why
) {
167 public boolean isStopped() {