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.conf;
019
020import static org.junit.jupiter.api.Assertions.fail;
021
022import java.util.UUID;
023import java.util.function.Consumer;
024import org.apache.hadoop.conf.Configuration;
025import org.apache.hadoop.hbase.CompoundConfiguration;
026import org.apache.hadoop.hbase.testclassification.MiscTests;
027import org.apache.hadoop.hbase.testclassification.SmallTests;
028import org.junit.jupiter.api.Tag;
029import org.junit.jupiter.api.Test;
030
031@Tag(MiscTests.TAG)
032@Tag(SmallTests.TAG)
033public class TestConfigKey {
034
035  private interface Interface {
036  }
037
038  private class Class implements Interface {
039  }
040
041  private void assertThrows(Runnable r) {
042    try {
043      r.run();
044      fail("validation should have failed");
045    } catch (IllegalArgumentException e) {
046      // Expected
047    }
048  }
049
050  private void assertPasses(Configuration conf, Consumer<Configuration> block) {
051    Configuration copy = new CompoundConfiguration().add(conf);
052    block.accept(copy);
053    ConfigKey.validate(copy);
054  }
055
056  private void assertThrows(Configuration conf, Consumer<Configuration> block) {
057    Configuration copy = new CompoundConfiguration().add(conf);
058    block.accept(copy);
059    assertThrows(() -> ConfigKey.validate(copy));
060  }
061
062  @Test
063  public void testConfigKey() {
064    Configuration conf = new CompoundConfiguration();
065
066    String intKey = UUID.randomUUID().toString();
067    ConfigKey.INT(intKey);
068    conf.set(intKey, "1");
069
070    String longKey = UUID.randomUUID().toString();
071    ConfigKey.LONG(longKey);
072    conf.set(longKey, "1");
073
074    String floatKey = UUID.randomUUID().toString();
075    ConfigKey.FLOAT(floatKey);
076    conf.set(floatKey, "1.0");
077
078    String doubleKey = UUID.randomUUID().toString();
079    ConfigKey.DOUBLE(doubleKey);
080    conf.set(doubleKey, "1.0");
081
082    String classKey = UUID.randomUUID().toString();
083    ConfigKey.CLASS(classKey, Interface.class);
084    conf.set(classKey, Class.class.getName());
085
086    String booleanKey = UUID.randomUUID().toString();
087    ConfigKey.BOOLEAN(booleanKey);
088    conf.set(booleanKey, "true");
089
090    // This should pass
091    ConfigKey.validate(conf);
092
093    // Add a predicate to make the validation fail
094    ConfigKey.INT(intKey, i -> i < 0);
095    assertThrows(() -> ConfigKey.validate(conf));
096
097    // New predicates to make the validation pass
098    ConfigKey.INT(intKey, i -> i > 0, i -> i < 2);
099    ConfigKey.validate(conf);
100
101    // Remove the predicate
102    ConfigKey.INT(intKey);
103
104    // Passing examples
105    assertPasses(conf, copy -> copy.set(intKey, String.valueOf(Integer.MAX_VALUE)));
106    assertPasses(conf, copy -> copy.set(longKey, String.valueOf(Long.MAX_VALUE)));
107    assertPasses(conf, copy -> copy.set(floatKey, String.valueOf(Float.MAX_VALUE)));
108    assertPasses(conf, copy -> copy.set(doubleKey, String.valueOf(Double.MAX_VALUE)));
109
110    // Because Configuration#getBoolean doesn't throw an exception on invalid values, we don't
111    // validate the value here
112    assertPasses(conf, copy -> copy.set(booleanKey, "yeah?"));
113
114    // Failing examples
115    assertThrows(conf, copy -> copy.set(intKey, "x"));
116    assertThrows(conf, copy -> copy.set(longKey, Long.MAX_VALUE + "0"));
117    assertThrows(conf, copy -> copy.set(longKey, "x"));
118    assertThrows(conf, copy -> copy.set(floatKey, "x"));
119    assertThrows(conf, copy -> copy.set(doubleKey, "x"));
120    assertThrows(conf, copy -> copy.set(classKey, "NoSuchClass"));
121    assertThrows(conf, copy -> copy.set(classKey, getClass().getName()));
122  }
123}