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; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertNull; 022import static org.junit.Assert.fail; 023 024import java.util.HashMap; 025import java.util.Map; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.hbase.testclassification.MiscTests; 028import org.apache.hadoop.hbase.testclassification.SmallTests; 029import org.apache.hadoop.hbase.util.Bytes; 030import org.junit.Before; 031import org.junit.ClassRule; 032import org.junit.Test; 033import org.junit.experimental.categories.Category; 034 035@Category({ MiscTests.class, SmallTests.class }) 036public class TestCompoundConfiguration { 037 038 @ClassRule 039 public static final HBaseClassTestRule CLASS_RULE = 040 HBaseClassTestRule.forClass(TestCompoundConfiguration.class); 041 042 private Configuration baseConf; 043 private int baseConfSize; 044 045 @Before 046 public void setUp() throws Exception { 047 baseConf = new Configuration(); 048 baseConf.set("A", "1"); 049 baseConf.setInt("B", 2); 050 baseConf.set("C", "3"); 051 baseConfSize = baseConf.size(); 052 } 053 054 @Test 055 public void testBasicFunctionality() throws ClassNotFoundException { 056 CompoundConfiguration compoundConf = new CompoundConfiguration().add(baseConf); 057 assertEquals("1", compoundConf.get("A")); 058 assertEquals(2, compoundConf.getInt("B", 0)); 059 assertEquals(3, compoundConf.getInt("C", 0)); 060 assertEquals(0, compoundConf.getInt("D", 0)); 061 062 assertEquals(CompoundConfiguration.class, 063 compoundConf.getClassByName(CompoundConfiguration.class.getName())); 064 try { 065 compoundConf.getClassByName("bad_class_name"); 066 fail("Trying to load bad_class_name should throw an exception"); 067 } catch (ClassNotFoundException e) { 068 // win! 069 } 070 } 071 072 @Test 073 public void testPut() { 074 CompoundConfiguration compoundConf = new CompoundConfiguration().add(baseConf); 075 assertEquals("1", compoundConf.get("A")); 076 assertEquals(2, compoundConf.getInt("B", 0)); 077 assertEquals(3, compoundConf.getInt("C", 0)); 078 assertEquals(0, compoundConf.getInt("D", 0)); 079 080 compoundConf.set("A", "1337"); 081 compoundConf.set("string", "stringvalue"); 082 assertEquals(1337, compoundConf.getInt("A", 0)); 083 assertEquals("stringvalue", compoundConf.get("string")); 084 085 // we didn't modify the base conf 086 assertEquals("1", baseConf.get("A")); 087 assertNull(baseConf.get("string")); 088 089 // adding to the base shows up in the compound 090 baseConf.set("setInParent", "fromParent"); 091 assertEquals("fromParent", compoundConf.get("setInParent")); 092 } 093 094 @Test 095 public void testWithConfig() { 096 Configuration conf = new Configuration(); 097 conf.set("B", "2b"); 098 conf.set("C", "33"); 099 conf.set("D", "4"); 100 101 CompoundConfiguration compoundConf = new CompoundConfiguration().add(baseConf).add(conf); 102 assertEquals("1", compoundConf.get("A")); 103 assertEquals("2b", compoundConf.get("B")); 104 assertEquals(33, compoundConf.getInt("C", 0)); 105 assertEquals("4", compoundConf.get("D")); 106 assertEquals(4, compoundConf.getInt("D", 0)); 107 assertNull(compoundConf.get("E")); 108 assertEquals(6, compoundConf.getInt("F", 6)); 109 110 int cnt = 0; 111 for (Map.Entry<String, String> entry : compoundConf) { 112 cnt++; 113 if (entry.getKey().equals("B")) { 114 assertEquals("2b", entry.getValue()); 115 } else if (entry.getKey().equals("G")) { 116 assertNull(entry.getValue()); 117 } 118 } 119 // verify that entries from ImmutableConfigMap's are merged in the iterator's view 120 assertEquals(baseConfSize + 1, cnt); 121 } 122 123 private Bytes strToIb(String s) { 124 return new Bytes(Bytes.toBytes(s)); 125 } 126 127 @Test 128 public void testWithIbwMap() { 129 Map<Bytes, Bytes> map = new HashMap<>(); 130 map.put(strToIb("B"), strToIb("2b")); 131 map.put(strToIb("C"), strToIb("33")); 132 map.put(strToIb("D"), strToIb("4")); 133 // unlike config, note that IBW Maps can accept null values 134 map.put(strToIb("G"), null); 135 136 CompoundConfiguration compoundConf = new CompoundConfiguration().add(baseConf).addBytesMap(map); 137 assertEquals("1", compoundConf.get("A")); 138 assertEquals("2b", compoundConf.get("B")); 139 assertEquals(33, compoundConf.getInt("C", 0)); 140 assertEquals("4", compoundConf.get("D")); 141 assertEquals(4, compoundConf.getInt("D", 0)); 142 assertNull(compoundConf.get("E")); 143 assertEquals(6, compoundConf.getInt("F", 6)); 144 assertNull(compoundConf.get("G")); 145 146 int cnt = 0; 147 for (Map.Entry<String, String> entry : compoundConf) { 148 cnt++; 149 if (entry.getKey().equals("B")) { 150 assertEquals("2b", entry.getValue()); 151 } else if (entry.getKey().equals("G")) { 152 assertNull(entry.getValue()); 153 } 154 } 155 // verify that entries from ImmutableConfigMap's are merged in the iterator's view 156 assertEquals(baseConfSize + 2, cnt); 157 158 // Verify that adding map after compound configuration is modified overrides properly 159 CompoundConfiguration conf2 = new CompoundConfiguration(); 160 conf2.set("X", "modification"); 161 conf2.set("D", "not4"); 162 assertEquals("modification", conf2.get("X")); 163 assertEquals("not4", conf2.get("D")); 164 conf2.addBytesMap(map); 165 assertEquals("4", conf2.get("D")); // map overrides 166 } 167 168 @Test 169 public void testWithStringMap() { 170 Map<String, String> map = new HashMap<>(); 171 map.put("B", "2b"); 172 map.put("C", "33"); 173 map.put("D", "4"); 174 // unlike config, note that IBW Maps can accept null values 175 map.put("G", null); 176 177 CompoundConfiguration compoundConf = new CompoundConfiguration().addStringMap(map); 178 assertEquals("2b", compoundConf.get("B")); 179 assertEquals(33, compoundConf.getInt("C", 0)); 180 assertEquals("4", compoundConf.get("D")); 181 assertEquals(4, compoundConf.getInt("D", 0)); 182 assertNull(compoundConf.get("E")); 183 assertEquals(6, compoundConf.getInt("F", 6)); 184 assertNull(compoundConf.get("G")); 185 186 int cnt = 0; 187 for (Map.Entry<String, String> entry : compoundConf) { 188 cnt++; 189 if (entry.getKey().equals("B")) { 190 assertEquals("2b", entry.getValue()); 191 } else if (entry.getKey().equals("G")) { 192 assertNull(entry.getValue()); 193 } 194 } 195 // verify that entries from ImmutableConfigMap's are merged in the iterator's view 196 assertEquals(4, cnt); 197 198 // Verify that adding map after compound configuration is modified overrides properly 199 CompoundConfiguration conf2 = new CompoundConfiguration(); 200 conf2.set("X", "modification"); 201 conf2.set("D", "not4"); 202 assertEquals("modification", conf2.get("X")); 203 assertEquals("not4", conf2.get("D")); 204 conf2.addStringMap(map); 205 assertEquals("4", conf2.get("D")); // map overrides 206 } 207 208 @Test 209 public void testLaterConfigsOverrideEarlier() { 210 Map<String, String> map1 = new HashMap<>(); 211 map1.put("A", "2"); 212 map1.put("D", "5"); 213 Map<String, String> map2 = new HashMap<>(); 214 String newValueForA = "3", newValueForB = "4"; 215 map2.put("A", newValueForA); 216 map2.put("B", newValueForB); 217 218 CompoundConfiguration compoundConf = 219 new CompoundConfiguration().addStringMap(map1).add(baseConf); 220 assertEquals("1", compoundConf.get("A")); 221 assertEquals("5", compoundConf.get("D")); 222 compoundConf.addStringMap(map2); 223 assertEquals(newValueForA, compoundConf.get("A")); 224 assertEquals(newValueForB, compoundConf.get("B")); 225 assertEquals("5", compoundConf.get("D")); 226 227 int cnt = 0; 228 for (Map.Entry<String, String> entry : compoundConf) { 229 cnt++; 230 if (entry.getKey().equals("A")) { 231 assertEquals(newValueForA, entry.getValue()); 232 } else if (entry.getKey().equals("B")) { 233 assertEquals(newValueForB, entry.getValue()); 234 } 235 } 236 // verify that entries from ImmutableConfigMap's are merged in the iterator's view 237 assertEquals(baseConfSize + 1, cnt); 238 } 239}