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.constraint; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023import static org.junit.Assert.fail; 024 025import java.util.List; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.hbase.HBaseClassTestRule; 028import org.apache.hadoop.hbase.HTableDescriptor; 029import org.apache.hadoop.hbase.TableName; 030import org.apache.hadoop.hbase.client.Put; 031import org.apache.hadoop.hbase.constraint.TestConstraint.CheckWasRunConstraint; 032import org.apache.hadoop.hbase.constraint.WorksConstraint.NameConstraint; 033import org.apache.hadoop.hbase.testclassification.MiscTests; 034import org.apache.hadoop.hbase.testclassification.SmallTests; 035import org.apache.hadoop.hbase.util.Pair; 036import org.junit.ClassRule; 037import org.junit.Rule; 038import org.junit.Test; 039import org.junit.experimental.categories.Category; 040import org.junit.rules.TestName; 041 042/** 043 * Test reading/writing the constraints into the {@link HTableDescriptor} 044 */ 045@Category({ MiscTests.class, SmallTests.class }) 046public class TestConstraints { 047 048 @ClassRule 049 public static final HBaseClassTestRule CLASS_RULE = 050 HBaseClassTestRule.forClass(TestConstraints.class); 051 052 @Rule 053 public TestName name = new TestName(); 054 055 @SuppressWarnings("unchecked") 056 @Test 057 public void testSimpleReadWrite() throws Throwable { 058 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 059 Constraints.add(desc, WorksConstraint.class); 060 061 List<? extends Constraint> constraints = 062 Constraints.getConstraints(desc, this.getClass().getClassLoader()); 063 assertEquals(1, constraints.size()); 064 065 assertEquals(WorksConstraint.class, constraints.get(0).getClass()); 066 067 // Check that we can add more than 1 constraint and that ordering is 068 // preserved 069 Constraints.add(desc, AlsoWorks.class, NameConstraint.class); 070 constraints = Constraints.getConstraints(desc, this.getClass().getClassLoader()); 071 assertEquals(3, constraints.size()); 072 073 assertEquals(WorksConstraint.class, constraints.get(0).getClass()); 074 assertEquals(AlsoWorks.class, constraints.get(1).getClass()); 075 assertEquals(NameConstraint.class, constraints.get(2).getClass()); 076 077 } 078 079 @SuppressWarnings("unchecked") 080 @Test 081 public void testReadWriteWithConf() throws Throwable { 082 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 083 Constraints.add(desc, new Pair<>(CheckConfigurationConstraint.class, 084 CheckConfigurationConstraint.getConfiguration())); 085 086 List<? extends Constraint> c = 087 Constraints.getConstraints(desc, this.getClass().getClassLoader()); 088 assertEquals(1, c.size()); 089 090 assertEquals(CheckConfigurationConstraint.class, c.get(0).getClass()); 091 092 // check to make sure that we overwrite configurations 093 Constraints.add(desc, new Pair<>(CheckConfigurationConstraint.class, new Configuration(false))); 094 095 try { 096 Constraints.getConstraints(desc, this.getClass().getClassLoader()); 097 fail("No exception thrown - configuration not overwritten"); 098 } catch (IllegalArgumentException e) { 099 // expect to have the exception, so don't do anything 100 } 101 } 102 103 /** 104 * Test that Constraints are properly enabled, disabled, and removed 105 */ 106 @SuppressWarnings("unchecked") 107 @Test 108 public void testEnableDisableRemove() throws Exception { 109 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 110 // check general enabling/disabling of constraints 111 // first add a constraint 112 Constraints.add(desc, AllPassConstraint.class); 113 // make sure everything is enabled 114 assertTrue(Constraints.enabled(desc, AllPassConstraint.class)); 115 assertTrue(desc.hasCoprocessor(ConstraintProcessor.class.getName())); 116 117 // check disabling 118 Constraints.disable(desc); 119 assertFalse(desc.hasCoprocessor(ConstraintProcessor.class.getName())); 120 // make sure the added constraints are still present 121 assertTrue(Constraints.enabled(desc, AllPassConstraint.class)); 122 123 // check just removing the single constraint 124 Constraints.remove(desc, AllPassConstraint.class); 125 assertFalse(Constraints.has(desc, AllPassConstraint.class)); 126 127 // Add back the single constraint 128 Constraints.add(desc, AllPassConstraint.class); 129 130 // and now check that when we remove constraints, all are gone 131 Constraints.remove(desc); 132 assertFalse(desc.hasCoprocessor(ConstraintProcessor.class.getName())); 133 assertFalse(Constraints.has(desc, AllPassConstraint.class)); 134 135 } 136 137 /** 138 * Test that when we update a constraint the ordering is not modified. 139 */ 140 @SuppressWarnings("unchecked") 141 @Test 142 public void testUpdateConstraint() throws Exception { 143 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 144 Constraints.add(desc, CheckConfigurationConstraint.class, CheckWasRunConstraint.class); 145 Constraints.setConfiguration(desc, CheckConfigurationConstraint.class, 146 CheckConfigurationConstraint.getConfiguration()); 147 148 List<? extends Constraint> constraints = 149 Constraints.getConstraints(desc, this.getClass().getClassLoader()); 150 151 assertEquals(2, constraints.size()); 152 153 // check to make sure the order didn't change 154 assertEquals(CheckConfigurationConstraint.class, constraints.get(0).getClass()); 155 assertEquals(CheckWasRunConstraint.class, constraints.get(1).getClass()); 156 } 157 158 /** 159 * Test that if a constraint hasn't been set that there are no problems with attempting to remove 160 * it. on failure. 161 */ 162 @Test 163 public void testRemoveUnsetConstraint() throws Throwable { 164 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 165 Constraints.remove(desc); 166 Constraints.remove(desc, AlsoWorks.class); 167 } 168 169 @Test 170 public void testConfigurationPreserved() throws Throwable { 171 Configuration conf = new Configuration(); 172 conf.setBoolean("_ENABLED", false); 173 conf.setLong("_PRIORITY", 10); 174 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 175 Constraints.add(desc, AlsoWorks.class, conf); 176 Constraints.add(desc, WorksConstraint.class); 177 assertFalse(Constraints.enabled(desc, AlsoWorks.class)); 178 List<? extends Constraint> constraints = 179 Constraints.getConstraints(desc, this.getClass().getClassLoader()); 180 for (Constraint c : constraints) { 181 Configuration storedConf = c.getConf(); 182 if (c instanceof AlsoWorks) assertEquals(10, storedConf.getLong("_PRIORITY", -1)); 183 // its just a worksconstraint 184 else assertEquals(2, storedConf.getLong("_PRIORITY", -1)); 185 186 } 187 188 } 189 190 // ---------- Constraints just used for testing 191 192 /** 193 * Also just works 194 */ 195 public static class AlsoWorks extends BaseConstraint { 196 @Override 197 public void check(Put p) { 198 // NOOP 199 } 200 } 201 202}