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.quotas; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertTrue; 022 023import java.io.IOException; 024import org.apache.hadoop.hbase.HBaseClassTestRule; 025import org.apache.hadoop.hbase.TableName; 026import org.apache.hadoop.hbase.testclassification.SmallTests; 027import org.junit.ClassRule; 028import org.junit.Test; 029import org.junit.experimental.categories.Category; 030 031import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 032import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos; 033 034@Category(SmallTests.class) 035public class TestGlobalQuotaSettingsImpl { 036 037 @ClassRule 038 public static final HBaseClassTestRule CLASS_RULE = 039 HBaseClassTestRule.forClass(TestGlobalQuotaSettingsImpl.class); 040 041 QuotaProtos.TimedQuota REQUEST_THROTTLE = QuotaProtos.TimedQuota.newBuilder() 042 .setScope(QuotaProtos.QuotaScope.MACHINE).setSoftLimit(100) 043 .setTimeUnit(HBaseProtos.TimeUnit.MINUTES).build(); 044 QuotaProtos.Throttle THROTTLE = QuotaProtos.Throttle.newBuilder() 045 .setReqNum(REQUEST_THROTTLE).build(); 046 047 QuotaProtos.SpaceQuota SPACE_QUOTA = QuotaProtos.SpaceQuota.newBuilder() 048 .setSoftLimit(1024L * 1024L).setViolationPolicy(QuotaProtos.SpaceViolationPolicy.NO_WRITES) 049 .build(); 050 051 @Test 052 public void testMergeThrottle() throws IOException { 053 QuotaProtos.Quotas quota = QuotaProtos.Quotas.newBuilder() 054 .setThrottle(THROTTLE).build(); 055 QuotaProtos.TimedQuota writeQuota = REQUEST_THROTTLE.toBuilder() 056 .setSoftLimit(500).build(); 057 // Unset the req throttle, set a write throttle 058 QuotaProtos.ThrottleRequest writeThrottle = QuotaProtos.ThrottleRequest.newBuilder() 059 .setTimedQuota(writeQuota).setType(QuotaProtos.ThrottleType.WRITE_NUMBER).build(); 060 061 GlobalQuotaSettingsImpl settings = new GlobalQuotaSettingsImpl("joe", null, null, null, quota); 062 GlobalQuotaSettingsImpl merged = settings.merge( 063 new ThrottleSettings("joe", null, null, null, writeThrottle)); 064 065 QuotaProtos.Throttle mergedThrottle = merged.getThrottleProto(); 066 // Verify the request throttle is in place 067 assertTrue(mergedThrottle.hasReqNum()); 068 QuotaProtos.TimedQuota actualReqNum = mergedThrottle.getReqNum(); 069 assertEquals(REQUEST_THROTTLE.getSoftLimit(), actualReqNum.getSoftLimit()); 070 071 // Verify the write throttle is in place 072 assertTrue(mergedThrottle.hasWriteNum()); 073 QuotaProtos.TimedQuota actualWriteNum = mergedThrottle.getWriteNum(); 074 assertEquals(writeQuota.getSoftLimit(), actualWriteNum.getSoftLimit()); 075 } 076 077 @Test 078 public void testMergeSpace() throws IOException { 079 TableName tn = TableName.valueOf("foo"); 080 QuotaProtos.Quotas quota = QuotaProtos.Quotas.newBuilder() 081 .setSpace(SPACE_QUOTA).build(); 082 083 GlobalQuotaSettingsImpl settings = new GlobalQuotaSettingsImpl(null, tn, null, null, quota); 084 // Switch the violation policy to DISABLE 085 GlobalQuotaSettingsImpl merged = settings.merge( 086 new SpaceLimitSettings(tn, SPACE_QUOTA.getSoftLimit(), SpaceViolationPolicy.DISABLE)); 087 088 QuotaProtos.SpaceQuota mergedSpaceQuota = merged.getSpaceProto(); 089 assertEquals(SPACE_QUOTA.getSoftLimit(), mergedSpaceQuota.getSoftLimit()); 090 assertEquals( 091 QuotaProtos.SpaceViolationPolicy.DISABLE, mergedSpaceQuota.getViolationPolicy()); 092 } 093 094 @Test 095 public void testMergeThrottleAndSpace() throws IOException { 096 final String ns = "org1"; 097 QuotaProtos.Quotas quota = QuotaProtos.Quotas.newBuilder() 098 .setThrottle(THROTTLE).setSpace(SPACE_QUOTA).build(); 099 GlobalQuotaSettingsImpl settings = new GlobalQuotaSettingsImpl(null, null, ns, null, quota); 100 101 QuotaProtos.TimedQuota writeQuota = REQUEST_THROTTLE.toBuilder() 102 .setSoftLimit(500).build(); 103 // Add a write throttle 104 QuotaProtos.ThrottleRequest writeThrottle = QuotaProtos.ThrottleRequest.newBuilder() 105 .setTimedQuota(writeQuota).setType(QuotaProtos.ThrottleType.WRITE_NUMBER).build(); 106 107 GlobalQuotaSettingsImpl merged = settings.merge( 108 new ThrottleSettings(null, null, ns, null, writeThrottle)); 109 GlobalQuotaSettingsImpl finalQuota = merged.merge(new SpaceLimitSettings( 110 ns, SPACE_QUOTA.getSoftLimit(), SpaceViolationPolicy.NO_WRITES_COMPACTIONS)); 111 112 // Verify both throttle quotas 113 QuotaProtos.Throttle throttle = finalQuota.getThrottleProto(); 114 assertTrue(throttle.hasReqNum()); 115 QuotaProtos.TimedQuota reqNumQuota = throttle.getReqNum(); 116 assertEquals(REQUEST_THROTTLE.getSoftLimit(), reqNumQuota.getSoftLimit()); 117 118 assertTrue(throttle.hasWriteNum()); 119 QuotaProtos.TimedQuota writeNumQuota = throttle.getWriteNum(); 120 assertEquals(writeQuota.getSoftLimit(), writeNumQuota.getSoftLimit()); 121 122 // Verify space quota 123 QuotaProtos.SpaceQuota finalSpaceQuota = finalQuota.getSpaceProto(); 124 assertEquals(SPACE_QUOTA.getSoftLimit(), finalSpaceQuota.getSoftLimit()); 125 assertEquals( 126 QuotaProtos.SpaceViolationPolicy.NO_WRITES_COMPACTIONS, 127 finalSpaceQuota.getViolationPolicy()); 128 } 129}