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.util; 019 020import static org.junit.jupiter.api.Assertions.assertThrows; 021 022import java.io.IOException; 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.hbase.DoNotRetryIOException; 025import org.apache.hadoop.hbase.TableName; 026import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 027import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 028import org.apache.hadoop.hbase.conf.ConfigKey; 029import org.apache.hadoop.hbase.regionserver.BloomType; 030import org.apache.hadoop.hbase.testclassification.MiscTests; 031import org.apache.hadoop.hbase.testclassification.SmallTests; 032import org.junit.jupiter.api.Tag; 033import org.junit.jupiter.api.Test; 034 035@Tag(MiscTests.TAG) 036@Tag(SmallTests.TAG) 037public class TestTableDescriptorChecker { 038 039 @Test 040 public void testSanityCheck() throws IOException { 041 Configuration conf = new Configuration(); 042 TableDescriptorBuilder t = TableDescriptorBuilder.newBuilder(TableName.valueOf("test")); 043 ColumnFamilyDescriptorBuilder cf = ColumnFamilyDescriptorBuilder.newBuilder("cf".getBytes()); 044 t.setColumnFamily(cf.build()); 045 046 // Empty configuration. Should be fine. 047 TableDescriptorChecker.sanityCheck(conf, t.build()); 048 049 // Declare configuration type as int. 050 String key = "hbase.hstore.compaction.ratio"; 051 ConfigKey.INT(key, v -> v > 0); 052 053 // Error in table configuration. 054 t.setValue(key, "xx"); 055 assertThrows(DoNotRetryIOException.class, 056 () -> TableDescriptorChecker.sanityCheck(conf, t.build()), 057 "Should have thrown IllegalArgumentException"); 058 059 // Fix the error. 060 t.setValue(key, "1"); 061 TableDescriptorChecker.sanityCheck(conf, t.build()); 062 063 // Verify column family configuration. 064 for (boolean viaSetValue : new boolean[] { true, false }) { 065 // Error in column family configuration. 066 if (viaSetValue) { 067 cf.setValue(key, "xx"); 068 } else { 069 cf.setConfiguration(key, "xx"); 070 } 071 t.removeColumnFamily("cf".getBytes()); 072 t.setColumnFamily(cf.build()); 073 assertThrows(DoNotRetryIOException.class, 074 () -> TableDescriptorChecker.sanityCheck(conf, t.build()), 075 "Should have thrown IllegalArgumentException"); 076 077 // Fix the error. 078 if (viaSetValue) { 079 cf.setValue(key, ""); 080 } else { 081 cf.setConfiguration(key, ""); 082 } 083 t.removeColumnFamily("cf".getBytes()); 084 t.setColumnFamily(cf.build()); 085 TableDescriptorChecker.sanityCheck(conf, t.build()); 086 } 087 } 088 089 @Test 090 public void testBloomFilterPrefixLengthValidation() throws IOException { 091 Configuration conf = new Configuration(); 092 String key = BloomFilterUtil.PREFIX_LENGTH_KEY; 093 094 for (boolean viaSetValue : new boolean[] { true, false }) { 095 ColumnFamilyDescriptorBuilder cf = ColumnFamilyDescriptorBuilder.newBuilder("cf".getBytes()) 096 .setBloomFilterType(BloomType.ROWPREFIX_FIXED_LENGTH); 097 TableDescriptorBuilder t = TableDescriptorBuilder.newBuilder(TableName.valueOf("test")); 098 099 // Invalid: prefix length must be > 0 for ROWPREFIX_FIXED_LENGTH 100 if (viaSetValue) { 101 cf.setValue(key, "0"); 102 } else { 103 cf.setConfiguration(key, "0"); 104 } 105 t.setColumnFamily(cf.build()); 106 assertThrows(DoNotRetryIOException.class, 107 () -> TableDescriptorChecker.sanityCheck(conf, t.build()), 108 "Should reject ROWPREFIX_FIXED_LENGTH with prefix length 0 set via " 109 + (viaSetValue ? "setValue" : "setConfiguration")); 110 111 // Fix the error. 112 if (viaSetValue) { 113 cf.setValue(key, "5"); 114 } else { 115 cf.setConfiguration(key, "5"); 116 } 117 t.removeColumnFamily("cf".getBytes()); 118 t.setColumnFamily(cf.build()); 119 TableDescriptorChecker.sanityCheck(conf, t.build()); 120 } 121 } 122}