1 /**
2  * Copyright The Apache Software Foundation
3  *
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 package org.apache.hadoop.hbase;
21 
22 import java.util.HashMap;
23 import java.util.Map;
24 
25 import junit.framework.TestCase;
26 
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
29 import org.apache.hadoop.hbase.testclassification.SmallTests;
30 import org.apache.hadoop.hbase.util.Bytes;
31 import org.junit.Test;
32 import org.junit.experimental.categories.Category;
33 
34 @Category(SmallTests.class)
35 public class TestCompoundConfiguration extends TestCase {
36   private Configuration baseConf;
37   private int baseConfSize;
38 
39   @Override
setUp()40   protected void setUp() throws Exception {
41     baseConf = new Configuration();
42     baseConf.set("A", "1");
43     baseConf.setInt("B", 2);
44     baseConf.set("C", "3");
45     baseConfSize = baseConf.size();
46   }
47 
48   @Test
testBasicFunctionality()49   public void testBasicFunctionality() throws ClassNotFoundException {
50     CompoundConfiguration compoundConf = new CompoundConfiguration()
51         .add(baseConf);
52     assertEquals("1", compoundConf.get("A"));
53     assertEquals(2, compoundConf.getInt("B", 0));
54     assertEquals(3, compoundConf.getInt("C", 0));
55     assertEquals(0, compoundConf.getInt("D", 0));
56 
57     assertEquals(CompoundConfiguration.class, compoundConf
58         .getClassByName(CompoundConfiguration.class.getName()));
59     try {
60       compoundConf.getClassByName("bad_class_name");
61       fail("Trying to load bad_class_name should throw an exception");
62     } catch (ClassNotFoundException e) {
63       // win!
64     }
65   }
66 
67   @Test
testPut()68   public void testPut() {
69     CompoundConfiguration compoundConf = new CompoundConfiguration()
70       .add(baseConf);
71     assertEquals("1", compoundConf.get("A"));
72     assertEquals(2, compoundConf.getInt("B", 0));
73     assertEquals(3, compoundConf.getInt("C", 0));
74     assertEquals(0, compoundConf.getInt("D", 0));
75 
76     compoundConf.set("A", "1337");
77     compoundConf.set("string", "stringvalue");
78     assertEquals(1337, compoundConf.getInt("A", 0));
79     assertEquals("stringvalue", compoundConf.get("string"));
80 
81     // we didn't modify the base conf
82     assertEquals("1", baseConf.get("A"));
83     assertNull(baseConf.get("string"));
84 
85     // adding to the base shows up in the compound
86     baseConf.set("setInParent", "fromParent");
87     assertEquals("fromParent", compoundConf.get("setInParent"));
88   }
89 
90   @Test
testWithConfig()91   public void testWithConfig() {
92     Configuration conf = new Configuration();
93     conf.set("B", "2b");
94     conf.set("C", "33");
95     conf.set("D", "4");
96 
97     CompoundConfiguration compoundConf = new CompoundConfiguration()
98         .add(baseConf)
99         .add(conf);
100     assertEquals("1", compoundConf.get("A"));
101     assertEquals("2b", compoundConf.get("B"));
102     assertEquals(33, compoundConf.getInt("C", 0));
103     assertEquals("4", compoundConf.get("D"));
104     assertEquals(4, compoundConf.getInt("D", 0));
105     assertNull(compoundConf.get("E"));
106     assertEquals(6, compoundConf.getInt("F", 6));
107 
108     int cnt = 0;
109     for (Map.Entry<String,String> entry : compoundConf) {
110       cnt++;
111       if (entry.getKey().equals("B")) assertEquals("2b", entry.getValue());
112       else if (entry.getKey().equals("G")) assertEquals(null, entry.getValue());
113     }
114     // verify that entries from ImmutableConfigMap's are merged in the iterator's view
115     assertEquals(baseConfSize + 1, cnt);
116   }
117 
strToIbw(String s)118   private ImmutableBytesWritable strToIbw(String s) {
119     return new ImmutableBytesWritable(Bytes.toBytes(s));
120   }
121 
122   @Test
testWithIbwMap()123   public void testWithIbwMap() {
124     Map<ImmutableBytesWritable, ImmutableBytesWritable> map =
125       new HashMap<ImmutableBytesWritable, ImmutableBytesWritable>();
126     map.put(strToIbw("B"), strToIbw("2b"));
127     map.put(strToIbw("C"), strToIbw("33"));
128     map.put(strToIbw("D"), strToIbw("4"));
129     // unlike config, note that IBW Maps can accept null values
130     map.put(strToIbw("G"), null);
131 
132     CompoundConfiguration compoundConf = new CompoundConfiguration()
133       .add(baseConf)
134       .addWritableMap(map);
135     assertEquals("1", compoundConf.get("A"));
136     assertEquals("2b", compoundConf.get("B"));
137     assertEquals(33, compoundConf.getInt("C", 0));
138     assertEquals("4", compoundConf.get("D"));
139     assertEquals(4, compoundConf.getInt("D", 0));
140     assertNull(compoundConf.get("E"));
141     assertEquals(6, compoundConf.getInt("F", 6));
142     assertNull(compoundConf.get("G"));
143 
144     int cnt = 0;
145     for (Map.Entry<String,String> entry : compoundConf) {
146       cnt++;
147       if (entry.getKey().equals("B")) assertEquals("2b", entry.getValue());
148       else if (entry.getKey().equals("G")) assertEquals(null, entry.getValue());
149     }
150     // verify that entries from ImmutableConfigMap's are merged in the iterator's view
151     assertEquals(baseConfSize + 2, cnt);
152 
153     // Verify that adding map after compound configuration is modified overrides properly
154     CompoundConfiguration conf2 = new CompoundConfiguration();
155     conf2.set("X", "modification");
156     conf2.set("D", "not4");
157     assertEquals("modification", conf2.get("X"));
158     assertEquals("not4", conf2.get("D"));
159     conf2.addWritableMap(map);
160     assertEquals("4", conf2.get("D")); // map overrides
161   }
162 
163   @Test
testWithStringMap()164   public void testWithStringMap() {
165     Map<String, String> map = new HashMap<String, String>();
166     map.put("B", "2b");
167     map.put("C", "33");
168     map.put("D", "4");
169     // unlike config, note that IBW Maps can accept null values
170     map.put("G", null);
171 
172     CompoundConfiguration compoundConf = new CompoundConfiguration().addStringMap(map);
173     assertEquals("2b", compoundConf.get("B"));
174     assertEquals(33, compoundConf.getInt("C", 0));
175     assertEquals("4", compoundConf.get("D"));
176     assertEquals(4, compoundConf.getInt("D", 0));
177     assertNull(compoundConf.get("E"));
178     assertEquals(6, compoundConf.getInt("F", 6));
179     assertNull(compoundConf.get("G"));
180 
181     int cnt = 0;
182     for (Map.Entry<String,String> entry : compoundConf) {
183       cnt++;
184       if (entry.getKey().equals("B")) assertEquals("2b", entry.getValue());
185       else if (entry.getKey().equals("G")) assertEquals(null, entry.getValue());
186     }
187     // verify that entries from ImmutableConfigMap's are merged in the iterator's view
188     assertEquals(4, cnt);
189 
190     // Verify that adding map after compound configuration is modified overrides properly
191     CompoundConfiguration conf2 = new CompoundConfiguration();
192     conf2.set("X", "modification");
193     conf2.set("D", "not4");
194     assertEquals("modification", conf2.get("X"));
195     assertEquals("not4", conf2.get("D"));
196     conf2.addStringMap(map);
197     assertEquals("4", conf2.get("D")); // map overrides
198   }
199 
200   @Test
testLaterConfigsOverrideEarlier()201   public void testLaterConfigsOverrideEarlier() {
202     Map<String, String> map1 = new HashMap<String, String>();
203     map1.put("A", "2");
204     map1.put("D", "5");
205     Map<String, String> map2 = new HashMap<String, String>();
206     String newValueForA = "3", newValueForB = "4";
207     map2.put("A", newValueForA);
208     map2.put("B", newValueForB);
209 
210     CompoundConfiguration compoundConf = new CompoundConfiguration()
211       .addStringMap(map1).add(baseConf);
212     assertEquals("1", compoundConf.get("A"));
213     assertEquals("5", compoundConf.get("D"));
214     compoundConf.addStringMap(map2);
215     assertEquals(newValueForA, compoundConf.get("A"));
216     assertEquals(newValueForB, compoundConf.get("B"));
217     assertEquals("5", compoundConf.get("D"));
218 
219     int cnt = 0;
220     for (Map.Entry<String,String> entry : compoundConf) {
221       cnt++;
222       if (entry.getKey().equals("A")) assertEquals(newValueForA, entry.getValue());
223       else if (entry.getKey().equals("B")) assertEquals(newValueForB, entry.getValue());
224     }
225     // verify that entries from ImmutableConfigMap's are merged in the iterator's view
226     assertEquals(baseConfSize + 1, cnt);
227   }
228 }
229