HBASE-23741 Data loss when WAL split to HFile enabled (#1254)
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / TestNamespace.java
blob9eb7d819a976719e8697f768fb4a9c02fc0b4e0e
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
25 import java.io.IOException;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.concurrent.Callable;
29 import java.util.regex.Pattern;
30 import org.apache.hadoop.fs.FileSystem;
31 import org.apache.hadoop.fs.Path;
32 import org.apache.hadoop.hbase.client.Admin;
33 import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
34 import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
35 import org.apache.hadoop.hbase.client.Get;
36 import org.apache.hadoop.hbase.client.Put;
37 import org.apache.hadoop.hbase.client.Table;
38 import org.apache.hadoop.hbase.client.TableDescriptor;
39 import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
40 import org.apache.hadoop.hbase.master.HMaster;
41 import org.apache.hadoop.hbase.testclassification.MediumTests;
42 import org.apache.hadoop.hbase.testclassification.MiscTests;
43 import org.apache.hadoop.hbase.util.Bytes;
44 import org.junit.AfterClass;
45 import org.junit.Assert;
46 import org.junit.Before;
47 import org.junit.BeforeClass;
48 import org.junit.ClassRule;
49 import org.junit.Rule;
50 import org.junit.Test;
51 import org.junit.experimental.categories.Category;
52 import org.junit.rules.TestName;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
58 @Category({MiscTests.class, MediumTests.class})
59 public class TestNamespace {
61 @ClassRule
62 public static final HBaseClassTestRule CLASS_RULE =
63 HBaseClassTestRule.forClass(TestNamespace.class);
65 private static final Logger LOG = LoggerFactory.getLogger(TestNamespace.class);
66 private static HMaster master;
67 protected final static int NUM_SLAVES_BASE = 4;
68 private static HBaseTestingUtility TEST_UTIL;
69 protected static Admin admin;
70 protected static HBaseCluster cluster;
71 private String prefix = "TestNamespace";
73 @Rule
74 public TestName name = new TestName();
76 @BeforeClass
77 public static void setUp() throws Exception {
78 TEST_UTIL = new HBaseTestingUtility();
79 TEST_UTIL.startMiniCluster(NUM_SLAVES_BASE);
80 admin = TEST_UTIL.getAdmin();
81 cluster = TEST_UTIL.getHBaseCluster();
82 master = ((MiniHBaseCluster)cluster).getMaster();
83 LOG.info("Done initializing cluster");
86 @AfterClass
87 public static void tearDown() throws Exception {
88 TEST_UTIL.shutdownMiniCluster();
91 @Before
92 public void beforeMethod() throws IOException {
93 for (TableDescriptor desc : admin.listTableDescriptors(Pattern.compile(prefix + ".*"))) {
94 admin.disableTable(desc.getTableName());
95 admin.deleteTable(desc.getTableName());
97 for (NamespaceDescriptor ns : admin.listNamespaceDescriptors()) {
98 if (ns.getName().startsWith(prefix)) {
99 admin.deleteNamespace(ns.getName());
104 @Test
105 public void verifyReservedNS() throws IOException {
106 //verify existence of reserved namespaces
107 NamespaceDescriptor ns =
108 admin.getNamespaceDescriptor(NamespaceDescriptor.DEFAULT_NAMESPACE.getName());
109 assertNotNull(ns);
110 assertEquals(ns.getName(), NamespaceDescriptor.DEFAULT_NAMESPACE.getName());
112 ns = admin.getNamespaceDescriptor(NamespaceDescriptor.SYSTEM_NAMESPACE.getName());
113 assertNotNull(ns);
114 assertEquals(ns.getName(), NamespaceDescriptor.SYSTEM_NAMESPACE.getName());
116 assertEquals(2, admin.listNamespaces().length);
117 assertEquals(2, admin.listNamespaceDescriptors().length);
119 //verify existence of system tables
120 Set<TableName> systemTables = Sets.newHashSet(TableName.META_TABLE_NAME);
121 List<TableDescriptor> descs = admin.listTableDescriptorsByNamespace(
122 Bytes.toBytes(NamespaceDescriptor.SYSTEM_NAMESPACE.getName()));
123 assertEquals(systemTables.size(), descs.size());
124 for (TableDescriptor desc : descs) {
125 assertTrue(systemTables.contains(desc.getTableName()));
127 //verify system tables aren't listed
128 assertEquals(0, admin.listTableDescriptors().size());
130 //Try creating default and system namespaces.
131 boolean exceptionCaught = false;
132 try {
133 admin.createNamespace(NamespaceDescriptor.DEFAULT_NAMESPACE);
134 } catch (IOException exp) {
135 LOG.warn(exp.toString(), exp);
136 exceptionCaught = true;
137 } finally {
138 assertTrue(exceptionCaught);
141 exceptionCaught = false;
142 try {
143 admin.createNamespace(NamespaceDescriptor.SYSTEM_NAMESPACE);
144 } catch (IOException exp) {
145 LOG.warn(exp.toString(), exp);
146 exceptionCaught = true;
147 } finally {
148 assertTrue(exceptionCaught);
152 @Test
153 public void testDeleteReservedNS() throws Exception {
154 boolean exceptionCaught = false;
155 try {
156 admin.deleteNamespace(NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR);
157 } catch (IOException exp) {
158 LOG.warn(exp.toString(), exp);
159 exceptionCaught = true;
160 } finally {
161 assertTrue(exceptionCaught);
164 try {
165 admin.deleteNamespace(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR);
166 } catch (IOException exp) {
167 LOG.warn(exp.toString(), exp);
168 exceptionCaught = true;
169 } finally {
170 assertTrue(exceptionCaught);
174 @Test
175 public void createRemoveTest() throws Exception {
176 String nsName = prefix + "_" + name.getMethodName();
177 LOG.info(name.getMethodName());
179 //create namespace and verify
180 admin.createNamespace(NamespaceDescriptor.create(nsName).build());
181 assertEquals(3, admin.listNamespaces().length);
182 assertEquals(3, admin.listNamespaceDescriptors().length);
183 //remove namespace and verify
184 admin.deleteNamespace(nsName);
185 assertEquals(2, admin.listNamespaces().length);
186 assertEquals(2, admin.listNamespaceDescriptors().length);
189 @Test
190 public void createDoubleTest() throws IOException, InterruptedException {
191 String nsName = prefix + "_" + name.getMethodName();
192 LOG.info(name.getMethodName());
194 final TableName tableName = TableName.valueOf(name.getMethodName());
195 final TableName tableNameFoo = TableName.valueOf(nsName + ":" + name.getMethodName());
196 //create namespace and verify
197 admin.createNamespace(NamespaceDescriptor.create(nsName).build());
198 TEST_UTIL.createTable(tableName, Bytes.toBytes(nsName));
199 TEST_UTIL.createTable(tableNameFoo,Bytes.toBytes(nsName));
200 assertEquals(2, admin.listTableDescriptors().size());
201 assertNotNull(admin
202 .getDescriptor(tableName));
203 assertNotNull(admin
204 .getDescriptor(tableNameFoo));
205 //remove namespace and verify
206 admin.disableTable(tableName);
207 admin.deleteTable(tableName);
208 assertEquals(1, admin.listTableDescriptors().size());
211 @Test
212 public void createTableTest() throws IOException, InterruptedException {
213 String nsName = prefix + "_" + name.getMethodName();
214 LOG.info(name.getMethodName());
216 TableDescriptorBuilder tableDescriptorBuilder =
217 TableDescriptorBuilder.newBuilder(TableName.valueOf(nsName + ":" + name.getMethodName()));
218 ColumnFamilyDescriptor columnFamilyDescriptor =
219 ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("my_cf")).build();
220 tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);
221 TableDescriptor tableDescriptor = tableDescriptorBuilder.build();
222 try {
223 admin.createTable(tableDescriptor);
224 fail("Expected no namespace exists exception");
225 } catch (NamespaceNotFoundException ex) {
227 //create table and in new namespace
228 admin.createNamespace(NamespaceDescriptor.create(nsName).build());
229 admin.createTable(tableDescriptor);
230 TEST_UTIL.waitTableAvailable(tableDescriptor.getTableName().getName(), 10000);
231 FileSystem fs = FileSystem.get(TEST_UTIL.getConfiguration());
232 assertTrue(fs.exists(
233 new Path(master.getMasterFileSystem().getRootDir(),
234 new Path(HConstants.BASE_NAMESPACE_DIR,
235 new Path(nsName, tableDescriptor.getTableName().getQualifierAsString())))));
236 assertEquals(1, admin.listTableDescriptors().size());
238 //verify non-empty namespace can't be removed
239 try {
240 admin.deleteNamespace(nsName);
241 fail("Expected non-empty namespace constraint exception");
242 } catch (Exception ex) {
243 LOG.info("Caught expected exception: " + ex);
246 //sanity check try to write and read from table
247 Table table = TEST_UTIL.getConnection().getTable(tableDescriptor.getTableName());
248 Put p = new Put(Bytes.toBytes("row1"));
249 p.addColumn(Bytes.toBytes("my_cf"), Bytes.toBytes("my_col"), Bytes.toBytes("value1"));
250 table.put(p);
251 //flush and read from disk to make sure directory changes are working
252 admin.flush(tableDescriptor.getTableName());
253 Get g = new Get(Bytes.toBytes("row1"));
254 assertTrue(table.exists(g));
256 //normal case of removing namespace
257 TEST_UTIL.deleteTable(tableDescriptor.getTableName());
258 admin.deleteNamespace(nsName);
261 @Test
262 public void createTableInDefaultNamespace() throws Exception {
263 TableDescriptorBuilder tableDescriptorBuilder =
264 TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));
265 ColumnFamilyDescriptor columnFamilyDescriptor =
266 ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("cf1")).build();
267 tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);
268 TableDescriptor tableDescriptor = tableDescriptorBuilder.build();
269 admin.createTable(tableDescriptor);
270 assertTrue(admin.listTableDescriptors().size() == 1);
271 admin.disableTable(tableDescriptor.getTableName());
272 admin.deleteTable(tableDescriptor.getTableName());
275 @Test
276 public void createTableInSystemNamespace() throws Exception {
277 final TableName tableName = TableName.valueOf("hbase:" + name.getMethodName());
278 TableDescriptorBuilder tableDescriptorBuilder =
279 TableDescriptorBuilder.newBuilder(tableName);
280 ColumnFamilyDescriptor columnFamilyDescriptor =
281 ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("cf1")).build();
282 tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);
283 TableDescriptor tableDescriptor = tableDescriptorBuilder.build();
284 admin.createTable(tableDescriptor);
285 assertEquals(0, admin.listTableDescriptors().size());
286 assertTrue(admin.tableExists(tableName));
287 admin.disableTable(tableDescriptor.getTableName());
288 admin.deleteTable(tableDescriptor.getTableName());
291 @Test
292 public void testNamespaceOperations() throws IOException {
293 admin.createNamespace(NamespaceDescriptor.create(prefix + "ns1").build());
294 admin.createNamespace(NamespaceDescriptor.create(prefix + "ns2").build());
296 // create namespace that already exists
297 runWithExpectedException(new Callable<Void>() {
298 @Override
299 public Void call() throws Exception {
300 admin.createNamespace(NamespaceDescriptor.create(prefix + "ns1").build());
301 return null;
303 }, NamespaceExistException.class);
305 // create a table in non-existing namespace
306 runWithExpectedException(new Callable<Void>() {
307 @Override
308 public Void call() throws Exception {
309 TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder
310 .newBuilder(TableName.valueOf("non_existing_namespace", name.getMethodName()));
311 ColumnFamilyDescriptor columnFamilyDescriptor =
312 ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("family1")).build();
313 tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);
314 admin.createTable(tableDescriptorBuilder.build());
315 return null;
317 }, NamespaceNotFoundException.class);
319 // get descriptor for existing namespace
320 admin.getNamespaceDescriptor(prefix + "ns1");
322 // get descriptor for non-existing namespace
323 runWithExpectedException(new Callable<NamespaceDescriptor>() {
324 @Override
325 public NamespaceDescriptor call() throws Exception {
326 return admin.getNamespaceDescriptor("non_existing_namespace");
328 }, NamespaceNotFoundException.class);
330 // delete descriptor for existing namespace
331 admin.deleteNamespace(prefix + "ns2");
333 // delete descriptor for non-existing namespace
334 runWithExpectedException(new Callable<Void>() {
335 @Override
336 public Void call() throws Exception {
337 admin.deleteNamespace("non_existing_namespace");
338 return null;
340 }, NamespaceNotFoundException.class);
342 // modify namespace descriptor for existing namespace
343 NamespaceDescriptor ns1 = admin.getNamespaceDescriptor(prefix + "ns1");
344 ns1.setConfiguration("foo", "bar");
345 admin.modifyNamespace(ns1);
347 // modify namespace descriptor for non-existing namespace
348 runWithExpectedException(new Callable<Void>() {
349 @Override
350 public Void call() throws Exception {
351 admin.modifyNamespace(NamespaceDescriptor.create("non_existing_namespace").build());
352 return null;
354 }, NamespaceNotFoundException.class);
356 // get table descriptors for existing namespace
357 TableDescriptorBuilder tableDescriptorBuilder =
358 TableDescriptorBuilder.newBuilder(TableName.valueOf(prefix + "ns1", name.getMethodName()));
359 ColumnFamilyDescriptor columnFamilyDescriptor =
360 ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("family1")).build();
361 tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);
362 admin.createTable(tableDescriptorBuilder.build());
363 List<TableDescriptor> htds =
364 admin.listTableDescriptorsByNamespace(Bytes.toBytes(prefix + "ns1"));
365 assertNotNull("Should have not returned null", htds);
366 assertEquals("Should have returned non-empty array", 1, htds.size());
368 // get table descriptors for non-existing namespace
369 runWithExpectedException(new Callable<Void>() {
370 @Override
371 public Void call() throws Exception {
372 admin.listTableDescriptorsByNamespace(Bytes.toBytes("non_existant_namespace"));
373 return null;
375 }, NamespaceNotFoundException.class);
377 // get table names for existing namespace
378 TableName[] tableNames = admin.listTableNamesByNamespace(prefix + "ns1");
379 assertNotNull("Should have not returned null", tableNames);
380 assertEquals("Should have returned non-empty array", 1, tableNames.length);
382 // get table names for non-existing namespace
383 runWithExpectedException(new Callable<Void>() {
384 @Override
385 public Void call() throws Exception {
386 admin.listTableNamesByNamespace("non_existing_namespace");
387 return null;
389 }, NamespaceNotFoundException.class);
393 private static <V, E> void runWithExpectedException(Callable<V> callable, Class<E> exceptionClass) {
394 try {
395 callable.call();
396 } catch(Exception ex) {
397 Assert.assertEquals(exceptionClass, ex.getClass());
398 return;
400 fail("Should have thrown exception " + exceptionClass);