001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.replication.regionserver; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertTrue; 022 023import org.apache.hadoop.hbase.testclassification.ReplicationTests; 024import org.apache.hadoop.hbase.testclassification.SmallTests; 025import org.junit.jupiter.api.Tag; 026import org.junit.jupiter.api.Test; 027import org.slf4j.Logger; 028import org.slf4j.LoggerFactory; 029 030@Tag(ReplicationTests.TAG) 031@Tag(SmallTests.TAG) 032public class TestReplicationThrottler { 033 034 private static final Logger LOG = LoggerFactory.getLogger(TestReplicationThrottler.class); 035 036 /** 037 * unit test for throttling 038 */ 039 @Test 040 public void testThrottling() { 041 LOG.info("testThrottling"); 042 043 // throttle bandwidth is 100 and 10 bytes/cycle respectively 044 ReplicationThrottler throttler1 = new ReplicationThrottler(100); 045 ReplicationThrottler throttler2 = new ReplicationThrottler(10); 046 047 long ticks1 = throttler1.getNextSleepInterval(1000); 048 long ticks2 = throttler2.getNextSleepInterval(1000); 049 050 // 1. the first push size is 1000, though 1000 bytes exceeds 100/10 051 // bandwidthes, but no sleep since it's the first push of current 052 // cycle, amortizing occurs when next push arrives 053 assertEquals(0, ticks1); 054 assertEquals(0, ticks2); 055 056 throttler1.addPushSize(1000); 057 throttler2.addPushSize(1000); 058 059 ticks1 = throttler1.getNextSleepInterval(5); 060 ticks2 = throttler2.getNextSleepInterval(5); 061 062 // 2. when the second push(5) arrives and throttling(5) is called, the 063 // current cyclePushSize is 1000 bytes, this should make throttler1 064 // sleep 1000/100 = 10 cycles = 1s and make throttler2 sleep 1000/10 065 // = 100 cycles = 10s before the second push occurs -- amortize case 066 // after amortizing, both cycleStartTick and cyclePushSize are reset 067 // 068 // Note: in a slow machine, the sleep interval might be less than ideal ticks. 069 // If it is 75% of expected value, its is still acceptable. 070 if (ticks1 != 1000 && ticks1 != 999) { 071 assertTrue(ticks1 >= 750 && ticks1 <= 1000); 072 } 073 if (ticks2 != 10000 && ticks2 != 9999) { 074 assertTrue(ticks2 >= 7500 && ticks2 <= 10000); 075 } 076 077 throttler1.resetStartTick(); 078 throttler2.resetStartTick(); 079 080 throttler1.addPushSize(5); 081 throttler2.addPushSize(5); 082 083 ticks1 = throttler1.getNextSleepInterval(45); 084 ticks2 = throttler2.getNextSleepInterval(45); 085 086 // 3. when the third push(45) arrives and throttling(45) is called, the 087 // current cyclePushSize is 5 bytes, 50-byte makes throttler1 no 088 // sleep, but can make throttler2 delay to next cycle 089 // note: in real case, sleep time should cover time elapses during push 090 // operation 091 assertTrue(ticks1 == 0); 092 if (ticks2 != 100 && ticks2 != 99) { 093 assertTrue(ticks1 >= 75 && ticks1 <= 100); 094 } 095 096 throttler2.resetStartTick(); 097 098 throttler1.addPushSize(45); 099 throttler2.addPushSize(45); 100 101 ticks1 = throttler1.getNextSleepInterval(60); 102 ticks2 = throttler2.getNextSleepInterval(60); 103 104 // 4. when the fourth push(60) arrives and throttling(60) is called, throttler1 105 // delay to next cycle since 45+60 == 105; and throttler2 should firstly sleep 106 // ceiling(45/10)= 5 cycles = 500ms to amortize previous push 107 // 108 // Note: in real case, sleep time should cover time elapses during push operation 109 if (ticks1 != 100 && ticks1 != 99) { 110 assertTrue(ticks1 >= 75 && ticks1 <= 100); 111 } 112 if (ticks2 != 500 && ticks2 != 499) { 113 assertTrue(ticks1 >= 375 && ticks1 <= 500); 114 } 115 } 116}