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 = 042 QuotaProtos.TimedQuota.newBuilder().setScope(QuotaProtos.QuotaScope.MACHINE).setSoftLimit(100) 043 .setTimeUnit(HBaseProtos.TimeUnit.MINUTES).build(); 044 QuotaProtos.Throttle THROTTLE = 045 QuotaProtos.Throttle.newBuilder().setReqNum(REQUEST_THROTTLE).build(); 046 047 QuotaProtos.SpaceQuota SPACE_QUOTA = 048 QuotaProtos.SpaceQuota.newBuilder().setSoftLimit(1024L * 1024L) 049 .setViolationPolicy(QuotaProtos.SpaceViolationPolicy.NO_WRITES).build(); 050 051 @Test 052 public void testMergeThrottle() throws IOException { 053 QuotaProtos.Quotas quota = QuotaProtos.Quotas.newBuilder().setThrottle(THROTTLE).build(); 054 QuotaProtos.TimedQuota writeQuota = REQUEST_THROTTLE.toBuilder().setSoftLimit(500).build(); 055 // Unset the req throttle, set a write throttle 056 QuotaProtos.ThrottleRequest writeThrottle = QuotaProtos.ThrottleRequest.newBuilder() 057 .setTimedQuota(writeQuota).setType(QuotaProtos.ThrottleType.WRITE_NUMBER).build(); 058 059 GlobalQuotaSettingsImpl settings = new GlobalQuotaSettingsImpl("joe", null, null, null, quota); 060 GlobalQuotaSettingsImpl merged = 061 settings.merge(new ThrottleSettings("joe", null, null, null, writeThrottle)); 062 063 QuotaProtos.Throttle mergedThrottle = merged.getThrottleProto(); 064 // Verify the request throttle is in place 065 assertTrue(mergedThrottle.hasReqNum()); 066 QuotaProtos.TimedQuota actualReqNum = mergedThrottle.getReqNum(); 067 assertEquals(REQUEST_THROTTLE.getSoftLimit(), actualReqNum.getSoftLimit()); 068 069 // Verify the write throttle is in place 070 assertTrue(mergedThrottle.hasWriteNum()); 071 QuotaProtos.TimedQuota actualWriteNum = mergedThrottle.getWriteNum(); 072 assertEquals(writeQuota.getSoftLimit(), actualWriteNum.getSoftLimit()); 073 } 074 075 @Test 076 public void testMergeSpace() throws IOException { 077 TableName tn = TableName.valueOf("foo"); 078 QuotaProtos.Quotas quota = QuotaProtos.Quotas.newBuilder().setSpace(SPACE_QUOTA).build(); 079 080 GlobalQuotaSettingsImpl settings = new GlobalQuotaSettingsImpl(null, tn, null, null, quota); 081 // Switch the violation policy to DISABLE 082 GlobalQuotaSettingsImpl merged = settings 083 .merge(new SpaceLimitSettings(tn, SPACE_QUOTA.getSoftLimit(), SpaceViolationPolicy.DISABLE)); 084 085 QuotaProtos.SpaceQuota mergedSpaceQuota = merged.getSpaceProto(); 086 assertEquals(SPACE_QUOTA.getSoftLimit(), mergedSpaceQuota.getSoftLimit()); 087 assertEquals(QuotaProtos.SpaceViolationPolicy.DISABLE, mergedSpaceQuota.getViolationPolicy()); 088 } 089 090 @Test 091 public void testMergeThrottleAndSpace() throws IOException { 092 final String ns = "org1"; 093 QuotaProtos.Quotas quota = 094 QuotaProtos.Quotas.newBuilder().setThrottle(THROTTLE).setSpace(SPACE_QUOTA).build(); 095 GlobalQuotaSettingsImpl settings = new GlobalQuotaSettingsImpl(null, null, ns, null, quota); 096 097 QuotaProtos.TimedQuota writeQuota = REQUEST_THROTTLE.toBuilder().setSoftLimit(500).build(); 098 // Add a write throttle 099 QuotaProtos.ThrottleRequest writeThrottle = QuotaProtos.ThrottleRequest.newBuilder() 100 .setTimedQuota(writeQuota).setType(QuotaProtos.ThrottleType.WRITE_NUMBER).build(); 101 102 GlobalQuotaSettingsImpl merged = 103 settings.merge(new ThrottleSettings(null, null, ns, null, writeThrottle)); 104 GlobalQuotaSettingsImpl finalQuota = merged.merge(new SpaceLimitSettings(ns, 105 SPACE_QUOTA.getSoftLimit(), SpaceViolationPolicy.NO_WRITES_COMPACTIONS)); 106 107 // Verify both throttle quotas 108 QuotaProtos.Throttle throttle = finalQuota.getThrottleProto(); 109 assertTrue(throttle.hasReqNum()); 110 QuotaProtos.TimedQuota reqNumQuota = throttle.getReqNum(); 111 assertEquals(REQUEST_THROTTLE.getSoftLimit(), reqNumQuota.getSoftLimit()); 112 113 assertTrue(throttle.hasWriteNum()); 114 QuotaProtos.TimedQuota writeNumQuota = throttle.getWriteNum(); 115 assertEquals(writeQuota.getSoftLimit(), writeNumQuota.getSoftLimit()); 116 117 // Verify space quota 118 QuotaProtos.SpaceQuota finalSpaceQuota = finalQuota.getSpaceProto(); 119 assertEquals(SPACE_QUOTA.getSoftLimit(), finalSpaceQuota.getSoftLimit()); 120 assertEquals(QuotaProtos.SpaceViolationPolicy.NO_WRITES_COMPACTIONS, 121 finalSpaceQuota.getViolationPolicy()); 122 } 123}