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