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.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertFalse; 022import static org.junit.jupiter.api.Assertions.assertNotNull; 023import static org.junit.jupiter.api.Assertions.assertThrows; 024import static org.junit.jupiter.api.Assertions.fail; 025 026import java.io.IOException; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.testclassification.SmallTests; 029import org.junit.jupiter.api.Tag; 030import org.junit.jupiter.api.Test; 031 032import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 033import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetQuotaRequest; 034import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.SpaceLimitRequest; 035import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.SpaceQuota; 036 037/** 038 * Test class for {@link SpaceLimitSettings}. 039 */ 040@Tag(SmallTests.TAG) 041public class TestSpaceLimitSettings { 042 043 @Test 044 public void testInvalidTableQuotaSizeLimit() { 045 assertThrows(IllegalArgumentException.class, 046 () -> new SpaceLimitSettings(TableName.valueOf("foo"), -1, SpaceViolationPolicy.NO_INSERTS)); 047 } 048 049 @Test 050 public void testNullTableName() { 051 TableName tn = null; 052 assertThrows(NullPointerException.class, 053 () -> new SpaceLimitSettings(tn, 1, SpaceViolationPolicy.NO_INSERTS)); 054 } 055 056 @Test 057 public void testNullTableViolationPolicy() { 058 assertThrows(NullPointerException.class, 059 () -> new SpaceLimitSettings(TableName.valueOf("foo"), 1, null)); 060 } 061 062 @Test 063 public void testInvalidNamespaceQuotaSizeLimit() { 064 assertThrows(IllegalArgumentException.class, 065 () -> new SpaceLimitSettings("foo_ns", -1, SpaceViolationPolicy.NO_INSERTS)); 066 } 067 068 @Test 069 public void testNullNamespace() { 070 String ns = null; 071 assertThrows(NullPointerException.class, 072 () -> new SpaceLimitSettings(ns, 1, SpaceViolationPolicy.NO_INSERTS)); 073 } 074 075 @Test 076 public void testNullNamespaceViolationPolicy() { 077 assertThrows(NullPointerException.class, () -> new SpaceLimitSettings("foo_ns", 1, null)); 078 079 } 080 081 @Test 082 public void testTableQuota() { 083 final TableName tableName = TableName.valueOf("foo"); 084 final long sizeLimit = 1024 * 1024; 085 final SpaceViolationPolicy policy = SpaceViolationPolicy.NO_WRITES; 086 SpaceLimitSettings settings = new SpaceLimitSettings(tableName, sizeLimit, policy); 087 SetQuotaRequest proto = QuotaSettings.buildSetQuotaRequestProto(settings); 088 089 assertFalse(proto.hasUserName(), "User should be missing"); 090 assertFalse(proto.hasNamespace(), "Namespace should be missing"); 091 assertEquals(ProtobufUtil.toProtoTableName(tableName), proto.getTableName()); 092 SpaceLimitRequest spaceLimitReq = proto.getSpaceLimit(); 093 assertNotNull(spaceLimitReq, "SpaceLimitRequest was null"); 094 SpaceQuota spaceQuota = spaceLimitReq.getQuota(); 095 assertNotNull(spaceQuota, "SpaceQuota was null"); 096 assertEquals(sizeLimit, spaceQuota.getSoftLimit()); 097 assertEquals(ProtobufUtil.toProtoViolationPolicy(policy), spaceQuota.getViolationPolicy()); 098 099 assertEquals(QuotaType.SPACE, settings.getQuotaType()); 100 101 SpaceLimitSettings copy = new SpaceLimitSettings(tableName, sizeLimit, policy); 102 assertEquals(settings, copy); 103 assertEquals(settings.hashCode(), copy.hashCode()); 104 } 105 106 @Test 107 public void testNamespaceQuota() { 108 final String namespace = "foo_ns"; 109 final long sizeLimit = 1024 * 1024; 110 final SpaceViolationPolicy policy = SpaceViolationPolicy.NO_WRITES; 111 SpaceLimitSettings settings = new SpaceLimitSettings(namespace, sizeLimit, policy); 112 SetQuotaRequest proto = QuotaSettings.buildSetQuotaRequestProto(settings); 113 114 assertFalse(proto.hasUserName(), "User should be missing"); 115 assertFalse(proto.hasTableName(), "TableName should be missing"); 116 assertEquals(namespace, proto.getNamespace()); 117 SpaceLimitRequest spaceLimitReq = proto.getSpaceLimit(); 118 assertNotNull(spaceLimitReq, "SpaceLimitRequest was null"); 119 SpaceQuota spaceQuota = spaceLimitReq.getQuota(); 120 assertNotNull(spaceQuota, "SpaceQuota was null"); 121 assertEquals(sizeLimit, spaceQuota.getSoftLimit()); 122 assertEquals(ProtobufUtil.toProtoViolationPolicy(policy), spaceQuota.getViolationPolicy()); 123 124 assertEquals(QuotaType.SPACE, settings.getQuotaType()); 125 126 SpaceLimitSettings copy = new SpaceLimitSettings(namespace, sizeLimit, policy); 127 assertEquals(settings, copy); 128 assertEquals(settings.hashCode(), copy.hashCode()); 129 } 130 131 @Test 132 public void testQuotaMerging() throws IOException { 133 TableName tn = TableName.valueOf("foo"); 134 QuotaSettings originalSettings = 135 QuotaSettingsFactory.limitTableSpace(tn, 1024L * 1024L, SpaceViolationPolicy.DISABLE); 136 QuotaSettings largerSizeLimit = 137 QuotaSettingsFactory.limitTableSpace(tn, 5L * 1024L * 1024L, SpaceViolationPolicy.DISABLE); 138 QuotaSettings differentPolicy = 139 QuotaSettingsFactory.limitTableSpace(tn, 1024L * 1024L, SpaceViolationPolicy.NO_WRITES); 140 QuotaSettings incompatibleSettings = QuotaSettingsFactory.limitNamespaceSpace("ns1", 141 5L * 1024L * 1024L, SpaceViolationPolicy.NO_WRITES); 142 143 assertEquals(originalSettings.merge(largerSizeLimit), largerSizeLimit); 144 assertEquals(originalSettings.merge(differentPolicy), differentPolicy); 145 try { 146 originalSettings.merge(incompatibleSettings); 147 fail("Should not be able to merge a Table space quota with a namespace space quota."); 148 } catch (IllegalArgumentException e) { 149 // pass 150 } 151 } 152}