View Javadoc

1   /**
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
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
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.
17   */
18  
19  package org.apache.hadoop.hbase.replication.regionserver;
20  
21  import static org.junit.Assert.assertArrayEquals;
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertTrue;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.hbase.testclassification.SmallTests;
28  
29  import org.junit.Test;
30  import org.junit.experimental.categories.Category;
31  
32  @Category(SmallTests.class)
33  public class TestReplicationThrottler {
34  
35    private static final Log LOG = LogFactory.getLog(TestReplicationThrottler.class);
36  
37    /**
38     * unit test for throttling
39     */
40    @Test(timeout=10000)
41    public void testThrottling() {
42      LOG.info("testThrottling");
43  
44      // throttle bandwidth is 100 and 10 bytes/cycle respectively
45      ReplicationThrottler throttler1 = new ReplicationThrottler(100);
46      ReplicationThrottler throttler2 = new ReplicationThrottler(10);
47  
48      long ticks1 = throttler1.getNextSleepInterval(1000);
49      long ticks2 = throttler2.getNextSleepInterval(1000);
50  
51      // 1. the first push size is 1000, though 1000 bytes exceeds 100/10
52      //    bandwidthes, but no sleep since it's the first push of current
53      //    cycle, amortizing occurs when next push arrives
54      assertEquals(0, ticks1);
55      assertEquals(0, ticks2);
56  
57      throttler1.addPushSize(1000);
58      throttler2.addPushSize(1000);
59  
60      ticks1 = throttler1.getNextSleepInterval(5);
61      ticks2 = throttler2.getNextSleepInterval(5);
62  
63      // 2. when the second push(5) arrives and throttling(5) is called, the
64      //    current cyclePushSize is 1000 bytes, this should make throttler1
65      //    sleep 1000/100 = 10 cycles = 1s and make throttler2 sleep 1000/10
66      //    = 100 cycles = 10s before the second push occurs -- amortize case
67      //    after amortizing, both cycleStartTick and cyclePushSize are reset
68      //
69      // Note: in a slow machine, the sleep interval might be less than ideal ticks.
70      // If it is 75% of expected value, its is still acceptable.
71      if (ticks1 != 1000 && ticks1 != 999) {
72        assertTrue(ticks1 >= 750 && ticks1 <=1000);
73      }
74      if (ticks2 != 10000 && ticks2 != 9999) {
75        assertTrue(ticks2 >= 7500 && ticks2 <=10000);
76      }
77  
78      throttler1.resetStartTick();
79      throttler2.resetStartTick();
80  
81      throttler1.addPushSize(5);
82      throttler2.addPushSize(5);
83  
84      ticks1 = throttler1.getNextSleepInterval(45);
85      ticks2 = throttler2.getNextSleepInterval(45);
86  
87      // 3. when the third push(45) arrives and throttling(45) is called, the
88      //    current cyclePushSize is 5 bytes, 50-byte makes throttler1 no
89      //    sleep, but can make throttler2 delay to next cycle
90      // note: in real case, sleep time should cover time elapses during push
91      //       operation
92      assertTrue(ticks1 == 0);
93      if (ticks2 != 100 && ticks2 != 99) {
94        assertTrue(ticks1 >= 75 && ticks1 <=100);
95      }
96  
97      throttler2.resetStartTick();
98  
99      throttler1.addPushSize(45);
100     throttler2.addPushSize(45);
101 
102     ticks1 = throttler1.getNextSleepInterval(60);
103     ticks2 = throttler2.getNextSleepInterval(60);
104 
105     // 4. when the fourth push(60) arrives and throttling(60) is called, throttler1
106     //    delay to next cycle since 45+60 == 105; and throttler2 should firstly sleep
107     //    ceiling(45/10)= 5 cycles = 500ms to amortize previous push
108     //
109     // Note: in real case, sleep time should cover time elapses during push operation
110     if (ticks1 != 100 && ticks1 != 99) {
111       assertTrue(ticks1 >= 75 && ticks1 <=100);
112     }
113     if (ticks2 != 500 && ticks2 != 499) {
114       assertTrue(ticks1 >= 375 && ticks1 <=500);
115     }
116   }
117 }