HADOOP-15015. TestConfigurationFieldsBase to use SLF4J for logging. Contributed by Steve Loughran
This commit is contained in:
parent
169cdaa38e
commit
b6d8f87b8e
|
@ -25,15 +25,23 @@ import org.junit.Test;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for comparing fields in one or more Configuration classes
|
* Base class for comparing fields in one or more Configuration classes
|
||||||
|
@ -74,6 +82,15 @@ import static org.junit.Assert.assertTrue;
|
||||||
@Ignore
|
@Ignore
|
||||||
public abstract class TestConfigurationFieldsBase {
|
public abstract class TestConfigurationFieldsBase {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(
|
||||||
|
TestConfigurationFieldsBase.class);
|
||||||
|
|
||||||
|
private static final Logger LOG_CONFIG = LoggerFactory.getLogger(
|
||||||
|
"org.apache.hadoop.conf.TestConfigurationFieldsBase.config");
|
||||||
|
|
||||||
|
private static final Logger LOG_XML = LoggerFactory.getLogger(
|
||||||
|
"org.apache.hadoop.conf.TestConfigurationFieldsBase.xml");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Member variable for storing xml filename.
|
* Member variable for storing xml filename.
|
||||||
*/
|
*/
|
||||||
|
@ -98,27 +115,27 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of properties to skip extracting (and thus comparing later) in
|
* Set of properties to skip extracting (and thus comparing later) in
|
||||||
* extractMemberVariablesFromConfigurationFields.
|
* {@link #extractMemberVariablesFromConfigurationFields(Field[])}.
|
||||||
*/
|
*/
|
||||||
protected Set<String> configurationPropsToSkipCompare = null;
|
protected Set<String> configurationPropsToSkipCompare = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of property prefixes to skip extracting (and thus comparing later)
|
* Set of property prefixes to skip extracting (and thus comparing later)
|
||||||
* in * extractMemberVariablesFromConfigurationFields.
|
* in * extractMemberVariablesFromConfigurationFields.
|
||||||
*/
|
*/
|
||||||
protected Set<String> configurationPrefixToSkipCompare = null;
|
protected Set<String> configurationPrefixToSkipCompare = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of properties to skip extracting (and thus comparing later) in
|
* Set of properties to skip extracting (and thus comparing later) in
|
||||||
* extractPropertiesFromXml.
|
* extractPropertiesFromXml.
|
||||||
*/
|
*/
|
||||||
protected Set<String> xmlPropsToSkipCompare = null;
|
protected Set<String> xmlPropsToSkipCompare = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of property prefixes to skip extracting (and thus comparing later)
|
* Set of property prefixes to skip extracting (and thus comparing later)
|
||||||
* in extractPropertiesFromXml.
|
* in extractPropertiesFromXml.
|
||||||
*/
|
*/
|
||||||
protected Set<String> xmlPrefixToSkipCompare = null;
|
protected Set<String> xmlPrefixToSkipCompare = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Member variable to store Configuration variables for later comparison.
|
* Member variable to store Configuration variables for later comparison.
|
||||||
|
@ -155,13 +172,6 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
@SuppressWarnings("checkstyle:visibilitymodifier")
|
@SuppressWarnings("checkstyle:visibilitymodifier")
|
||||||
protected Set<String> filtersForDefaultValueCollisionCheck = new HashSet<>();
|
protected Set<String> filtersForDefaultValueCollisionCheck = new HashSet<>();
|
||||||
|
|
||||||
/**
|
|
||||||
* Member variable for debugging base class operation
|
|
||||||
*/
|
|
||||||
protected boolean configDebug = false;
|
|
||||||
protected boolean xmlDebug = false;
|
|
||||||
protected boolean defaultDebug = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract method to be used by subclasses for initializing base
|
* Abstract method to be used by subclasses for initializing base
|
||||||
* members.
|
* members.
|
||||||
|
@ -173,27 +183,24 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
* variables from a Configuration type class.
|
* variables from a Configuration type class.
|
||||||
*
|
*
|
||||||
* @param fields The class member variables
|
* @param fields The class member variables
|
||||||
* @return HashMap containing <StringValue,MemberVariableName> entries
|
* @return HashMap containing (StringValue, MemberVariableName) entries
|
||||||
*/
|
*/
|
||||||
private HashMap<String,String>
|
private HashMap<String,String>
|
||||||
extractMemberVariablesFromConfigurationFields(Field[] fields) {
|
extractMemberVariablesFromConfigurationFields(Field[] fields) {
|
||||||
// Sanity Check
|
// Sanity Check
|
||||||
if (fields==null)
|
if (fields == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
HashMap<String,String> retVal = new HashMap<String,String>();
|
HashMap<String,String> retVal = new HashMap<>();
|
||||||
|
|
||||||
// Setup regexp for valid properties
|
// Setup regexp for valid properties
|
||||||
String propRegex = "^[A-Za-z][A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)+$";
|
String propRegex = "^[A-Za-z][A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)+$";
|
||||||
Pattern p = Pattern.compile(propRegex);
|
Pattern p = Pattern.compile(propRegex);
|
||||||
|
|
||||||
// Iterate through class member variables
|
// Iterate through class member variables
|
||||||
int totalFields = 0;
|
|
||||||
String value;
|
String value;
|
||||||
for (Field f : fields) {
|
for (Field f : fields) {
|
||||||
if (configDebug) {
|
LOG_CONFIG.debug("Field: {}", f);
|
||||||
System.out.println("Field: " + f);
|
|
||||||
}
|
|
||||||
// Filter out anything that isn't "public static final"
|
// Filter out anything that isn't "public static final"
|
||||||
if (!Modifier.isStatic(f.getModifiers()) ||
|
if (!Modifier.isStatic(f.getModifiers()) ||
|
||||||
!Modifier.isPublic(f.getModifiers()) ||
|
!Modifier.isPublic(f.getModifiers()) ||
|
||||||
|
@ -217,9 +224,7 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
} catch (IllegalAccessException iaException) {
|
} catch (IllegalAccessException iaException) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (configDebug) {
|
LOG_CONFIG.debug(" Value: {}", value);
|
||||||
System.out.println(" Value: " + value);
|
|
||||||
}
|
|
||||||
// Special Case: Detect and ignore partial properties (ending in x)
|
// Special Case: Detect and ignore partial properties (ending in x)
|
||||||
// or file properties (ending in .xml)
|
// or file properties (ending in .xml)
|
||||||
if (value.endsWith(".xml") ||
|
if (value.endsWith(".xml") ||
|
||||||
|
@ -227,20 +232,16 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
value.endsWith("-"))
|
value.endsWith("-"))
|
||||||
continue;
|
continue;
|
||||||
// Ignore known configuration props
|
// Ignore known configuration props
|
||||||
if (configurationPropsToSkipCompare != null) {
|
if (configurationPropsToSkipCompare.contains(value)) {
|
||||||
if (configurationPropsToSkipCompare.contains(value)) {
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Ignore known configuration prefixes
|
// Ignore known configuration prefixes
|
||||||
boolean skipPrefix = false;
|
boolean skipPrefix = false;
|
||||||
if (configurationPrefixToSkipCompare != null) {
|
for (String cfgPrefix : configurationPrefixToSkipCompare) {
|
||||||
for (String cfgPrefix : configurationPrefixToSkipCompare) {
|
if (value.startsWith(cfgPrefix)) {
|
||||||
if (value.startsWith(cfgPrefix)) {
|
skipPrefix = true;
|
||||||
skipPrefix = true;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (skipPrefix) {
|
if (skipPrefix) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -249,22 +250,16 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
// something like: blah.blah2(.blah3.blah4...)
|
// something like: blah.blah2(.blah3.blah4...)
|
||||||
Matcher m = p.matcher(value);
|
Matcher m = p.matcher(value);
|
||||||
if (!m.find()) {
|
if (!m.find()) {
|
||||||
if (configDebug) {
|
LOG_CONFIG.debug(" Passes Regex: false");
|
||||||
System.out.println(" Passes Regex: false");
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (configDebug) {
|
LOG_CONFIG.debug(" Passes Regex: true");
|
||||||
System.out.println(" Passes Regex: true");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save member variable/value as hash
|
// Save member variable/value as hash
|
||||||
if (!retVal.containsKey(value)) {
|
if (!retVal.containsKey(value)) {
|
||||||
retVal.put(value,f.getName());
|
retVal.put(value,f.getName());
|
||||||
} else {
|
} else {
|
||||||
if (configDebug) {
|
LOG_CONFIG.debug("ERROR: Already found key for property " + value);
|
||||||
System.out.println("ERROR: Already found key for property " + value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,11 +270,10 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
* Pull properties and values from filename.
|
* Pull properties and values from filename.
|
||||||
*
|
*
|
||||||
* @param filename XML filename
|
* @param filename XML filename
|
||||||
* @return HashMap containing <Property,Value> entries from XML file
|
* @return HashMap containing <Property,Value> entries from XML file
|
||||||
*/
|
*/
|
||||||
private HashMap<String,String> extractPropertiesFromXml
|
private HashMap<String,String> extractPropertiesFromXml(String filename) {
|
||||||
(String filename) {
|
if (filename == null) {
|
||||||
if (filename==null) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,48 +282,28 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
conf.setAllowNullValueProperties(true);
|
conf.setAllowNullValueProperties(true);
|
||||||
conf.addResource(filename);
|
conf.addResource(filename);
|
||||||
|
|
||||||
HashMap<String,String> retVal = new HashMap<String,String>();
|
HashMap<String,String> retVal = new HashMap<>();
|
||||||
Iterator<Map.Entry<String,String>> kvItr = conf.iterator();
|
Iterator<Map.Entry<String,String>> kvItr = conf.iterator();
|
||||||
while (kvItr.hasNext()) {
|
while (kvItr.hasNext()) {
|
||||||
Map.Entry<String,String> entry = kvItr.next();
|
Map.Entry<String,String> entry = kvItr.next();
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
// Ignore known xml props
|
// Ignore known xml props
|
||||||
if (xmlPropsToSkipCompare != null) {
|
if (xmlPropsToSkipCompare.contains(key)) {
|
||||||
if (xmlPropsToSkipCompare.contains(key)) {
|
LOG_XML.debug(" Skipping Full Key: {}", key);
|
||||||
if (xmlDebug) {
|
continue;
|
||||||
System.out.println(" Skipping Full Key: " + key);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Ignore known xml prefixes
|
// Ignore known xml prefixes
|
||||||
boolean skipPrefix = false;
|
if (xmlPrefixToSkipCompare.stream().anyMatch(key::startsWith)) {
|
||||||
if (xmlPrefixToSkipCompare != null) {
|
LOG_XML.debug(" Skipping Prefix Key: " + key);
|
||||||
for (String xmlPrefix : xmlPrefixToSkipCompare) {
|
|
||||||
if (key.startsWith(xmlPrefix)) {
|
|
||||||
skipPrefix = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (skipPrefix) {
|
|
||||||
if (xmlDebug) {
|
|
||||||
System.out.println(" Skipping Prefix Key: " + key);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (conf.onlyKeyExists(key)) {
|
if (conf.onlyKeyExists(key)) {
|
||||||
retVal.put(key,null);
|
retVal.put(key, null);
|
||||||
if (xmlDebug) {
|
LOG_XML.debug(" XML Key,Null Value: " + key);
|
||||||
System.out.println(" XML Key,Null Value: " + key);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
String value = conf.get(key);
|
if (conf.get(key) != null) {
|
||||||
if (value!=null) {
|
retVal.put(key, entry.getValue());
|
||||||
retVal.put(key,entry.getValue());
|
LOG_XML.debug(" XML Key,Valid Value: " + key);
|
||||||
if (xmlDebug) {
|
|
||||||
System.out.println(" XML Key,Valid Value: " + key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kvItr.remove();
|
kvItr.remove();
|
||||||
|
@ -353,12 +327,12 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
* member variables from a Configuration type class.
|
* member variables from a Configuration type class.
|
||||||
*
|
*
|
||||||
* @param fields The class member variables
|
* @param fields The class member variables
|
||||||
* @return HashMap containing <DefaultVariableName,DefaultValue> entries
|
* @return HashMap containing (DefaultVariableName, DefaultValue) entries
|
||||||
*/
|
*/
|
||||||
private HashMap<String,String>
|
private HashMap<String,String>
|
||||||
extractDefaultVariablesFromConfigurationFields(Field[] fields) {
|
extractDefaultVariablesFromConfigurationFields(Field[] fields) {
|
||||||
// Sanity Check
|
// Sanity Check
|
||||||
if (fields==null) {
|
if (fields == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,12 +381,11 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
boolean bValue = (boolean) f.get(null);
|
boolean bValue = (boolean) f.get(null);
|
||||||
retVal.put(f.getName(),Boolean.toString(bValue));
|
retVal.put(f.getName(),Boolean.toString(bValue));
|
||||||
} else {
|
} else {
|
||||||
if (defaultDebug) {
|
LOG.debug("Config variable {} has unknown type {}",
|
||||||
System.out.println("Config variable " + f.getName() + " has unknown type " + f.getType().getName());
|
f.getName(), f.getType().getName());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (IllegalAccessException iaException) {
|
} catch (IllegalAccessException iaException) {
|
||||||
iaException.printStackTrace();
|
LOG.error("{}", f, iaException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,8 +400,9 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
* @param keyMap2 The set to subtract
|
* @param keyMap2 The set to subtract
|
||||||
* @return Returns set operation keyMap1-keyMap2
|
* @return Returns set operation keyMap1-keyMap2
|
||||||
*/
|
*/
|
||||||
private static Set<String> compareConfigurationToXmlFields(Map<String,String> keyMap1, Map<String,String> keyMap2) {
|
private static Set<String> compareConfigurationToXmlFields(
|
||||||
Set<String> retVal = new HashSet<String>(keyMap1.keySet());
|
Map<String,String> keyMap1, Map<String,String> keyMap2) {
|
||||||
|
Set<String> retVal = new HashSet<>(keyMap1.keySet());
|
||||||
retVal.removeAll(keyMap2.keySet());
|
retVal.removeAll(keyMap2.keySet());
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -443,60 +417,36 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
initializeMemberVariables();
|
initializeMemberVariables();
|
||||||
|
|
||||||
// Error if subclass hasn't set class members
|
// Error if subclass hasn't set class members
|
||||||
assertTrue(xmlFilename!=null);
|
assertNotNull(xmlFilename);
|
||||||
assertTrue(configurationClasses!=null);
|
assertNotNull(configurationClasses);
|
||||||
|
|
||||||
// Create class member/value map
|
// Create class member/value map
|
||||||
configurationMemberVariables = new HashMap<String,String>();
|
configurationMemberVariables = new HashMap<>();
|
||||||
if (configDebug) {
|
LOG_CONFIG.debug("Reading configuration classes\n");
|
||||||
System.out.println("Reading configuration classes");
|
|
||||||
System.out.println("");
|
|
||||||
}
|
|
||||||
for (Class c : configurationClasses) {
|
for (Class c : configurationClasses) {
|
||||||
Field[] fields = c.getDeclaredFields();
|
Field[] fields = c.getDeclaredFields();
|
||||||
Map<String,String> memberMap =
|
Map<String,String> memberMap =
|
||||||
extractMemberVariablesFromConfigurationFields(fields);
|
extractMemberVariablesFromConfigurationFields(fields);
|
||||||
if (memberMap!=null) {
|
if (memberMap != null) {
|
||||||
configurationMemberVariables.putAll(memberMap);
|
configurationMemberVariables.putAll(memberMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (configDebug) {
|
LOG_CONFIG.debug("\n=====\n");
|
||||||
System.out.println("");
|
|
||||||
System.out.println("=====");
|
|
||||||
System.out.println("");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create XML key/value map
|
// Create XML key/value map
|
||||||
if (xmlDebug) {
|
LOG_XML.debug("Reading XML property files\n");
|
||||||
System.out.println("Reading XML property files");
|
|
||||||
System.out.println("");
|
|
||||||
}
|
|
||||||
xmlKeyValueMap = extractPropertiesFromXml(xmlFilename);
|
xmlKeyValueMap = extractPropertiesFromXml(xmlFilename);
|
||||||
if (xmlDebug) {
|
LOG_XML.debug("\n=====\n");
|
||||||
System.out.println("");
|
|
||||||
System.out.println("=====");
|
|
||||||
System.out.println("");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create default configuration variable key/value map
|
// Create default configuration variable key/value map
|
||||||
if (defaultDebug) {
|
LOG.debug("Reading Config property files for defaults\n");
|
||||||
System.out.println("Reading Config property files for defaults");
|
configurationDefaultVariables = new HashMap<>();
|
||||||
System.out.println("");
|
Arrays.stream(configurationClasses)
|
||||||
}
|
.map(Class::getDeclaredFields)
|
||||||
configurationDefaultVariables = new HashMap<String,String>();
|
.map(this::extractDefaultVariablesFromConfigurationFields)
|
||||||
for (Class c : configurationClasses) {
|
.filter(Objects::nonNull)
|
||||||
Field[] fields = c.getDeclaredFields();
|
.forEach(map -> configurationDefaultVariables.putAll(map));
|
||||||
Map<String,String> defaultMap =
|
LOG.debug("\n=====\n");
|
||||||
extractDefaultVariablesFromConfigurationFields(fields);
|
|
||||||
if (defaultMap!=null) {
|
|
||||||
configurationDefaultVariables.putAll(defaultMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (defaultDebug) {
|
|
||||||
System.out.println("");
|
|
||||||
System.out.println("=====");
|
|
||||||
System.out.println("");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find class members not in the XML file
|
// Find class members not in the XML file
|
||||||
configurationFieldsMissingInXmlFile = compareConfigurationToXmlFields
|
configurationFieldsMissingInXmlFile = compareConfigurationToXmlFields
|
||||||
|
@ -514,17 +464,16 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
@Test
|
@Test
|
||||||
public void testCompareConfigurationClassAgainstXml() {
|
public void testCompareConfigurationClassAgainstXml() {
|
||||||
// Error if subclass hasn't set class members
|
// Error if subclass hasn't set class members
|
||||||
assertTrue(xmlFilename!=null);
|
assertNotNull(xmlFilename);
|
||||||
assertTrue(configurationClasses!=null);
|
assertNotNull(configurationClasses);
|
||||||
|
|
||||||
final int missingXmlSize = configurationFieldsMissingInXmlFile.size();
|
final int missingXmlSize = configurationFieldsMissingInXmlFile.size();
|
||||||
|
|
||||||
for (Class c : configurationClasses) {
|
for (Class c : configurationClasses) {
|
||||||
System.out.println(c);
|
LOG.info(c.toString());
|
||||||
}
|
}
|
||||||
System.out.println(" (" + configurationMemberVariables.size() + " member variables)");
|
LOG.info("({} member variables)\n", configurationMemberVariables.size());
|
||||||
System.out.println();
|
StringBuilder xmlErrorMsg = new StringBuilder();
|
||||||
StringBuffer xmlErrorMsg = new StringBuffer();
|
|
||||||
for (Class c : configurationClasses) {
|
for (Class c : configurationClasses) {
|
||||||
xmlErrorMsg.append(c);
|
xmlErrorMsg.append(c);
|
||||||
xmlErrorMsg.append(" ");
|
xmlErrorMsg.append(" ");
|
||||||
|
@ -533,23 +482,33 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
xmlErrorMsg.append(missingXmlSize);
|
xmlErrorMsg.append(missingXmlSize);
|
||||||
xmlErrorMsg.append(" variables missing in ");
|
xmlErrorMsg.append(" variables missing in ");
|
||||||
xmlErrorMsg.append(xmlFilename);
|
xmlErrorMsg.append(xmlFilename);
|
||||||
System.out.println(xmlErrorMsg.toString());
|
LOG.error(xmlErrorMsg.toString());
|
||||||
System.out.println();
|
if (missingXmlSize == 0) {
|
||||||
if (missingXmlSize==0) {
|
LOG.info(" (None)");
|
||||||
System.out.println(" (None)");
|
|
||||||
} else {
|
} else {
|
||||||
for (String missingField : configurationFieldsMissingInXmlFile) {
|
appendMissingEntries(xmlErrorMsg, configurationFieldsMissingInXmlFile);
|
||||||
System.out.println(" " + missingField);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
System.out.println();
|
LOG.info("\n=====\n");
|
||||||
System.out.println("=====");
|
|
||||||
System.out.println();
|
|
||||||
if (errorIfMissingXmlProps) {
|
if (errorIfMissingXmlProps) {
|
||||||
assertTrue(xmlErrorMsg.toString(), missingXmlSize==0);
|
assertEquals(xmlErrorMsg.toString(), 0, missingXmlSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take a set of missing entries, sort, append to the string builder
|
||||||
|
* and also log at INFO.
|
||||||
|
* @param sb string builder
|
||||||
|
* @param missing set of missing entries
|
||||||
|
*/
|
||||||
|
private void appendMissingEntries(StringBuilder sb, Set<String> missing) {
|
||||||
|
sb.append(" Entries: ");
|
||||||
|
new TreeSet<>(missing).forEach(
|
||||||
|
(s) -> {
|
||||||
|
LOG.info(" {}", s);
|
||||||
|
sb.append(" ").append(s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares the properties that are in the XML properties file, but not
|
* Compares the properties that are in the XML properties file, but not
|
||||||
* in the Configuration class.
|
* in the Configuration class.
|
||||||
|
@ -557,35 +516,28 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
@Test
|
@Test
|
||||||
public void testCompareXmlAgainstConfigurationClass() {
|
public void testCompareXmlAgainstConfigurationClass() {
|
||||||
// Error if subclass hasn't set class members
|
// Error if subclass hasn't set class members
|
||||||
assertTrue(xmlFilename!=null);
|
assertNotNull(xmlFilename);
|
||||||
assertTrue(configurationClasses!=null);
|
assertNotNull(configurationClasses);
|
||||||
|
|
||||||
final int missingConfigSize = xmlFieldsMissingInConfiguration.size();
|
final int missingConfigSize = xmlFieldsMissingInConfiguration.size();
|
||||||
|
|
||||||
System.out.println("File " + xmlFilename + " (" + xmlKeyValueMap.size() + " properties)");
|
LOG.info("File {} ({} properties)", xmlFilename, xmlKeyValueMap.size());
|
||||||
System.out.println();
|
StringBuilder configErrorMsg = new StringBuilder();
|
||||||
StringBuffer configErrorMsg = new StringBuffer();
|
|
||||||
configErrorMsg.append(xmlFilename);
|
configErrorMsg.append(xmlFilename);
|
||||||
configErrorMsg.append(" has ");
|
configErrorMsg.append(" has ");
|
||||||
configErrorMsg.append(missingConfigSize);
|
configErrorMsg.append(missingConfigSize);
|
||||||
configErrorMsg.append(" properties missing in");
|
configErrorMsg.append(" properties missing in");
|
||||||
for (Class c : configurationClasses) {
|
Arrays.stream(configurationClasses)
|
||||||
configErrorMsg.append(" " + c);
|
.forEach(c -> configErrorMsg.append(" ").append(c));
|
||||||
}
|
LOG.info(configErrorMsg.toString());
|
||||||
System.out.println(configErrorMsg.toString());
|
if (missingConfigSize == 0) {
|
||||||
System.out.println();
|
LOG.info(" (None)");
|
||||||
if (missingConfigSize==0) {
|
|
||||||
System.out.println(" (None)");
|
|
||||||
} else {
|
} else {
|
||||||
for (String missingField : xmlFieldsMissingInConfiguration) {
|
appendMissingEntries(configErrorMsg, xmlFieldsMissingInConfiguration);
|
||||||
System.out.println(" " + missingField);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
System.out.println();
|
LOG.info("\n=====\n");
|
||||||
System.out.println("=====");
|
if (errorIfMissingConfigProps) {
|
||||||
System.out.println();
|
assertEquals(configErrorMsg.toString(), 0, missingConfigSize);
|
||||||
if ( errorIfMissingConfigProps ) {
|
|
||||||
assertTrue(configErrorMsg.toString(), missingConfigSize==0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,23 +548,23 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
@Test
|
@Test
|
||||||
public void testXmlAgainstDefaultValuesInConfigurationClass() {
|
public void testXmlAgainstDefaultValuesInConfigurationClass() {
|
||||||
// Error if subclass hasn't set class members
|
// Error if subclass hasn't set class members
|
||||||
assertTrue(xmlFilename!=null);
|
assertNotNull(xmlFilename);
|
||||||
assertTrue(configurationMemberVariables!=null);
|
assertNotNull(configurationMemberVariables);
|
||||||
assertTrue(configurationDefaultVariables!=null);
|
assertNotNull(configurationDefaultVariables);
|
||||||
|
|
||||||
HashSet<String> xmlPropertiesWithEmptyValue = new HashSet<String>();
|
TreeSet<String> xmlPropertiesWithEmptyValue = new TreeSet<>();
|
||||||
HashSet<String> configPropertiesWithNoDefaultConfig = new HashSet<String>();
|
TreeSet<String> configPropertiesWithNoDefaultConfig = new TreeSet<>();
|
||||||
HashMap<String,String> xmlPropertiesMatchingConfigDefault =
|
HashMap<String,String> xmlPropertiesMatchingConfigDefault =
|
||||||
new HashMap<String,String>();
|
new HashMap<>();
|
||||||
// Ugly solution. Should have tuple-based solution.
|
// Ugly solution. Should have tuple-based solution.
|
||||||
HashMap<HashMap<String,String>,HashMap<String,String>> mismatchingXmlConfig =
|
HashMap<HashMap<String,String>, HashMap<String,String>> mismatchingXmlConfig
|
||||||
new HashMap<HashMap<String,String>,HashMap<String,String>>();
|
= new HashMap<>();
|
||||||
|
|
||||||
for (Map.Entry<String,String> xEntry : xmlKeyValueMap.entrySet()) {
|
for (Map.Entry<String,String> xEntry : xmlKeyValueMap.entrySet()) {
|
||||||
String xmlProperty = xEntry.getKey();
|
String xmlProperty = xEntry.getKey();
|
||||||
String xmlDefaultValue = xEntry.getValue();
|
String xmlDefaultValue = xEntry.getValue();
|
||||||
String configProperty = configurationMemberVariables.get(xmlProperty);
|
String configProperty = configurationMemberVariables.get(xmlProperty);
|
||||||
if (configProperty!=null) {
|
if (configProperty != null) {
|
||||||
String defaultConfigName = null;
|
String defaultConfigName = null;
|
||||||
String defaultConfigValue = null;
|
String defaultConfigValue = null;
|
||||||
|
|
||||||
|
@ -624,7 +576,7 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
String defaultNameCheck2 = null;
|
String defaultNameCheck2 = null;
|
||||||
if (configProperty.endsWith("_KEY")) {
|
if (configProperty.endsWith("_KEY")) {
|
||||||
defaultNameCheck2 = configProperty
|
defaultNameCheck2 = configProperty
|
||||||
.substring(0,configProperty.length()-4) + "_DEFAULT";
|
.substring(0, configProperty.length() - 4) + "_DEFAULT";
|
||||||
}
|
}
|
||||||
String defaultValueCheck2 = configurationDefaultVariables
|
String defaultValueCheck2 = configurationDefaultVariables
|
||||||
.get(defaultNameCheck2);
|
.get(defaultNameCheck2);
|
||||||
|
@ -634,115 +586,94 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
.get(defaultNameCheck3);
|
.get(defaultNameCheck3);
|
||||||
|
|
||||||
// Pick the default value that exists
|
// Pick the default value that exists
|
||||||
if (defaultValueCheck1!=null) {
|
if (defaultValueCheck1 != null) {
|
||||||
defaultConfigName = defaultNameCheck1;
|
defaultConfigName = defaultNameCheck1;
|
||||||
defaultConfigValue = defaultValueCheck1;
|
defaultConfigValue = defaultValueCheck1;
|
||||||
} else if (defaultValueCheck2!=null) {
|
} else if (defaultValueCheck2 != null) {
|
||||||
defaultConfigName = defaultNameCheck2;
|
defaultConfigName = defaultNameCheck2;
|
||||||
defaultConfigValue = defaultValueCheck2;
|
defaultConfigValue = defaultValueCheck2;
|
||||||
} else if (defaultValueCheck3!=null) {
|
} else if (defaultValueCheck3 != null) {
|
||||||
defaultConfigName = defaultNameCheck3;
|
defaultConfigName = defaultNameCheck3;
|
||||||
defaultConfigValue = defaultValueCheck3;
|
defaultConfigValue = defaultValueCheck3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultConfigValue!=null) {
|
if (defaultConfigValue != null) {
|
||||||
if (xmlDefaultValue==null) {
|
if (xmlDefaultValue == null) {
|
||||||
xmlPropertiesWithEmptyValue.add(xmlProperty);
|
xmlPropertiesWithEmptyValue.add(xmlProperty);
|
||||||
} else if (!xmlDefaultValue.equals(defaultConfigValue)) {
|
} else if (!xmlDefaultValue.equals(defaultConfigValue)) {
|
||||||
HashMap<String,String> xmlEntry =
|
HashMap<String, String> xmlEntry = new HashMap<>();
|
||||||
new HashMap<String,String>();
|
xmlEntry.put(xmlProperty, xmlDefaultValue);
|
||||||
xmlEntry.put(xmlProperty,xmlDefaultValue);
|
HashMap<String, String> configEntry = new HashMap<>();
|
||||||
HashMap<String,String> configEntry =
|
configEntry.put(defaultConfigName, defaultConfigValue);
|
||||||
new HashMap<String,String>();
|
mismatchingXmlConfig.put(xmlEntry, configEntry);
|
||||||
configEntry.put(defaultConfigName,defaultConfigValue);
|
} else {
|
||||||
mismatchingXmlConfig.put(xmlEntry,configEntry);
|
|
||||||
} else {
|
|
||||||
xmlPropertiesMatchingConfigDefault
|
xmlPropertiesMatchingConfigDefault
|
||||||
.put(xmlProperty, defaultConfigName);
|
.put(xmlProperty, defaultConfigName);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
configPropertiesWithNoDefaultConfig.add(configProperty);
|
configPropertiesWithNoDefaultConfig.add(configProperty);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print out any unknown mismatching XML value/Config default value
|
// Print out any unknown mismatching XML value/Config default value
|
||||||
System.out.println(this.xmlFilename + " has " +
|
LOG.info("{} has {} properties that do not match the default Config value",
|
||||||
mismatchingXmlConfig.size() +
|
xmlFilename, mismatchingXmlConfig.size());
|
||||||
" properties that do not match the default Config value");
|
if (mismatchingXmlConfig.isEmpty()) {
|
||||||
if (mismatchingXmlConfig.size()==0) {
|
LOG.info(" (None)");
|
||||||
System.out.println(" (None)");
|
|
||||||
} else {
|
} else {
|
||||||
for (Map.Entry<HashMap<String,String>,HashMap<String,String>> xcEntry :
|
for (Map.Entry<HashMap<String,String>,HashMap<String,String>> xcEntry :
|
||||||
mismatchingXmlConfig.entrySet()) {
|
mismatchingXmlConfig.entrySet()) {
|
||||||
HashMap<String,String> xmlMap = xcEntry.getKey();
|
xcEntry.getKey().forEach((key, value) -> {
|
||||||
HashMap<String,String> configMap = xcEntry.getValue();
|
LOG.info("XML Property: {}", key);
|
||||||
for (Map.Entry<String,String> xmlEntry : xmlMap.entrySet()) {
|
LOG.info("XML Value: {}", value);
|
||||||
System.out.println(" XML Property: " + xmlEntry.getKey());
|
});
|
||||||
System.out.println(" XML Value: " + xmlEntry.getValue());
|
xcEntry.getValue().forEach((key, value) -> {
|
||||||
}
|
LOG.info("Config Name: {}", key);
|
||||||
for (Map.Entry<String,String> configEntry : configMap.entrySet()) {
|
LOG.info("Config Value: {}", value);
|
||||||
System.out.println(" Config Name: " + configEntry.getKey());
|
});
|
||||||
System.out.println(" Config Value: " + configEntry.getValue());
|
LOG.info("");
|
||||||
}
|
|
||||||
System.out.println("");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println();
|
LOG.info("\n");
|
||||||
|
|
||||||
// Print out Config properties that have no corresponding DEFAULT_*
|
// Print out Config properties that have no corresponding DEFAULT_*
|
||||||
// variable and cannot do any XML comparison (i.e. probably needs to
|
// variable and cannot do any XML comparison (i.e. probably needs to
|
||||||
// be checked by hand)
|
// be checked by hand)
|
||||||
System.out.println("Configuration(s) have " +
|
LOG.info("Configuration(s) have {} " +
|
||||||
configPropertiesWithNoDefaultConfig.size() +
|
|
||||||
" properties with no corresponding default member variable. These" +
|
" properties with no corresponding default member variable. These" +
|
||||||
" will need to be verified manually.");
|
" will need to be verified manually.",
|
||||||
if (configPropertiesWithNoDefaultConfig.size()==0) {
|
configPropertiesWithNoDefaultConfig.size());
|
||||||
System.out.println(" (None)");
|
if (configPropertiesWithNoDefaultConfig.isEmpty()) {
|
||||||
|
LOG.info(" (None)");
|
||||||
} else {
|
} else {
|
||||||
Iterator<String> cItr = configPropertiesWithNoDefaultConfig.iterator();
|
configPropertiesWithNoDefaultConfig.forEach(c -> LOG.info(" {}", c));
|
||||||
while (cItr.hasNext()) {
|
|
||||||
System.out.println(" " + cItr.next());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
System.out.println();
|
LOG.info("\n");
|
||||||
|
|
||||||
// MAYBE TODO Print out any known mismatching XML value/Config default
|
// MAYBE TODO Print out any known mismatching XML value/Config default
|
||||||
|
|
||||||
// Print out XML properties that have empty values (i.e. should result
|
// Print out XML properties that have empty values (i.e. should result
|
||||||
// in code-based default)
|
// in code-based default)
|
||||||
System.out.println(this.xmlFilename + " has " +
|
LOG.info("{} has {} properties with empty values",
|
||||||
xmlPropertiesWithEmptyValue.size() + " properties with empty values");
|
xmlFilename, xmlPropertiesWithEmptyValue.size());
|
||||||
if (xmlPropertiesWithEmptyValue.size()==0) {
|
if (xmlPropertiesWithEmptyValue.isEmpty()) {
|
||||||
System.out.println(" (None)");
|
LOG.info(" (None)");
|
||||||
} else {
|
} else {
|
||||||
Iterator<String> xItr = xmlPropertiesWithEmptyValue.iterator();
|
xmlPropertiesWithEmptyValue.forEach(p -> LOG.info(" {}", p));
|
||||||
while (xItr.hasNext()) {
|
|
||||||
System.out.println(" " + xItr.next());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
System.out.println();
|
LOG.info("\n");
|
||||||
|
|
||||||
// Print out any matching XML value/Config default value
|
// Print out any matching XML value/Config default value
|
||||||
System.out.println(this.xmlFilename + " has " +
|
LOG.info("{} has {} properties which match a corresponding Config variable",
|
||||||
xmlPropertiesMatchingConfigDefault.size() +
|
xmlFilename, xmlPropertiesMatchingConfigDefault.size());
|
||||||
" properties which match a corresponding Config variable");
|
if (xmlPropertiesMatchingConfigDefault.isEmpty()) {
|
||||||
if (xmlPropertiesMatchingConfigDefault.size()==0) {
|
LOG.info(" (None)");
|
||||||
System.out.println(" (None)");
|
|
||||||
} else {
|
} else {
|
||||||
for (Map.Entry<String,String> xcEntry :
|
xmlPropertiesMatchingConfigDefault.forEach(
|
||||||
xmlPropertiesMatchingConfigDefault.entrySet()) {
|
(key, value) -> LOG.info(" {} / {}", key, value));
|
||||||
System.out.println(" " + xcEntry.getKey() + " / " +
|
|
||||||
xcEntry.getValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
System.out.println();
|
LOG.info("\n=====\n");
|
||||||
|
|
||||||
// Test separator
|
|
||||||
System.out.println();
|
|
||||||
System.out.println("=====");
|
|
||||||
System.out.println();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -754,8 +685,8 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultValueCollision() {
|
public void testDefaultValueCollision() {
|
||||||
for (String filter : filtersForDefaultValueCollisionCheck) {
|
for (String filter : filtersForDefaultValueCollisionCheck) {
|
||||||
System.out.println("Checking if any of the default values whose name " +
|
LOG.info("Checking if any of the default values whose name " +
|
||||||
"contains string \"" + filter + "\" collide.");
|
"contains string \"{}\" collide.", filter);
|
||||||
|
|
||||||
// Map from filtered default value to name of the corresponding parameter.
|
// Map from filtered default value to name of the corresponding parameter.
|
||||||
Map<String, String> filteredValues = new HashMap<>();
|
Map<String, String> filteredValues = new HashMap<>();
|
||||||
|
@ -769,15 +700,14 @@ public abstract class TestConfigurationFieldsBase {
|
||||||
if (StringUtils.isNumeric(ent.getValue())) {
|
if (StringUtils.isNumeric(ent.getValue())) {
|
||||||
String crtValue =
|
String crtValue =
|
||||||
filteredValues.putIfAbsent(ent.getValue(), ent.getKey());
|
filteredValues.putIfAbsent(ent.getValue(), ent.getKey());
|
||||||
assertTrue("Parameters " + ent.getKey() + " and " + crtValue +
|
assertNull("Parameters " + ent.getKey() + " and " + crtValue +
|
||||||
" are using the same default value!", crtValue == null);
|
" are using the same default value!", crtValue);
|
||||||
}
|
}
|
||||||
valuesChecked++;
|
valuesChecked++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println(
|
}
|
||||||
"Checked " + valuesChecked + " default values for collision.");
|
LOG.info("Checked {} default values for collision.", valuesChecked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue