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