1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.quotas;
18
19 import static com.google.common.collect.Iterables.size;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertNull;
22 import static org.mockito.Matchers.any;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.when;
25
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.concurrent.atomic.AtomicReference;
29
30 import org.apache.hadoop.hbase.HRegionInfo;
31 import org.apache.hadoop.hbase.NamespaceDescriptor;
32 import org.apache.hadoop.hbase.TableName;
33 import org.apache.hadoop.hbase.client.Connection;
34 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
35 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos;
36 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
37 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.SpaceQuota;
38 import org.apache.hadoop.hbase.testclassification.SmallTests;
39 import org.apache.hadoop.hbase.util.Bytes;
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.experimental.categories.Category;
43 import org.mockito.invocation.InvocationOnMock;
44 import org.mockito.stubbing.Answer;
45
46
47
48
49 @Category(SmallTests.class)
50 public class TestNamespaceQuotaViolationStore {
51 private static final long ONE_MEGABYTE = 1024L * 1024L;
52
53 private Connection conn;
54 private QuotaObserverChore chore;
55 private Map<HRegionInfo, Long> regionReports;
56 private NamespaceQuotaSnapshotStore store;
57
58 @Before
59 public void setup() {
60 conn = mock(Connection.class);
61 chore = mock(QuotaObserverChore.class);
62 regionReports = new HashMap<>();
63 store = new NamespaceQuotaSnapshotStore(conn, chore, regionReports);
64 }
65
66 @Test
67 public void testGetSpaceQuota() throws Exception {
68 NamespaceQuotaSnapshotStore mockStore = mock(NamespaceQuotaSnapshotStore.class);
69 when(mockStore.getSpaceQuota(any(String.class))).thenCallRealMethod();
70
71 Quotas quotaWithSpace = Quotas.newBuilder().setSpace(
72 SpaceQuota.newBuilder()
73 .setSoftLimit(1024L)
74 .setViolationPolicy(QuotaProtos.SpaceViolationPolicy.DISABLE)
75 .build())
76 .build();
77 Quotas quotaWithoutSpace = Quotas.newBuilder().build();
78
79 final AtomicReference<Quotas> quotaRef = new AtomicReference<>();
80 when(mockStore.getQuotaForNamespace(any(String.class))).then(new Answer<Quotas>() {
81 @Override
82 public Quotas answer(InvocationOnMock invocation) throws Throwable {
83 return quotaRef.get();
84 }
85 });
86
87 quotaRef.set(quotaWithSpace);
88 assertEquals(quotaWithSpace.getSpace(), mockStore.getSpaceQuota("ns"));
89 quotaRef.set(quotaWithoutSpace);
90 assertNull(mockStore.getSpaceQuota("ns"));
91 }
92
93 @Test
94 public void testTargetViolationState() {
95 final String NS = "ns";
96 TableName tn1 = TableName.valueOf(NS, "tn1");
97 TableName tn2 = TableName.valueOf(NS, "tn2");
98 TableName tn3 = TableName.valueOf("tn3");
99 SpaceQuota quota = SpaceQuota.newBuilder()
100 .setSoftLimit(ONE_MEGABYTE)
101 .setViolationPolicy(ProtobufUtil.toProtoViolationPolicy(SpaceViolationPolicy.DISABLE))
102 .build();
103
104
105
106 for (int i = 0; i < 3; i++) {
107 regionReports.put(new HRegionInfo(tn3, Bytes.toBytes(i), Bytes.toBytes(i + 1)),
108 5L * ONE_MEGABYTE);
109 }
110
111 regionReports.put(new HRegionInfo(tn1, Bytes.toBytes(0), Bytes.toBytes(1)), 1024L * 512L);
112 regionReports.put(new HRegionInfo(tn1, Bytes.toBytes(1), Bytes.toBytes(2)), 1024L * 256L);
113
114
115 assertEquals(false, store.getTargetState(NS, quota).getQuotaStatus().isInViolation());
116
117 regionReports.put(new HRegionInfo(tn2, Bytes.toBytes(2), Bytes.toBytes(3)), 1024L * 256L);
118
119
120 assertEquals(false, store.getTargetState(NS, quota).getQuotaStatus().isInViolation());
121
122 regionReports.put(new HRegionInfo(tn2, Bytes.toBytes(3), Bytes.toBytes(4)), 1024L);
123
124
125 assertEquals(true, store.getTargetState(NS, quota).getQuotaStatus().isInViolation());
126 assertEquals(SpaceViolationPolicy.DISABLE, store.getTargetState(NS, quota).getQuotaStatus().getPolicy());
127 }
128
129 @Test
130 public void testFilterRegionsByNamespace() {
131 TableName tn1 = TableName.valueOf("foo");
132 TableName tn2 = TableName.valueOf("sn", "bar");
133 TableName tn3 = TableName.valueOf("ns", "foo");
134 TableName tn4 = TableName.valueOf("ns", "bar");
135
136 assertEquals(0, size(store.filterBySubject("asdf")));
137
138 for (int i = 0; i < 5; i++) {
139 regionReports.put(new HRegionInfo(tn1, Bytes.toBytes(i), Bytes.toBytes(i+1)), 0L);
140 }
141 for (int i = 0; i < 3; i++) {
142 regionReports.put(new HRegionInfo(tn2, Bytes.toBytes(i), Bytes.toBytes(i+1)), 0L);
143 }
144 for (int i = 0; i < 10; i++) {
145 regionReports.put(new HRegionInfo(tn3, Bytes.toBytes(i), Bytes.toBytes(i+1)), 0L);
146 }
147 for (int i = 0; i < 8; i++) {
148 regionReports.put(new HRegionInfo(tn4, Bytes.toBytes(i), Bytes.toBytes(i+1)), 0L);
149 }
150 assertEquals(26, regionReports.size());
151 assertEquals(5, size(store.filterBySubject(NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR)));
152 assertEquals(3, size(store.filterBySubject("sn")));
153 assertEquals(18, size(store.filterBySubject("ns")));
154 }
155
156 }