View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.monitoring;
20  
21  import static org.junit.Assert.*;
22  
23  import java.util.concurrent.atomic.AtomicBoolean;
24  
25  import org.apache.hadoop.conf.Configuration;
26  import org.apache.hadoop.hbase.testclassification.SmallTests;
27  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
28  import org.junit.Test;
29  import org.junit.experimental.categories.Category;
30  
31  @Category(SmallTests.class)
32  public class TestTaskMonitor {
33  
34    @Test
35    public void testTaskMonitorBasics() {
36      TaskMonitor tm = new TaskMonitor();
37      assertTrue("Task monitor should start empty",
38          tm.getTasks().isEmpty());
39      
40      // Make a task and fetch it back out
41      MonitoredTask task = tm.createStatus("Test task");
42      MonitoredTask taskFromTm = tm.getTasks().get(0);
43      
44      // Make sure the state is reasonable.
45      assertEquals(task.getDescription(), taskFromTm.getDescription());
46      assertEquals(-1, taskFromTm.getCompletionTimestamp());
47      assertEquals(MonitoredTask.State.RUNNING, taskFromTm.getState());
48      
49      // Mark it as finished
50      task.markComplete("Finished!");
51      assertEquals(MonitoredTask.State.COMPLETE, task.getState());
52      
53      // It should still show up in the TaskMonitor list
54      assertEquals(1, tm.getTasks().size());
55      
56      // If we mark its completion time back a few minutes, it should get gced
57      task.expireNow();
58      assertEquals(0, tm.getTasks().size());
59  
60      tm.shutdown();
61    }
62    
63    @Test
64    public void testTasksGetAbortedOnLeak() throws InterruptedException {
65      final TaskMonitor tm = new TaskMonitor();
66      assertTrue("Task monitor should start empty",
67          tm.getTasks().isEmpty());
68      
69      final AtomicBoolean threadSuccess = new AtomicBoolean(false);
70      // Make a task in some other thread and leak it
71      Thread t = new Thread() {
72        @Override
73        public void run() {
74          MonitoredTask task = tm.createStatus("Test task");    
75          assertEquals(MonitoredTask.State.RUNNING, task.getState());
76          threadSuccess.set(true);
77        }
78      };
79      t.start();
80      t.join();
81      // Make sure the thread saw the correct state
82      assertTrue(threadSuccess.get());
83      
84      // Make sure the leaked reference gets cleared
85      System.gc();
86      System.gc();
87      System.gc();
88      
89      // Now it should be aborted 
90      MonitoredTask taskFromTm = tm.getTasks().get(0);
91      assertEquals(MonitoredTask.State.ABORTED, taskFromTm.getState());
92  
93      tm.shutdown();
94    }
95    
96    @Test
97    public void testTaskLimit() throws Exception {
98      TaskMonitor tm = new TaskMonitor();
99      for (int i = 0; i < TaskMonitor.DEFAULT_MAX_TASKS + 10; i++) {
100       tm.createStatus("task " + i);
101     }
102     // Make sure it was limited correctly
103     assertEquals(TaskMonitor.DEFAULT_MAX_TASKS, tm.getTasks().size());
104     // Make sure we culled the earlier tasks, not later
105     // (i.e. tasks 0 through 9 should have been deleted)
106     assertEquals("task 10", tm.getTasks().get(0).getDescription());
107 
108     tm.shutdown();
109   }
110 
111   @Test
112   public void testStatusJournal() {
113     TaskMonitor tm = new TaskMonitor();
114     MonitoredTask task = tm.createStatus("Test task");
115     assertTrue(task.getStatusJournal().isEmpty());
116     task.disableStatusJournal();
117     task.setStatus("status1");
118     // journal should be empty since it is disabled
119     assertTrue(task.getStatusJournal().isEmpty());
120     task.enableStatusJournal(true);
121     // check existing status entered in journal
122     assertEquals("status1", task.getStatusJournal().get(0).getStatus());
123     assertTrue(task.getStatusJournal().get(0).getTimeStamp() > 0);
124     task.disableStatusJournal();
125     task.setStatus("status2");
126     // check status 2 not added since disabled
127     assertEquals(1, task.getStatusJournal().size());
128     task.enableStatusJournal(false);
129     // size should still be 1 since we didn't include current status
130     assertEquals(1, task.getStatusJournal().size());
131     task.setStatus("status3");
132     assertEquals("status3", task.getStatusJournal().get(1).getStatus());
133 
134     tm.shutdown();
135   }
136 
137   @Test
138   public void testWarnStuckTasks() throws Exception {
139     final int INTERVAL = 1000;
140     Configuration conf = new Configuration();
141     conf.setLong(TaskMonitor.RPC_WARN_TIME_KEY, INTERVAL);
142     conf.setLong(TaskMonitor.MONITOR_INTERVAL_KEY, INTERVAL);
143     final TaskMonitor tm = new TaskMonitor(conf);
144     MonitoredRPCHandler t = tm.createRPCStatus("test task");
145     long then = EnvironmentEdgeManager.currentTime();
146     t.setRPC("testMethod", new Object[0], then);
147     Thread.sleep(INTERVAL * 2);
148     assertTrue("We did not warn", t.getWarnTime() > then);
149     tm.shutdown();
150   }
151 
152 }
153