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 = Constraints.getConstraints(desc, 062 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() 071 .getClassLoader()); 072 assertEquals(3, constraints.size()); 073 074 assertEquals(WorksConstraint.class, constraints.get(0).getClass()); 075 assertEquals(AlsoWorks.class, constraints.get(1).getClass()); 076 assertEquals(NameConstraint.class, constraints.get(2).getClass()); 077 078 } 079 080 @SuppressWarnings("unchecked") 081 @Test 082 public void testReadWriteWithConf() throws Throwable { 083 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 084 Constraints.add(desc, 085 new Pair<>(CheckConfigurationConstraint.class, 086 CheckConfigurationConstraint.getConfiguration())); 087 088 List<? extends Constraint> c = Constraints.getConstraints(desc, this 089 .getClass().getClassLoader()); 090 assertEquals(1, c.size()); 091 092 assertEquals(CheckConfigurationConstraint.class, c.get(0).getClass()); 093 094 // check to make sure that we overwrite configurations 095 Constraints.add(desc, new Pair<>( 096 CheckConfigurationConstraint.class, new Configuration(false))); 097 098 try { 099 Constraints.getConstraints(desc, this.getClass().getClassLoader()); 100 fail("No exception thrown - configuration not overwritten"); 101 } catch (IllegalArgumentException e) { 102 // expect to have the exception, so don't do anything 103 } 104 } 105 106 /** 107 * Test that Constraints are properly enabled, disabled, and removed 108 * 109 * @throws Exception 110 */ 111 @SuppressWarnings("unchecked") 112 @Test 113 public void testEnableDisableRemove() throws Exception { 114 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 115 // check general enabling/disabling of constraints 116 // first add a constraint 117 Constraints.add(desc, AllPassConstraint.class); 118 // make sure everything is enabled 119 assertTrue(Constraints.enabled(desc, AllPassConstraint.class)); 120 assertTrue(desc.hasCoprocessor(ConstraintProcessor.class.getName())); 121 122 // check disabling 123 Constraints.disable(desc); 124 assertFalse(desc.hasCoprocessor(ConstraintProcessor.class.getName())); 125 // make sure the added constraints are still present 126 assertTrue(Constraints.enabled(desc, AllPassConstraint.class)); 127 128 // check just removing the single constraint 129 Constraints.remove(desc, AllPassConstraint.class); 130 assertFalse(Constraints.has(desc, AllPassConstraint.class)); 131 132 // Add back the single constraint 133 Constraints.add(desc, AllPassConstraint.class); 134 135 // and now check that when we remove constraints, all are gone 136 Constraints.remove(desc); 137 assertFalse(desc.hasCoprocessor(ConstraintProcessor.class.getName())); 138 assertFalse(Constraints.has(desc, AllPassConstraint.class)); 139 140 } 141 142 /** 143 * Test that when we update a constraint the ordering is not modified. 144 * 145 * @throws Exception 146 */ 147 @SuppressWarnings("unchecked") 148 @Test 149 public void testUpdateConstraint() throws Exception { 150 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 151 Constraints.add(desc, CheckConfigurationConstraint.class, 152 CheckWasRunConstraint.class); 153 Constraints.setConfiguration(desc, CheckConfigurationConstraint.class, 154 CheckConfigurationConstraint.getConfiguration()); 155 156 List<? extends Constraint> constraints = Constraints.getConstraints(desc, 157 this.getClass().getClassLoader()); 158 159 assertEquals(2, constraints.size()); 160 161 // check to make sure the order didn't change 162 assertEquals(CheckConfigurationConstraint.class, constraints.get(0) 163 .getClass()); 164 assertEquals(CheckWasRunConstraint.class, constraints.get(1).getClass()); 165 } 166 167 /** 168 * Test that if a constraint hasn't been set that there are no problems with 169 * attempting to remove it. 170 * 171 * @throws Throwable 172 * on failure. 173 */ 174 @Test 175 public void testRemoveUnsetConstraint() throws Throwable { 176 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 177 Constraints.remove(desc); 178 Constraints.remove(desc, AlsoWorks.class); 179 } 180 181 @Test 182 public void testConfigurationPreserved() throws Throwable { 183 Configuration conf = new Configuration(); 184 conf.setBoolean("_ENABLED", false); 185 conf.setLong("_PRIORITY", 10); 186 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 187 Constraints.add(desc, AlsoWorks.class, conf); 188 Constraints.add(desc, WorksConstraint.class); 189 assertFalse(Constraints.enabled(desc, AlsoWorks.class)); 190 List<? extends Constraint> constraints = Constraints.getConstraints(desc, 191 this.getClass().getClassLoader()); 192 for (Constraint c : constraints) { 193 Configuration storedConf = c.getConf(); 194 if (c instanceof AlsoWorks) 195 assertEquals(10, storedConf.getLong("_PRIORITY", -1)); 196 // its just a worksconstraint 197 else 198 assertEquals(2, storedConf.getLong("_PRIORITY", -1)); 199 200 } 201 202 } 203 204 // ---------- Constraints just used for testing 205 206 /** 207 * Also just works 208 */ 209 public static class AlsoWorks extends BaseConstraint { 210 @Override 211 public void check(Put p) { 212 // NOOP 213 } 214 } 215 216}