@Test
  public void testResolve_Configuration__ExcludedTypes__ParentType() throws Exception {
    // child
    ServiceInfo info = new ServiceInfo();
    info.setExcludedConfigTypes(Collections.singleton("BAR"));

    // FOO
    Collection<PropertyInfo> fooProperties = new ArrayList<PropertyInfo>();
    PropertyInfo prop1 = new PropertyInfo();
    prop1.setName("name1");
    prop1.setValue("val1");
    fooProperties.add(prop1);
    PropertyInfo prop2 = new PropertyInfo();
    prop2.setName("name2");
    prop2.setValue("val2");
    fooProperties.add(prop2);

    ConfigurationModule childConfigModule = createConfigurationModule("FOO", fooProperties);
    Collection<ConfigurationModule> childConfigModules = new ArrayList<ConfigurationModule>();
    childConfigModules.add(childConfigModule);

    // parent
    ServiceInfo parentInfo = new ServiceInfo();

    // BAR
    Collection<PropertyInfo> barProperties = new ArrayList<PropertyInfo>();
    PropertyInfo prop3 = new PropertyInfo();
    prop3.setName("name1");
    prop3.setValue("val3");
    barProperties.add(prop3);

    ConfigurationModule parentConfigModule = createConfigurationModule("BAR", barProperties);
    Collection<ConfigurationModule> parentConfigModules = new ArrayList<ConfigurationModule>();
    parentConfigModules.add(parentConfigModule);

    // create service modules
    ServiceModule service = createServiceModule(info, childConfigModules);
    ServiceModule parentService = createServiceModule(parentInfo, parentConfigModules);
    // resolve child with parent
    resolveService(service, parentService);
    // assertions
    List<PropertyInfo> properties = service.getModuleInfo().getProperties();
    assertEquals(2, properties.size());

    Map<String, Map<String, Map<String, String>>> attributes =
        service.getModuleInfo().getConfigTypeAttributes();
    assertEquals(1, attributes.size());
    assertTrue(attributes.containsKey("FOO"));

    Map<String, Map<String, Map<String, String>>> parentAttributes =
        parentService.getModuleInfo().getConfigTypeAttributes();
    assertEquals(1, parentAttributes.size());
    assertTrue(parentAttributes.containsKey("BAR"));
  }
  @Test
  public void testResolve_Configuration__attributes() throws Exception {
    ServiceInfo info = new ServiceInfo();
    ServiceInfo parentInfo = new ServiceInfo();

    // child configurations
    // FOO
    Collection<PropertyInfo> childFooProperties = new ArrayList<PropertyInfo>();
    PropertyInfo childProp1 = new PropertyInfo();
    childProp1.setName("childName1");
    childProp1.setValue("childVal1");
    childFooProperties.add(childProp1);

    // add attributes for parent FOO
    Map<String, String> childFooAttributes = new HashMap<String, String>();
    // override parents value
    childFooAttributes.put(
        ConfigurationInfo.Supports.ADDING_FORBIDDEN.getXmlAttributeName(), "false");

    // create child config modules
    ConfigurationModule childConfigModule1 =
        createConfigurationModule("FOO", childFooProperties, childFooAttributes);
    Collection<ConfigurationModule> childModules = new ArrayList<ConfigurationModule>();
    childModules.add(childConfigModule1);

    // parent configurations
    // FOO
    Collection<PropertyInfo> parentFooProperties = new ArrayList<PropertyInfo>();
    PropertyInfo parentProp1 = new PropertyInfo();
    parentProp1.setName("parentName1");
    parentProp1.setValue("parentVal1");
    parentFooProperties.add(parentProp1);

    // add attributes for parent FOO
    Map<String, String> parentFooAttributes = new HashMap<String, String>();
    // child will inherit
    parentFooAttributes.put(ConfigurationInfo.Supports.FINAL.getXmlAttributeName(), "true");
    // child will override
    parentFooAttributes.put(
        ConfigurationInfo.Supports.ADDING_FORBIDDEN.getXmlAttributeName(), "true");

    // BAR
    Collection<PropertyInfo> parentBarProperties = new ArrayList<PropertyInfo>();
    PropertyInfo parentProp2 = new PropertyInfo();
    parentProp2.setName("parentName2");
    parentProp2.setValue("parentVal2");
    parentBarProperties.add(parentProp2);

    // create parent config modules
    ConfigurationModule parentConfigModule1 =
        createConfigurationModule("FOO", parentFooProperties, parentFooAttributes);
    ConfigurationModule parentConfigModule2 = createConfigurationModule("BAR", parentBarProperties);
    Collection<ConfigurationModule> parentModules = new ArrayList<ConfigurationModule>();
    parentModules.add(parentConfigModule1);
    parentModules.add(parentConfigModule2);

    // create service modules
    ServiceModule child = createServiceModule(info, childModules);
    ServiceModule parent = createServiceModule(parentInfo, parentModules);

    // resolve child with parent
    resolveService(child, parent);

    // assertions
    Map<String, Map<String, Map<String, String>>> childTypeAttributes =
        child.getModuleInfo().getConfigTypeAttributes();
    Map<String, Map<String, Map<String, String>>> parentTypeAttributes =
        parent.getModuleInfo().getConfigTypeAttributes();
    assertTrue(childTypeAttributes.containsKey("FOO"));
    Map<String, Map<String, String>> mergedChildFooAttributes = childTypeAttributes.get("FOO");
    assertTrue(mergedChildFooAttributes.containsKey(ConfigurationInfo.Supports.KEYWORD));
    // inherited value
    assertEquals(
        "true",
        mergedChildFooAttributes
            .get(ConfigurationInfo.Supports.KEYWORD)
            .get(ConfigurationInfo.Supports.valueOf("FINAL").getPropertyName()));
    // overridden value
    assertEquals(
        "false",
        mergedChildFooAttributes
            .get(ConfigurationInfo.Supports.KEYWORD)
            .get(ConfigurationInfo.Supports.valueOf("ADDING_FORBIDDEN").getPropertyName()));

    assertEquals(2, childTypeAttributes.size());

    assertEquals(2, parentTypeAttributes.size());
    assertAttributes(parentTypeAttributes.get("FOO"), parentFooAttributes);
    assertAttributes(parentTypeAttributes.get("BAR"), Collections.<String, String>emptyMap());
  }
  @Test
  public void testResolve_Configuration__ExcludedTypes() throws Exception {
    ServiceInfo info = new ServiceInfo();
    info.setExcludedConfigTypes(Collections.singleton("BAR"));

    // FOO
    Collection<PropertyInfo> fooProperties = new ArrayList<PropertyInfo>();
    PropertyInfo prop1 = new PropertyInfo();
    prop1.setName("name1");
    prop1.setValue("val1");
    fooProperties.add(prop1);
    PropertyInfo prop2 = new PropertyInfo();
    prop2.setName("name2");
    prop2.setValue("val2");
    fooProperties.add(prop2);

    // BAR
    Collection<PropertyInfo> barProperties = new ArrayList<PropertyInfo>();
    PropertyInfo prop3 = new PropertyInfo();
    prop3.setName("name1");
    prop3.setValue("val3");
    barProperties.add(prop3);

    // OTHER
    Collection<PropertyInfo> otherProperties = new ArrayList<PropertyInfo>();
    PropertyInfo prop4 = new PropertyInfo();
    prop4.setName("name1");
    prop4.setValue("val4");
    otherProperties.add(prop4);

    ConfigurationModule configModule1 = createConfigurationModule("FOO", fooProperties);
    ConfigurationModule configModule2 = createConfigurationModule("BAR", barProperties);
    ConfigurationModule configModule3 = createConfigurationModule("OTHER", otherProperties);
    Collection<ConfigurationModule> configModules = new ArrayList<ConfigurationModule>();
    configModules.add(configModule1);
    configModules.add(configModule2);
    configModules.add(configModule3);

    ServiceModule service = createServiceModule(info, configModules);

    List<PropertyInfo> properties = service.getModuleInfo().getProperties();
    assertEquals(4, properties.size());

    Map<String, Map<String, Map<String, String>>> attributes =
        service.getModuleInfo().getConfigTypeAttributes();
    assertEquals(2, attributes.size());
    assertTrue(attributes.containsKey("FOO"));
    assertTrue(attributes.containsKey("OTHER"));
  }
  @Test
  public void testResolve_Configuration__properties() throws Exception {
    ServiceInfo info = new ServiceInfo();
    ServiceInfo parentInfo = new ServiceInfo();

    // child configurations
    // FOO
    Collection<PropertyInfo> childFooProperties = new ArrayList<PropertyInfo>();
    PropertyInfo childProp1 = new PropertyInfo();
    childProp1.setName("childName1");
    childProp1.setValue("childVal1");
    childFooProperties.add(childProp1);

    // BAR : Doesn't inherit parents BAR due to attribute Supports.DO_NOT_EXTEND
    Collection<PropertyInfo> childBarProperties = new ArrayList<PropertyInfo>();
    PropertyInfo childProp2 = new PropertyInfo();
    childProp2.setName("childName2");
    childProp2.setValue("childVal2");
    childBarProperties.add(childProp2);

    // add attributes for BAR
    Map<String, String> attributes = new HashMap<String, String>();
    attributes.put(ConfigurationInfo.Supports.DO_NOT_EXTEND.getXmlAttributeName(), "true");

    // create child config modules
    ConfigurationModule childConfigModule1 = createConfigurationModule("FOO", childFooProperties);
    ConfigurationModule childConfigModule2 =
        createConfigurationModule("BAR", childBarProperties, attributes);
    Collection<ConfigurationModule> childModules = new ArrayList<ConfigurationModule>();
    childModules.add(childConfigModule1);
    childModules.add(childConfigModule2);

    // parent configurations
    // FOO
    Collection<PropertyInfo> parentFooProperties = new ArrayList<PropertyInfo>();
    PropertyInfo parentProp1 = new PropertyInfo();
    parentProp1.setName("parentName1");
    parentProp1.setValue("parentVal1");
    parentFooProperties.add(parentProp1);
    PropertyInfo parentProp12 = new PropertyInfo();
    // overwritten by child
    parentProp12.setName("childName1");
    parentProp12.setValue("parentVal1");
    parentFooProperties.add(parentProp12);

    // BAR
    Collection<PropertyInfo> parentBarProperties = new ArrayList<PropertyInfo>();
    PropertyInfo parentProp2 = new PropertyInfo();
    parentProp2.setName("parentName2");
    parentProp2.setValue("parentVal2");
    parentBarProperties.add(parentProp2);

    // OTHER
    Collection<PropertyInfo> parentOtherProperties = new ArrayList<PropertyInfo>();
    PropertyInfo parentProp3 = new PropertyInfo();
    parentProp3.setName("parentName3");
    parentProp3.setValue("parentVal3");
    parentOtherProperties.add(parentProp3);

    // create parent config modules
    ConfigurationModule parentConfigModule1 = createConfigurationModule("FOO", parentFooProperties);
    ConfigurationModule parentConfigModule2 = createConfigurationModule("BAR", parentBarProperties);
    ConfigurationModule parentConfigModule3 =
        createConfigurationModule("OTHER", parentOtherProperties);
    Collection<ConfigurationModule> parentModules = new ArrayList<ConfigurationModule>();
    parentModules.add(parentConfigModule1);
    parentModules.add(parentConfigModule2);
    parentModules.add(parentConfigModule3);

    // create service modules
    ServiceModule child = createServiceModule(info, childModules);
    ServiceModule parent = createServiceModule(parentInfo, parentModules);

    // resolve child with parent
    resolveService(child, parent);

    // assertions
    List<PropertyInfo> mergedProperties = child.getModuleInfo().getProperties();
    assertEquals(4, mergedProperties.size());

    Map<String, PropertyInfo> mergedPropertyMap = new HashMap<String, PropertyInfo>();
    for (PropertyInfo prop : mergedProperties) {
      mergedPropertyMap.put(prop.getName(), prop);
    }

    // filename is null for all props because that is set in ConfigurationDirectory which is mocked
    assertEquals("childVal1", mergedPropertyMap.get("childName1").getValue());
    assertEquals("childVal2", mergedPropertyMap.get("childName2").getValue());
    assertEquals("parentVal1", mergedPropertyMap.get("parentName1").getValue());
    assertEquals("parentVal3", mergedPropertyMap.get("parentName3").getValue());

    Map<String, Map<String, Map<String, String>>> childAttributes =
        child.getModuleInfo().getConfigTypeAttributes();
    Map<String, Map<String, Map<String, String>>> parentAttributes =
        parent.getModuleInfo().getConfigTypeAttributes();

    assertEquals(3, childAttributes.size());
    assertAttributes(childAttributes.get("FOO"), Collections.<String, String>emptyMap());
    assertAttributes(childAttributes.get("BAR"), attributes);
    assertAttributes(childAttributes.get("OTHER"), Collections.<String, String>emptyMap());

    assertEquals(3, parentAttributes.size());
    assertAttributes(parentAttributes.get("FOO"), Collections.<String, String>emptyMap());
    assertAttributes(parentAttributes.get("BAR"), Collections.<String, String>emptyMap());
    assertAttributes(parentAttributes.get("OTHER"), Collections.<String, String>emptyMap());
  }