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; 022import static org.mockito.Mockito.doNothing; 023import static org.mockito.Mockito.doThrow; 024import static org.mockito.Mockito.mock; 025import static org.mockito.Mockito.when; 026 027import java.io.IOException; 028import java.util.HashMap; 029import java.util.Map; 030import org.apache.hadoop.hbase.HBaseClassTestRule; 031import org.apache.hadoop.hbase.TableName; 032import org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshot.SpaceQuotaStatus; 033import org.apache.hadoop.hbase.quotas.policies.DefaultViolationPolicyEnforcement; 034import org.apache.hadoop.hbase.quotas.policies.DisableTableViolationPolicyEnforcement; 035import org.apache.hadoop.hbase.quotas.policies.NoInsertsViolationPolicyEnforcement; 036import org.apache.hadoop.hbase.quotas.policies.NoWritesCompactionsViolationPolicyEnforcement; 037import org.apache.hadoop.hbase.quotas.policies.NoWritesViolationPolicyEnforcement; 038import org.apache.hadoop.hbase.regionserver.RegionServerServices; 039import org.apache.hadoop.hbase.testclassification.SmallTests; 040import org.junit.Before; 041import org.junit.ClassRule; 042import org.junit.Test; 043import org.junit.experimental.categories.Category; 044 045/** 046 * Test class for {@link RegionServerSpaceQuotaManager}. 047 */ 048@Category(SmallTests.class) 049public class TestRegionServerSpaceQuotaManager { 050 051 @ClassRule 052 public static final HBaseClassTestRule CLASS_RULE = 053 HBaseClassTestRule.forClass(TestRegionServerSpaceQuotaManager.class); 054 055 private RegionServerSpaceQuotaManager quotaManager; 056 private RegionServerServices rss; 057 058 @Before 059 public void setup() throws Exception { 060 quotaManager = mock(RegionServerSpaceQuotaManager.class); 061 rss = mock(RegionServerServices.class); 062 } 063 064 @Test 065 public void testSpacePoliciesFromEnforcements() { 066 final Map<TableName, SpaceViolationPolicyEnforcement> enforcements = new HashMap<>(); 067 final Map<TableName, SpaceQuotaSnapshot> expectedPolicies = new HashMap<>(); 068 when(quotaManager.copyActiveEnforcements()).thenReturn(enforcements); 069 when(quotaManager.getActivePoliciesAsMap()).thenCallRealMethod(); 070 071 NoInsertsViolationPolicyEnforcement noInsertsPolicy = new NoInsertsViolationPolicyEnforcement(); 072 SpaceQuotaSnapshot noInsertsSnapshot = new SpaceQuotaSnapshot( 073 new SpaceQuotaStatus(SpaceViolationPolicy.NO_INSERTS), 256L, 1024L); 074 noInsertsPolicy.initialize(rss, TableName.valueOf("no_inserts"), noInsertsSnapshot); 075 enforcements.put(noInsertsPolicy.getTableName(), noInsertsPolicy); 076 expectedPolicies.put(noInsertsPolicy.getTableName(), noInsertsSnapshot); 077 078 NoWritesViolationPolicyEnforcement noWritesPolicy = new NoWritesViolationPolicyEnforcement(); 079 SpaceQuotaSnapshot noWritesSnapshot = new SpaceQuotaSnapshot( 080 new SpaceQuotaStatus(SpaceViolationPolicy.NO_WRITES), 512L, 2048L); 081 noWritesPolicy.initialize(rss, TableName.valueOf("no_writes"), noWritesSnapshot); 082 enforcements.put(noWritesPolicy.getTableName(), noWritesPolicy); 083 expectedPolicies.put(noWritesPolicy.getTableName(), noWritesSnapshot); 084 085 NoWritesCompactionsViolationPolicyEnforcement noWritesCompactionsPolicy = 086 new NoWritesCompactionsViolationPolicyEnforcement(); 087 SpaceQuotaSnapshot noWritesCompactionsSnapshot = new SpaceQuotaSnapshot( 088 new SpaceQuotaStatus(SpaceViolationPolicy.NO_WRITES_COMPACTIONS), 1024L, 4096L); 089 noWritesCompactionsPolicy.initialize( 090 rss, TableName.valueOf("no_writes_compactions"), noWritesCompactionsSnapshot); 091 enforcements.put(noWritesCompactionsPolicy.getTableName(), noWritesCompactionsPolicy); 092 expectedPolicies.put(noWritesCompactionsPolicy.getTableName(), 093 noWritesCompactionsSnapshot); 094 095 DisableTableViolationPolicyEnforcement disablePolicy = 096 new DisableTableViolationPolicyEnforcement(); 097 SpaceQuotaSnapshot disableSnapshot = new SpaceQuotaSnapshot( 098 new SpaceQuotaStatus(SpaceViolationPolicy.DISABLE), 2048L, 8192L); 099 disablePolicy.initialize(rss, TableName.valueOf("disable"), disableSnapshot); 100 enforcements.put(disablePolicy.getTableName(), disablePolicy); 101 expectedPolicies.put(disablePolicy.getTableName(), disableSnapshot); 102 103 enforcements.put( 104 TableName.valueOf("no_policy"), new DefaultViolationPolicyEnforcement()); 105 106 Map<TableName, SpaceQuotaSnapshot> actualPolicies = quotaManager.getActivePoliciesAsMap(); 107 assertEquals(expectedPolicies, actualPolicies); 108 } 109 110 @Test 111 public void testExceptionOnPolicyEnforcementEnable() throws Exception { 112 final TableName tableName = TableName.valueOf("foo"); 113 final SpaceQuotaSnapshot snapshot = new SpaceQuotaSnapshot( 114 new SpaceQuotaStatus(SpaceViolationPolicy.DISABLE), 1024L, 2048L); 115 RegionServerServices rss = mock(RegionServerServices.class); 116 SpaceViolationPolicyEnforcementFactory factory = mock( 117 SpaceViolationPolicyEnforcementFactory.class); 118 SpaceViolationPolicyEnforcement enforcement = mock(SpaceViolationPolicyEnforcement.class); 119 RegionServerSpaceQuotaManager realManager = new RegionServerSpaceQuotaManager(rss, factory); 120 121 when(factory.create(rss, tableName, snapshot)).thenReturn(enforcement); 122 doThrow(new IOException("Failed for test!")).when(enforcement).enable(); 123 124 realManager.enforceViolationPolicy(tableName, snapshot); 125 Map<TableName, SpaceViolationPolicyEnforcement> enforcements = 126 realManager.copyActiveEnforcements(); 127 assertTrue("Expected active enforcements to be empty, but were " + enforcements, 128 enforcements.isEmpty()); 129 } 130 131 @Test 132 public void testExceptionOnPolicyEnforcementDisable() throws Exception { 133 final TableName tableName = TableName.valueOf("foo"); 134 final SpaceQuotaSnapshot snapshot = new SpaceQuotaSnapshot( 135 new SpaceQuotaStatus(SpaceViolationPolicy.DISABLE), 1024L, 2048L); 136 RegionServerServices rss = mock(RegionServerServices.class); 137 SpaceViolationPolicyEnforcementFactory factory = mock( 138 SpaceViolationPolicyEnforcementFactory.class); 139 SpaceViolationPolicyEnforcement enforcement = mock(SpaceViolationPolicyEnforcement.class); 140 RegionServerSpaceQuotaManager realManager = new RegionServerSpaceQuotaManager(rss, factory); 141 142 when(factory.create(rss, tableName, snapshot)).thenReturn(enforcement); 143 doNothing().when(enforcement).enable(); 144 doThrow(new IOException("Failed for test!")).when(enforcement).disable(); 145 146 // Enabling should work 147 realManager.enforceViolationPolicy(tableName, snapshot); 148 Map<TableName, SpaceViolationPolicyEnforcement> enforcements = 149 realManager.copyActiveEnforcements(); 150 assertEquals(1, enforcements.size()); 151 152 // If the disable fails, we should still treat it as "active" 153 realManager.disableViolationPolicyEnforcement(tableName); 154 enforcements = realManager.copyActiveEnforcements(); 155 assertEquals(1, enforcements.size()); 156 } 157}