@Test
  public void testMergedConfigurationsDoNotAddExplicitelyRemovedProperties() throws Exception {
    RepositoryVersionEntity repoVersion211 = createNiceMock(RepositoryVersionEntity.class);
    RepositoryVersionEntity repoVersion220 = createNiceMock(RepositoryVersionEntity.class);

    StackId stack211 = new StackId("HDP-2.1.1");
    StackId stack220 = new StackId("HDP-2.2.0");

    String version211 = "2.1.1.0-1234";
    String version220 = "2.2.0.0-1234";

    expect(repoVersion211.getStackId()).andReturn(stack211).atLeastOnce();
    expect(repoVersion211.getVersion()).andReturn(version211).atLeastOnce();

    expect(repoVersion220.getStackId()).andReturn(stack220).atLeastOnce();
    expect(repoVersion220.getVersion()).andReturn(version220).atLeastOnce();

    Map<String, Map<String, String>> stack211Configs = new HashMap<>();
    Map<String, String> stack211FooType = new HashMap<>();
    Map<String, String> stack211BarType = new HashMap<>();
    stack211Configs.put("foo-site", stack211FooType);
    stack211Configs.put("bar-site", stack211BarType);
    stack211FooType.put("foo-property-1", "stack-211-original");
    stack211FooType.put("foo-property-2", "stack-211-original");
    stack211BarType.put("bar-property-1", "stack-211-original");

    Map<String, Map<String, String>> stack220Configs = new HashMap<>();
    Map<String, String> stack220FooType = new HashMap<>();
    Map<String, String> stack220BarType = new HashMap<>();
    stack220Configs.put("foo-site", stack220FooType);
    stack220Configs.put("bar-site", stack220BarType);
    stack220FooType.put("foo-property-1", "stack-220-original");
    stack220FooType.put("foo-property-2", "stack-220-original");
    stack220BarType.put("bar-property-1", "stack-220-original");
    stack220BarType.put("bar-property-2", "stack-220-original");

    Map<String, String> existingFooType = new HashMap<>();
    Map<String, String> existingBarType = new HashMap<>();

    ClusterConfigEntity fooConfigEntity = createNiceMock(ClusterConfigEntity.class);
    ClusterConfigEntity barConfigEntity = createNiceMock(ClusterConfigEntity.class);

    expect(fooConfigEntity.getType()).andReturn("foo-site");
    expect(barConfigEntity.getType()).andReturn("bar-site");

    Config fooConfig = createNiceMock(Config.class);
    Config barConfig = createNiceMock(Config.class);

    existingFooType.put("foo-property-1", "my-foo-property-1");
    existingBarType.put("bar-property-1", "stack-211-original");

    expect(fooConfig.getType()).andReturn("foo-site").atLeastOnce();
    expect(barConfig.getType()).andReturn("bar-site").atLeastOnce();
    expect(fooConfig.getProperties()).andReturn(existingFooType);
    expect(barConfig.getProperties()).andReturn(existingBarType);

    Map<String, DesiredConfig> desiredConfigurations = new HashMap<>();
    desiredConfigurations.put("foo-site", null);
    desiredConfigurations.put("bar-site", null);

    Service zookeeper = createNiceMock(Service.class);
    expect(zookeeper.getName()).andReturn("ZOOKEEPER").atLeastOnce();
    expect(zookeeper.getServiceComponents()).andReturn(
      new HashMap<>()).once();
    zookeeper.setDesiredRepositoryVersion(repoVersion220);
    expectLastCall().once();

    Cluster cluster = createNiceMock(Cluster.class);
    expect(cluster.getCurrentStackVersion()).andReturn(stack211).atLeastOnce();
    expect(cluster.getDesiredStackVersion()).andReturn(stack220);
    expect(cluster.getDesiredConfigs()).andReturn(desiredConfigurations);
    expect(cluster.getDesiredConfigByType("foo-site")).andReturn(fooConfig);
    expect(cluster.getDesiredConfigByType("bar-site")).andReturn(barConfig);
    expect(cluster.getService("ZOOKEEPER")).andReturn(zookeeper);
    expect(cluster.getDesiredConfigByType("foo-type")).andReturn(fooConfig);
    expect(cluster.getDesiredConfigByType("bar-type")).andReturn(barConfig);

    ConfigHelper configHelper = m_injector.getInstance(ConfigHelper.class);

    expect(configHelper.getDefaultProperties(stack211, "ZOOKEEPER")).andReturn(
        stack211Configs).anyTimes();

    expect(configHelper.getDefaultProperties(stack220, "ZOOKEEPER")).andReturn(
        stack220Configs).anyTimes();

    Capture<Map<String, Map<String, String>>> expectedConfigurationsCapture = EasyMock.newCapture();

    expect(configHelper.createConfigTypes(EasyMock.anyObject(Cluster.class),
        EasyMock.anyObject(StackId.class), EasyMock.anyObject(AmbariManagementController.class),
        EasyMock.capture(expectedConfigurationsCapture), EasyMock.anyObject(String.class),
        EasyMock.anyObject(String.class))).andReturn(true);

    // mock the service config DAO and replay it
    ServiceConfigEntity zookeeperServiceConfig = createNiceMock(ServiceConfigEntity.class);
    expect(zookeeperServiceConfig.getClusterConfigEntities()).andReturn(
        Lists.newArrayList(fooConfigEntity, barConfigEntity));

    ServiceConfigDAO serviceConfigDAOMock = m_injector.getInstance(ServiceConfigDAO.class);
    List<ServiceConfigEntity> latestServiceConfigs = Lists.newArrayList(zookeeperServiceConfig);
    expect(serviceConfigDAOMock.getLastServiceConfigsForService(EasyMock.anyLong(),
        eq("ZOOKEEPER"))).andReturn(latestServiceConfigs).once();

    UpgradeContext context = createNiceMock(UpgradeContext.class);
    expect(context.getCluster()).andReturn(cluster).atLeastOnce();
    expect(context.getType()).andReturn(UpgradeType.ROLLING).atLeastOnce();
    expect(context.getDirection()).andReturn(Direction.UPGRADE).atLeastOnce();
    expect(context.getRepositoryVersion()).andReturn(repoVersion220).anyTimes();
    expect(context.getSupportedServices()).andReturn(Sets.newHashSet("ZOOKEEPER")).atLeastOnce();
    expect(context.getSourceRepositoryVersion(EasyMock.anyString())).andReturn(repoVersion211).atLeastOnce();
    expect(context.getTargetRepositoryVersion(EasyMock.anyString())).andReturn(repoVersion220).atLeastOnce();
    expect(context.getOrchestrationType()).andReturn(RepositoryType.STANDARD).anyTimes();
    expect(context.getHostRoleCommandFactory()).andStubReturn(m_injector.getInstance(HostRoleCommandFactory.class));
    expect(context.getRoleGraphFactory()).andStubReturn(m_injector.getInstance(RoleGraphFactory.class));

    replayAll();

    UpgradeHelper upgradeHelper = m_injector.getInstance(UpgradeHelper.class);
    upgradeHelper.updateDesiredRepositoriesAndConfigs(context);

    Map<String, Map<String, String>> expectedConfigurations = expectedConfigurationsCapture.getValue();
    Map<String, String> expectedFooType = expectedConfigurations.get("foo-site");
    Map<String, String> expectedBarType = expectedConfigurations.get("bar-site");

    // As the upgrade pack did not have any Flume updates, its configs should
    // not be updated.
    assertEquals(2, expectedConfigurations.size());

    assertEquals("my-foo-property-1", expectedFooType.get("foo-property-1"));
    assertEquals(null, expectedFooType.get("foo-property-2"));
    assertEquals("stack-220-original", expectedBarType.get("bar-property-1"));
    assertEquals("stack-220-original", expectedBarType.get("bar-property-2"));
  }
Tests that properties which were explicitely removed in the current
configurations by stack advisor are not re-introduced as "new" properties
accidentally.
<p/>

HDP 2.1 defaults
<ul>
<li>foo-site/foo-property-1</li>
<li>foo-site/foo-property-2</li>
<li>bar-site/bar-property-1</li>
</ul>

HDP 2.2 defaults
<ul>
<li>foo-site/foo-property-1</li>
<li>foo-site/foo-property-2</li>
<li>bar-site/bar-property-1</li>
<li>bar-site/bar-property-2</li>
</ul>

CURRENT 2.1 configs
<ul>
<li>foo-site/foo-property-1</li>
<li>foo-site/foo-property-99</li>
<li>bar-site/bar-property-1</li>
<li>bar-site/bar-property-20</li>
<li>bar-site/bar-property-99</li>
</ul>

The final merged configurations should detect that {{foo-property-2}}
exists in both stacks but is not in the current configs and was therefore
purposefully removed. It shoudl also detect that {{bar-property-2}} was
added in the new stack and should be added in.

@throws Exception
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackUpgradeConfigurationMergeTest.java