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.util;
20  
21  import org.apache.hadoop.hbase.testclassification.SmallTests;
22  import org.junit.Test;
23  import org.junit.experimental.categories.Category;
24  
25  import static org.junit.Assert.*;
26  
27  @Category(SmallTests.class)
28  public class TestDrainBarrier {
29  
30    @Test
31    public void testBeginEndStopWork() throws Exception {
32      DrainBarrier barrier = new DrainBarrier();
33      assertTrue(barrier.beginOp());
34      assertTrue(barrier.beginOp());
35      barrier.endOp();
36      barrier.endOp();
37      barrier.stopAndDrainOps();
38      assertFalse(barrier.beginOp());
39    }
40  
41    @Test
42    public void testUnmatchedEndAssert() throws Exception {
43      DrainBarrier barrier = new DrainBarrier();
44      try {
45        barrier.endOp();
46        fail("Should have asserted");
47      } catch (AssertionError e) {
48      }
49  
50      barrier.beginOp();
51      barrier.beginOp();
52      barrier.endOp();
53      barrier.endOp();
54      try {
55        barrier.endOp();
56        fail("Should have asserted");
57      } catch (AssertionError e) {
58      }
59    }
60  
61    @Test
62    public void testStopWithoutOpsDoesntBlock() throws Exception {
63      DrainBarrier barrier = new DrainBarrier();
64      barrier.stopAndDrainOpsOnce();
65  
66      barrier = new DrainBarrier();
67      barrier.beginOp();
68      barrier.endOp();
69      barrier.stopAndDrainOpsOnce();
70    }
71  
72    @Test
73    /** This test tests blocking and can have false positives in very bad timing cases. */
74    public void testStopIsBlockedByOps() throws Exception {
75      final DrainBarrier barrier = new DrainBarrier();
76      barrier.beginOp();
77      barrier.beginOp();
78      barrier.beginOp();
79      barrier.endOp();
80  
81      Thread stoppingThread = new Thread(new Runnable() {
82        @Override
83        public void run() {
84          try {
85            barrier.stopAndDrainOpsOnce();
86          } catch (InterruptedException e) {
87            fail("Should not have happened");
88          }
89        }
90      });
91      stoppingThread.start();
92  
93      // First "end" should not unblock the thread, but the second should.
94      barrier.endOp();
95      stoppingThread.join(1000);
96      assertTrue(stoppingThread.isAlive());
97      barrier.endOp();
98      stoppingThread.join(30000); // When not broken, will be a very fast wait; set safe value.
99      assertFalse(stoppingThread.isAlive());
100   }
101 
102   @Test
103   public void testMultipleStopOnceAssert() throws Exception {
104     DrainBarrier barrier = new DrainBarrier();
105     barrier.stopAndDrainOpsOnce();
106     try {
107       barrier.stopAndDrainOpsOnce();
108       fail("Should have asserted");
109     } catch (AssertionError e) {
110     }
111   }
112 
113   @Test
114   public void testMultipleSloppyStopsHaveNoEffect() throws Exception {
115     DrainBarrier barrier = new DrainBarrier();
116     barrier.stopAndDrainOps();
117     barrier.stopAndDrainOps();
118   }
119 }