/*
* Copyright (C) 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook.config;
import org.json.JSONException;
import org.json.JSONObject;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class TestExpandedConfFileJSONProvider {
private Map<File, JSONObject> mockFileParser = new HashMap<>();
public final static String simpleAConfig = "simpleA.json";
public final static String simpleBConfig = "simpleB.json";
public final static String simpleIncludeConfig = "simpleInclude.json";
public final static String multiIncludeConfig = "multiInclude.json";
public final static String chainedConfig = "chainInclude.json";
public final static String circularAConfig = "circularIncludeA.json";
public final static String circularBConfig = "circularIncludeB.json";
private JSONObject addInclude(JSONObject json, String include)
throws JSONException {
return json.append("includes", include);
}
private JSONObject addConf(JSONObject json, String key, String value)
throws JSONException {
if (!json.has("conf")) {
json.put("conf", new JSONObject());
}
JSONObject confs = json.getJSONObject("conf");
confs.put(key, value);
return json;
}
private JSONObject buildSimpleAConfig() throws JSONException {
JSONObject json = new JSONObject();
json = addConf(json, "key1", "simpleA1");
json = addConf(json, "key2", "simpleA2");
return json;
}
private JSONObject buildSimpleBConfig() throws JSONException {
JSONObject json = new JSONObject();
json = addConf(json, "key1", "simpleB1");
json = addConf(json, "key3", "simpleB3");
return json;
}
private JSONObject buildSimpleIncludeConfig() throws JSONException {
JSONObject json = new JSONObject();
json = addInclude(json, simpleAConfig);
json = addConf(json, "key1", "simpleInclude1");
json = addConf(json, "key4", "simpleInclude4");
return json;
}
private JSONObject buildMultiIncludeConfig() throws JSONException {
JSONObject json = new JSONObject();
json = addInclude(json, simpleAConfig);
json = addInclude(json, simpleBConfig);
json = addConf(json, "key1", "multiInclude1");
json = addConf(json, "key4", "multiInclude4");
return json;
}
private JSONObject buildChainedConfig() throws JSONException {
JSONObject json = new JSONObject();
json = addInclude(json, simpleIncludeConfig);
json = addConf(json, "key1", "chainInclude1");
json = addConf(json, "key5", "chainInclude5");
return json;
}
private JSONObject buildCircularIncludeAConfig() throws JSONException {
JSONObject json = new JSONObject();
json = addInclude(json, circularBConfig);
json = addConf(json, "key1", "circularA1");
json = addConf(json, "key2", "circularA2");
return json;
}
private JSONObject buildCircularIncludeBConfig() throws JSONException {
JSONObject json = new JSONObject();
json = addInclude(json, circularAConfig);
json = addConf(json, "key1", "circularB1");
json = addConf(json, "key3", "circularB3");
return json;
}
private String getStagingDirPath() {
// Make it relative to the current user directory
return new File("").getAbsolutePath() + "/tmp";
}
private String buildFullPath(String fileName) {
return getStagingDirPath() + "/" + fileName;
}
private void registerMockFile(String path, JSONObject json) {
mockFileParser.put(new File(path), json);
}
@BeforeTest(alwaysRun = true)
public void setUp() throws Exception {
registerMockFile(
buildFullPath(simpleAConfig), buildSimpleAConfig());
registerMockFile(
buildFullPath(simpleBConfig), buildSimpleBConfig());
registerMockFile(
buildFullPath(simpleIncludeConfig),buildSimpleIncludeConfig());
registerMockFile(
buildFullPath(multiIncludeConfig), buildMultiIncludeConfig());
registerMockFile(
buildFullPath(chainedConfig), buildChainedConfig());
registerMockFile(
buildFullPath(circularAConfig), buildCircularIncludeAConfig());
registerMockFile(
buildFullPath(circularBConfig), buildCircularIncludeBConfig());
}
// Return an anonymous inner class that simulates file reading
private ExpandedConfFileJSONProvider buildJSONProvider(String configPath) {
return new ExpandedConfFileJSONProvider(new File(configPath)) {
// Override file parsing so we can get contents w/o having actual files
@Override
protected JSONObject load(String fileName) {
File file = new File(fileName);
return mockFileParser.get(file);
}
};
}
@Test(groups = "fast")
public void testSimpleConfig() throws Exception {
JSONObject json =
buildJSONProvider(buildFullPath(simpleAConfig)).get();
Assert.assertTrue(json.has("key1"));
Assert.assertEquals(json.getString("key1"), "simpleA1");
Assert.assertTrue(json.has("key2"));
Assert.assertEquals(json.getString("key2"), "simpleA2");
}
@Test(groups = "fast")
public void testSimpleIncludeConfig() throws Exception {
JSONObject json =
buildJSONProvider(buildFullPath(simpleIncludeConfig)).get();
Assert.assertTrue(json.has("key1"));
Assert.assertEquals(json.getString("key1"), "simpleInclude1");
Assert.assertTrue(json.has("key2"));
Assert.assertEquals(json.getString("key2"), "simpleA2");
Assert.assertTrue(json.has("key4"));
Assert.assertEquals(json.getString("key4"), "simpleInclude4");
}
@Test(groups = "fast")
public void testMultiIncludeConfig() throws Exception {
JSONObject json =
buildJSONProvider(buildFullPath(multiIncludeConfig)).get();
Assert.assertTrue(json.has("key1"));
Assert.assertEquals(json.getString("key1"), "multiInclude1");
Assert.assertTrue(json.has("key2"));
Assert.assertEquals(json.getString("key2"), "simpleA2");
Assert.assertTrue(json.has("key3"));
Assert.assertEquals(json.getString("key3"), "simpleB3");
Assert.assertTrue(json.has("key4"));
Assert.assertEquals(json.getString("key4"), "multiInclude4");
}
@Test(groups = "fast")
public void testChainedConfig() throws Exception {
JSONObject json =
buildJSONProvider(buildFullPath(chainedConfig)).get();
Assert.assertTrue(json.has("key1"));
Assert.assertEquals(json.getString("key1"), "chainInclude1");
Assert.assertTrue(json.has("key2"));
Assert.assertEquals(json.getString("key2"), "simpleA2");
Assert.assertTrue(json.has("key4"));
Assert.assertEquals(json.getString("key4"), "simpleInclude4");
Assert.assertTrue(json.has("key5"));
Assert.assertEquals(json.getString("key5"), "chainInclude5");
}
@Test(groups = "fast")
public void testCircularIncludeConfig() throws Exception {
JSONObject json =
buildJSONProvider(buildFullPath(circularAConfig)).get();
Assert.assertTrue(json.has("key1"));
Assert.assertEquals(json.getString("key1"), "circularA1");
Assert.assertTrue(json.has("key2"));
Assert.assertEquals(json.getString("key2"), "circularA2");
Assert.assertTrue(json.has("key3"));
Assert.assertEquals(json.getString("key3"), "circularB3");
// Running also this proves that there is no infinite loop
}
}