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 = 073 new SpaceQuotaSnapshot(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 = 080 new SpaceQuotaSnapshot(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(rss, TableName.valueOf("no_writes_compactions"), 090 noWritesCompactionsSnapshot); 091 enforcements.put(noWritesCompactionsPolicy.getTableName(), noWritesCompactionsPolicy); 092 expectedPolicies.put(noWritesCompactionsPolicy.getTableName(), noWritesCompactionsSnapshot); 093 094 DisableTableViolationPolicyEnforcement disablePolicy = 095 new DisableTableViolationPolicyEnforcement(); 096 SpaceQuotaSnapshot disableSnapshot = 097 new SpaceQuotaSnapshot(new SpaceQuotaStatus(SpaceViolationPolicy.DISABLE), 2048L, 8192L); 098 disablePolicy.initialize(rss, TableName.valueOf("disable"), disableSnapshot); 099 enforcements.put(disablePolicy.getTableName(), disablePolicy); 100 expectedPolicies.put(disablePolicy.getTableName(), disableSnapshot); 101 102 enforcements.put(TableName.valueOf("no_policy"), new DefaultViolationPolicyEnforcement()); 103 104 Map<TableName, SpaceQuotaSnapshot> actualPolicies = quotaManager.getActivePoliciesAsMap(); 105 assertEquals(expectedPolicies, actualPolicies); 106 } 107 108 @Test 109 public void testExceptionOnPolicyEnforcementEnable() throws Exception { 110 final TableName tableName = TableName.valueOf("foo"); 111 final SpaceQuotaSnapshot snapshot = 112 new SpaceQuotaSnapshot(new SpaceQuotaStatus(SpaceViolationPolicy.DISABLE), 1024L, 2048L); 113 RegionServerServices rss = mock(RegionServerServices.class); 114 SpaceViolationPolicyEnforcementFactory factory = 115 mock(SpaceViolationPolicyEnforcementFactory.class); 116 SpaceViolationPolicyEnforcement enforcement = mock(SpaceViolationPolicyEnforcement.class); 117 RegionServerSpaceQuotaManager realManager = new RegionServerSpaceQuotaManager(rss, factory); 118 119 when(factory.create(rss, tableName, snapshot)).thenReturn(enforcement); 120 doThrow(new IOException("Failed for test!")).when(enforcement).enable(); 121 122 realManager.enforceViolationPolicy(tableName, snapshot); 123 Map<TableName, SpaceViolationPolicyEnforcement> enforcements = 124 realManager.copyActiveEnforcements(); 125 assertTrue("Expected active enforcements to be empty, but were " + enforcements, 126 enforcements.isEmpty()); 127 } 128 129 @Test 130 public void testExceptionOnPolicyEnforcementDisable() throws Exception { 131 final TableName tableName = TableName.valueOf("foo"); 132 final SpaceQuotaSnapshot snapshot = 133 new SpaceQuotaSnapshot(new SpaceQuotaStatus(SpaceViolationPolicy.DISABLE), 1024L, 2048L); 134 RegionServerServices rss = mock(RegionServerServices.class); 135 SpaceViolationPolicyEnforcementFactory factory = 136 mock(SpaceViolationPolicyEnforcementFactory.class); 137 SpaceViolationPolicyEnforcement enforcement = mock(SpaceViolationPolicyEnforcement.class); 138 RegionServerSpaceQuotaManager realManager = new RegionServerSpaceQuotaManager(rss, factory); 139 140 when(factory.create(rss, tableName, snapshot)).thenReturn(enforcement); 141 doNothing().when(enforcement).enable(); 142 doThrow(new IOException("Failed for test!")).when(enforcement).disable(); 143 144 // Enabling should work 145 realManager.enforceViolationPolicy(tableName, snapshot); 146 Map<TableName, SpaceViolationPolicyEnforcement> enforcements = 147 realManager.copyActiveEnforcements(); 148 assertEquals(1, enforcements.size()); 149 150 // If the disable fails, we should still treat it as "active" 151 realManager.disableViolationPolicyEnforcement(tableName); 152 enforcements = realManager.copyActiveEnforcements(); 153 assertEquals(1, enforcements.size()); 154 } 155}