Repository: ambari Updated Branches: refs/heads/branch-feature-AMBARI-12556 2cfc8d22d -> 770c519a9
http://git-wip-us.apache.org/repos/asf/ambari/blob/770c519a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java index b228988..cfb7726 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java @@ -182,7 +182,7 @@ public class UpgradeHelper { * {@link StageWrapperBuilder} has finished building out all of the stages. */ @Inject - private Provider<ConfigHelper> m_configHelperProvider; + Provider<ConfigHelper> m_configHelperProvider; @Inject private Provider<AmbariMetaInfo> m_ambariMetaInfoProvider; @@ -203,7 +203,7 @@ public class UpgradeHelper { * Used to get configurations by service name. */ @Inject - private ServiceConfigDAO m_serviceConfigDAO; + ServiceConfigDAO m_serviceConfigDAO; /** * Get right Upgrade Pack, depends on stack, direction and upgrade type http://git-wip-us.apache.org/repos/asf/ambari/blob/770c519a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackUpgradeConfigurationMergeTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackUpgradeConfigurationMergeTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackUpgradeConfigurationMergeTest.java index f79b1c2..a631448 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackUpgradeConfigurationMergeTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackUpgradeConfigurationMergeTest.java @@ -17,8 +17,13 @@ */ package org.apache.ambari.server.controller.internal; -import java.util.ArrayList; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.junit.Assert.assertEquals; + import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.persistence.EntityManager; @@ -28,7 +33,6 @@ import org.apache.ambari.server.actionmanager.HostRoleCommandFactory; import org.apache.ambari.server.actionmanager.HostRoleCommandFactoryImpl; import org.apache.ambari.server.actionmanager.RequestFactory; import org.apache.ambari.server.actionmanager.StageFactory; -import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.controller.AbstractRootServiceResponseFactory; import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.controller.KerberosHelper; @@ -38,8 +42,10 @@ import org.apache.ambari.server.hooks.HookService; import org.apache.ambari.server.orm.DBAccessor; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; import org.apache.ambari.server.orm.dao.RepositoryVersionDAO; +import org.apache.ambari.server.orm.dao.ServiceConfigDAO; +import org.apache.ambari.server.orm.entities.ClusterConfigEntity; import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; -import org.apache.ambari.server.orm.entities.StackEntity; +import org.apache.ambari.server.orm.entities.ServiceConfigEntity; import org.apache.ambari.server.scheduler.ExecutionScheduler; import org.apache.ambari.server.security.authorization.Users; import org.apache.ambari.server.stack.StackManagerFactory; @@ -50,10 +56,12 @@ import org.apache.ambari.server.state.Config; import org.apache.ambari.server.state.ConfigFactory; import org.apache.ambari.server.state.ConfigHelper; import org.apache.ambari.server.state.DesiredConfig; +import org.apache.ambari.server.state.RepositoryType; +import org.apache.ambari.server.state.Service; +import org.apache.ambari.server.state.ServiceComponent; import org.apache.ambari.server.state.ServiceComponentFactory; import org.apache.ambari.server.state.ServiceComponentHostFactory; import org.apache.ambari.server.state.ServiceFactory; -import org.apache.ambari.server.state.ServiceInfo; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.UpgradeContext; import org.apache.ambari.server.state.UpgradeContextFactory; @@ -63,7 +71,7 @@ import org.apache.ambari.server.state.scheduler.RequestExecutionFactory; import org.apache.ambari.server.state.stack.OsFamily; import org.apache.ambari.server.state.stack.UpgradePack; import org.apache.ambari.server.state.stack.upgrade.Direction; -import org.apache.ambari.server.state.stack.upgrade.Grouping; +import org.apache.ambari.server.state.stack.upgrade.UpgradeType; import org.easymock.Capture; import org.easymock.EasyMock; import org.easymock.EasyMockSupport; @@ -73,14 +81,14 @@ import org.junit.Before; import org.junit.Test; import org.springframework.security.crypto.password.PasswordEncoder; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.google.inject.Binder; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.assistedinject.FactoryModuleBuilder; -import junit.framework.Assert; - /** * Tests that * {@link UpgradeResourceProvider#applyStackAndProcessConfigurations(String, Cluster, String, Direction, UpgradePack, String)} @@ -88,19 +96,13 @@ import junit.framework.Assert; */ public class StackUpgradeConfigurationMergeTest extends EasyMockSupport { - private static final StackId s_currentStackId = new StackId("HDP-2.4"); - private static final StackId s_targetStackId = new StackId("HDP-2.5"); - private Injector m_injector; - private AmbariMetaInfo m_ambariMetaInfoMock; /** * @throws Exception */ @Before public void before() throws Exception { - m_ambariMetaInfoMock = createNiceMock(AmbariMetaInfo.class); - MockModule mockModule = new MockModule(); // create an injector which will inject the mocks @@ -120,14 +122,14 @@ public class StackUpgradeConfigurationMergeTest extends EasyMockSupport { * accidentally. * <p/> * - * HDP 2.4 defaults + * 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.5 defaults + * HDP 2.2 defaults * <ul> * <li>foo-site/foo-property-1</li> * <li>foo-site/foo-property-2</li> @@ -135,7 +137,7 @@ public class StackUpgradeConfigurationMergeTest extends EasyMockSupport { * <li>bar-site/bar-property-2</li> * </ul> * - * CURRENT 2.4 configs + * CURRENT 2.1 configs * <ul> * <li>foo-site/foo-property-1</li> * <li>foo-site/foo-property-99</li> @@ -146,132 +148,144 @@ public class StackUpgradeConfigurationMergeTest extends EasyMockSupport { * * 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-20}} was + * purposefully removed. It shoudl also detect that {{bar-property-2}} was * added in the new stack and should be added in. * * @throws Exception */ @Test public void testMergedConfigurationsDoNotAddExplicitelyRemovedProperties() throws Exception { - Cluster cluster = createNiceMock(Cluster.class); - RepositoryVersionEntity repositoryVersionEntity = createNiceMock(RepositoryVersionEntity.class); - UpgradePack upgradePack = createNiceMock(UpgradePack.class); - StackEntity targetStack = createNiceMock(StackEntity.class); - StackId targetStackId = createNiceMock(StackId.class); + 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<String, ServiceComponent>()).once(); + zookeeper.setDesiredRepositoryVersion(repoVersion220); + expectLastCall().once(); - String version = "2.5.0.0-1234"; + 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); - // mocks which were bound previously - AmbariManagementController amc = m_injector.getInstance(AmbariManagementController.class); - AmbariMetaInfo ambariMetaInfo = m_injector.getInstance(AmbariMetaInfo.class); ConfigHelper configHelper = m_injector.getInstance(ConfigHelper.class); - RepositoryVersionDAO repositoryVersionDAO = m_injector.getInstance(RepositoryVersionDAO.class); - - EasyMock.expect(amc.getConfigHelper()).andReturn(configHelper); - - EasyMock.expect(cluster.getCurrentStackVersion()).andReturn(s_currentStackId); - EasyMock.expect(cluster.getDesiredStackVersion()).andReturn(s_targetStackId); - - EasyMock.expect(targetStack.getStackName()).andReturn("HDP").anyTimes(); - EasyMock.expect(targetStack.getStackVersion()).andReturn("2.5").anyTimes(); - EasyMock.expect(targetStackId.getStackName()).andReturn("HDP").atLeastOnce(); - EasyMock.expect(targetStackId.getStackVersion()).andReturn("2.5").atLeastOnce(); - - EasyMock.expect(repositoryVersionEntity.getStackId()).andReturn(targetStackId).atLeastOnce(); - EasyMock.expect(repositoryVersionEntity.getStack()).andReturn(targetStack).atLeastOnce(); - EasyMock.expect(repositoryVersionEntity.getVersion()).andReturn(version).atLeastOnce(); - EasyMock.expect(repositoryVersionDAO.findByStackNameAndVersion("HDP", version)).andReturn( - repositoryVersionEntity); - - EasyMock.expect(upgradePack.getGroups(Direction.UPGRADE)).andReturn(new ArrayList<Grouping>()); - - EasyMock.expect(ambariMetaInfo.getServices("HDP", "2.5")).andReturn( - new HashMap<String, ServiceInfo>()); - - // config helper mocks (the heart of this test) - Map<String, Map<String, String>> oldStackDefaultConfigurationsByType = new HashMap<>(); - oldStackDefaultConfigurationsByType.put("foo-type", new HashMap<String, String>()); - oldStackDefaultConfigurationsByType.get("foo-type").put("foo-property-1", "foo-value-1"); - oldStackDefaultConfigurationsByType.get("foo-type").put("foo-property-2", "foo-value-2"); - oldStackDefaultConfigurationsByType.put("bar-type", new HashMap<String, String>()); - oldStackDefaultConfigurationsByType.get("bar-type").put("bar-property-1", "bar-value-1"); - - Map<String, Map<String, String>> newConfigurationsByType = new HashMap<>(); - newConfigurationsByType.put("foo-type", new HashMap<String, String>()); - newConfigurationsByType.get("foo-type").put("foo-property-1", "foo-value-1"); - newConfigurationsByType.get("foo-type").put("foo-property-2", "foo-value-2"); - newConfigurationsByType.put("bar-type", new HashMap<String, String>()); - newConfigurationsByType.get("bar-type").put("bar-property-1", "bar-value-1"); - newConfigurationsByType.get("bar-type").put("bar-property-20", "bar-value-20"); - - // HDP 2.4 configs - EasyMock.expect(configHelper.getDefaultProperties(EasyMock.eq(s_currentStackId), - EasyMock.anyString())).andReturn(oldStackDefaultConfigurationsByType); - - // HDP 2.5 configs - EasyMock.expect(configHelper.getDefaultProperties(EasyMock.eq(s_targetStackId), - EasyMock.anyString())).andReturn(newConfigurationsByType); - - // CURRENT HDP 2.4 configs - Config currentClusterConfigFoo = createNiceMock(Config.class); - Config currentClusterConfigBar = createNiceMock(Config.class); - - Map<String, String> existingPropertiesFoo = new HashMap<>(); - existingPropertiesFoo.put("foo-property-1", "foo-value-1"); - existingPropertiesFoo.put("foo-property-99", "foo-value-99"); - EasyMock.expect(currentClusterConfigFoo.getProperties()).andReturn(existingPropertiesFoo); - - Map<String, String> existingPropertiesBar = new HashMap<>(); - existingPropertiesBar.put("bar-property-1", "bar-value-1"); - existingPropertiesBar.put("bar-property-99", "bar-value-99"); - EasyMock.expect(currentClusterConfigBar.getProperties()).andReturn(existingPropertiesBar); - - EasyMock.expect(cluster.getDesiredConfigByType("foo-type")).andReturn(currentClusterConfigFoo); - EasyMock.expect(cluster.getDesiredConfigByType("bar-type")).andReturn(currentClusterConfigBar); - - // desired configs - Map<String, DesiredConfig> existingDesiredConfigurationsByType = new HashMap<>(); - existingDesiredConfigurationsByType.put("foo-type", null); - existingDesiredConfigurationsByType.put("bar-type", null); - EasyMock.expect(cluster.getDesiredConfigs()).andReturn(existingDesiredConfigurationsByType); - - // we need to know what configs are being created, so capture them - Capture<Map<String, Map<String, String>>> capturedArgument = EasyMock.newCapture(); + + 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(); + configHelper.createConfigTypes(EasyMock.anyObject(Cluster.class), - EasyMock.anyObject(AmbariManagementController.class), - EasyMock.anyObject(StackId.class), - EasyMock.capture(capturedArgument), - EasyMock.anyString(), EasyMock.anyString()); - - EasyMock.expectLastCall(); - - UpgradeContext upgradeContext = createNiceMock(UpgradeContext.class); - EasyMock.expect(upgradeContext.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes(); - EasyMock.expect(upgradeContext.getCluster()).andReturn(cluster).anyTimes(); - EasyMock.expect(upgradeContext.getDirection()).andReturn(Direction.UPGRADE).anyTimes(); - EasyMock.expect(upgradeContext.getUpgradePack()).andReturn(upgradePack).anyTimes(); - EasyMock.expect(upgradeContext.getRepositoryVersion()).andReturn(repositoryVersionEntity).anyTimes(); - EasyMock.expect(upgradeContext.getTargetRepositoryVersion(EasyMock.anyString())).andReturn(repositoryVersionEntity).anyTimes(); + EasyMock.anyObject(AmbariManagementController.class), EasyMock.anyObject(StackId.class), + EasyMock.capture(expectedConfigurationsCapture), EasyMock.anyObject(String.class), + EasyMock.anyObject(String.class)); + + expectLastCall().once(); + + // 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.getRepositoryType()).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(upgradeContext); - - // assertion time! - Map<String, Map<String, String>> mergedConfigurations = capturedArgument.getValue(); - Map<String, String> mergedFooSite = mergedConfigurations.get("foo-type"); - Map<String, String> mergedBarSite = mergedConfigurations.get("bar-type"); - - // foo-site validation - Assert.assertEquals("foo-value-1", mergedFooSite.get("foo-property-1")); - Assert.assertEquals("foo-value-99", mergedFooSite.get("foo-property-99")); - Assert.assertFalse(mergedFooSite.containsKey("foo-property-2")); - - // bar-site validation - Assert.assertEquals("bar-value-1", mergedBarSite.get("bar-property-1")); - Assert.assertEquals("bar-value-20", mergedBarSite.get("bar-property-20")); - Assert.assertEquals("bar-value-99", mergedBarSite.get("bar-property-99")); - Assert.assertEquals(3, mergedBarSite.size()); + 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")); } @@ -282,7 +296,6 @@ public class StackUpgradeConfigurationMergeTest extends EasyMockSupport { */ @Override public void configure(Binder binder) { - binder.bind(AmbariMetaInfo.class).toInstance(m_ambariMetaInfoMock); binder.bind(Clusters.class).toInstance(createNiceMock(Clusters.class)); binder.bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class)); binder.bind(DBAccessor.class).toInstance(createNiceMock(DBAccessor.class)); @@ -311,6 +324,7 @@ public class StackUpgradeConfigurationMergeTest extends EasyMockSupport { binder.bind(RepositoryVersionDAO.class).toInstance(createNiceMock(RepositoryVersionDAO.class)); binder.bind(HookContextFactory.class).toInstance(createMock(HookContextFactory.class)); binder.bind(HookService.class).toInstance(createMock(HookService.class)); + binder.bind(ServiceConfigDAO.class).toInstance(createNiceMock(ServiceConfigDAO.class)); binder.install(new FactoryModuleBuilder().build(UpgradeContextFactory.class)); binder.bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class); http://git-wip-us.apache.org/repos/asf/ambari/blob/770c519a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java index 04773bc..f63f706 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java @@ -17,7 +17,6 @@ */ package org.apache.ambari.server.controller.internal; -import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertEquals; @@ -47,7 +46,6 @@ import org.apache.ambari.server.actionmanager.HostRoleCommand; import org.apache.ambari.server.actionmanager.HostRoleStatus; import org.apache.ambari.server.actionmanager.Stage; import org.apache.ambari.server.agent.ExecutionCommand.KeyNames; -import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.audit.AuditLogger; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.AmbariManagementController; @@ -87,7 +85,6 @@ import org.apache.ambari.server.state.Clusters; import org.apache.ambari.server.state.Config; import org.apache.ambari.server.state.ConfigFactory; import org.apache.ambari.server.state.ConfigHelper; -import org.apache.ambari.server.state.DesiredConfig; import org.apache.ambari.server.state.Host; import org.apache.ambari.server.state.HostState; import org.apache.ambari.server.state.Service; @@ -97,14 +94,13 @@ import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.UpgradeContext; import org.apache.ambari.server.state.UpgradeHelper; import org.apache.ambari.server.state.UpgradeState; -import org.apache.ambari.server.state.stack.UpgradePack; import org.apache.ambari.server.state.stack.upgrade.Direction; import org.apache.ambari.server.state.stack.upgrade.UpgradeType; import org.apache.ambari.server.topology.TopologyManager; import org.apache.ambari.server.utils.StageUtils; import org.apache.ambari.server.view.ViewRegistry; -import org.easymock.Capture; import org.easymock.EasyMock; +import org.easymock.EasyMockSupport; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -125,7 +121,7 @@ import com.google.inject.util.Modules; /** * UpgradeResourceDefinition tests. */ -public class UpgradeResourceProviderTest { +public class UpgradeResourceProviderTest extends EasyMockSupport { private UpgradeDAO upgradeDao = null; private RequestDAO requestDao = null; @@ -135,7 +131,6 @@ public class UpgradeResourceProviderTest { private AmbariManagementController amc; private ConfigHelper configHelper; private StackDAO stackDAO; - private AmbariMetaInfo ambariMetaInfo; private TopologyManager topologyManager; private ConfigFactory configFactory; private HostRoleCommandDAO hrcDAO; @@ -144,6 +139,12 @@ public class UpgradeResourceProviderTest { RepositoryVersionEntity repoVersionEntity2111; RepositoryVersionEntity repoVersionEntity2200; + /** + * Creates a single host cluster with ZOOKEEPER_SERVER and ZOOKEEPER_CLIENT on + * {@link #repoVersionEntity2110}. + * + * @throws Exception + */ @Before public void before() throws Exception { SecurityContextHolder.getContext().setAuthentication( @@ -162,19 +163,18 @@ public class UpgradeResourceProviderTest { EasyMock.anyString())).andReturn( new HashMap<String, Map<String, String>>()).anyTimes(); - - EasyMock.replay(configHelper); + replay(configHelper); InMemoryDefaultTestModule module = new InMemoryDefaultTestModule(); // create an injector which will inject the mocks - injector = Guice.createInjector(Modules.override(module).with(new MockModule())); + injector = Guice.createInjector( + Modules.override(module).with(new MockModule())); H2DatabaseCleaner.resetSequences(injector); injector.getInstance(GuiceJpaInitializer.class); amc = injector.getInstance(AmbariManagementController.class); - ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class); configFactory = injector.getInstance(ConfigFactory.class); Field field = AmbariServer.class.getDeclaredField("clusterController"); @@ -187,7 +187,7 @@ public class UpgradeResourceProviderTest { repoVersionDao = injector.getInstance(RepositoryVersionDAO.class); hrcDAO = injector.getInstance(HostRoleCommandDAO.class); - AmbariEventPublisher publisher = createNiceMock(AmbariEventPublisher.class); + AmbariEventPublisher publisher = EasyMock.createNiceMock(AmbariEventPublisher.class); replay(publisher); ViewRegistry.initInstance(new ViewRegistry(publisher)); @@ -591,11 +591,6 @@ public class UpgradeResourceProviderTest { Cluster cluster = clusters.getCluster("c1"); Service service = cluster.getService("ZOOKEEPER"); - // this should get skipped - ServiceComponent component = service.getServiceComponent("ZOOKEEPER_SERVER"); - ServiceComponentHost sch = component.addServiceComponentHost("h2"); - sch.setVersion(repoVersionEntity2200.getVersion()); - // start out with 0 (sanity check) List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId()); assertEquals(0, upgrades.size()); @@ -616,10 +611,32 @@ public class UpgradeResourceProviderTest { upgradeEntity.setUpgradeType(UpgradeType.ROLLING); upgradeEntity.setRequestEntity(requestEntity); + UpgradeHistoryEntity history = new UpgradeHistoryEntity(); + history.setUpgrade(upgradeEntity); + history.setFromRepositoryVersion(service.getDesiredRepositoryVersion()); + history.setTargetRepositoryVersion(repoVersionEntity2200); + history.setServiceName(service.getName()); + history.setComponentName("ZOKKEEPER_SERVER"); + upgradeEntity.addHistory(history); + + history = new UpgradeHistoryEntity(); + history.setUpgrade(upgradeEntity); + history.setFromRepositoryVersion(service.getDesiredRepositoryVersion()); + history.setTargetRepositoryVersion(repoVersionEntity2200); + history.setServiceName(service.getName()); + history.setComponentName("ZOKKEEPER_CLIENT"); + upgradeEntity.addHistory(history); + upgradeDao.create(upgradeEntity); upgrades = upgradeDao.findUpgrades(cluster.getClusterId()); assertEquals(1, upgrades.size()); + // push a ZK server foward to the new repo version, leaving the old one on + // the old version + ServiceComponent component = service.getServiceComponent("ZOOKEEPER_SERVER"); + ServiceComponentHost sch = component.addServiceComponentHost("h2"); + sch.setVersion(repoVersionEntity2200.getVersion()); + UpgradeEntity lastUpgrade = upgradeDao.findLastUpgradeForCluster(cluster.getClusterId(), Direction.UPGRADE); assertNotNull(lastUpgrade); @@ -645,10 +662,11 @@ public class UpgradeResourceProviderTest { List<UpgradeGroupEntity> upgradeGroups = downgrade.getUpgradeGroups(); assertEquals(3, upgradeGroups.size()); + // the ZK restart group should only have 3 entries since the ZK server on h1 + // didn't get upgraded UpgradeGroupEntity group = upgradeGroups.get(1); assertEquals("ZOOKEEPER", group.getName()); - assertEquals(4, group.getItems().size()); - + assertEquals(3, group.getItems().size()); } @@ -1036,7 +1054,7 @@ public class UpgradeResourceProviderTest { @Test public void testCreateCrossStackUpgrade() throws Exception { Cluster cluster = clusters.getCluster("c1"); - StackId oldStack = cluster.getDesiredStackVersion(); + StackId oldStack = repoVersionEntity2110.getStackId(); for (Service s : cluster.getServices().values()) { assertEquals(oldStack, s.getDesiredStackId()); @@ -1054,6 +1072,7 @@ public class UpgradeResourceProviderTest { Config config = configFactory.createNew(cluster, "zoo.cfg", "abcdefg", Collections.singletonMap("a", "b"), null); cluster.addDesiredConfig("admin", Collections.singleton(config)); + // create the upgrade across major versions Map<String, Object> requestProps = new HashMap<>(); requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1"); requestProps.put(UpgradeResourceProvider.UPGRADE_REPO_VERSION_ID, String.valueOf(repoVersionEntity2200.getId())); @@ -1062,7 +1081,6 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); - Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); upgradeResourceProvider.createResources(request); @@ -1080,10 +1098,6 @@ public class UpgradeResourceProviderTest { assertTrue(cluster.getDesiredConfigs().containsKey("zoo.cfg")); - StackId newStack = cluster.getDesiredStackVersion(); - - assertFalse(oldStack.equals(newStack)); - for (Service s : cluster.getServices().values()) { assertEquals(repoVersionEntity2200, s.getDesiredRepositoryVersion()); @@ -1094,135 +1108,6 @@ public class UpgradeResourceProviderTest { } /** - * Tests merging configurations between existing and new stack values on - * upgrade. - * - * @throws Exception - */ - @Test - public void testMergeConfigurations() 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"; - - EasyMock.expect(repoVersion211.getStackId()).andReturn(stack211).atLeastOnce(); - EasyMock.expect(repoVersion211.getVersion()).andReturn(version211).atLeastOnce(); - - EasyMock.expect(repoVersion220.getStackId()).andReturn(stack220).atLeastOnce(); - EasyMock.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<>(); - Map<String, String> stack211BazType = new HashMap<>(); - stack211Configs.put("foo-site", stack211FooType); - stack211Configs.put("bar-site", stack211BarType); - stack211Configs.put("baz-site", stack211BazType); - stack211FooType.put("1", "one"); - stack211FooType.put("11", "one-one"); - stack211BarType.put("2", "two"); - stack211BazType.put("3", "three"); - - Map<String, Map<String, String>> stack220Configs = new HashMap<>(); - Map<String, String> stack220FooType = new HashMap<>(); - Map<String, String> stack220BazType = new HashMap<>(); - Map<String, String> stack220FlumeEnvType = new HashMap<>(); - stack220Configs.put("foo-site", stack220FooType); - stack220Configs.put("baz-site", stack220BazType); - stack220Configs.put("flume-env", stack220FlumeEnvType); - stack220FooType.put("1", "one-new"); - stack220FooType.put("111", "one-one-one"); - stack220BazType.put("3", "three-new"); - stack220FlumeEnvType.put("flume_env_key", "flume-env-value"); - - Map<String, String> clusterFooType = new HashMap<>(); - Map<String, String> clusterBarType = new HashMap<>(); - Map<String, String> clusterBazType = new HashMap<>(); - - Config fooConfig = EasyMock.createNiceMock(Config.class); - Config barConfig = EasyMock.createNiceMock(Config.class); - Config bazConfig = EasyMock.createNiceMock(Config.class); - - clusterFooType.put("1", "one"); - clusterFooType.put("11", "one-one"); - clusterBarType.put("2", "two"); - clusterBazType.put("3", "three-changed"); - - expect(fooConfig.getProperties()).andReturn(clusterFooType); - expect(barConfig.getProperties()).andReturn(clusterBarType); - expect(bazConfig.getProperties()).andReturn(clusterBazType); - - Map<String, DesiredConfig> desiredConfigurations = new HashMap<>(); - desiredConfigurations.put("foo-site", null); - desiredConfigurations.put("bar-site", null); - desiredConfigurations.put("baz-site", null); - - Cluster cluster = EasyMock.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.getDesiredConfigByType("baz-site")).andReturn(bazConfig); - - // setup the config helper for placeholder resolution - EasyMock.reset(configHelper); - - expect( - configHelper.getDefaultProperties(EasyMock.eq(stack211), EasyMock.anyString())).andReturn( - stack211Configs).anyTimes(); - - expect( - configHelper.getDefaultProperties(EasyMock.eq(stack220), EasyMock.anyString())).andReturn( - stack220Configs).anyTimes(); - - Capture<Map<String, Map<String, String>>> expectedConfigurationsCapture = EasyMock.newCapture(); - - configHelper.createConfigTypes(EasyMock.anyObject(Cluster.class), - EasyMock.anyObject(AmbariManagementController.class), - EasyMock.anyObject(StackId.class), - EasyMock.capture(expectedConfigurationsCapture), - EasyMock.anyObject(String.class), EasyMock.anyObject(String.class)); - - EasyMock.expectLastCall().once(); - - EasyMock.replay(configHelper, cluster, fooConfig, barConfig, bazConfig); - - Map<String, UpgradePack> upgradePacks = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1"); - UpgradePack upgradePack = upgradePacks.get("upgrade_to_new_stack"); - - UpgradeContext upgradeContext = EasyMock.createNiceMock(UpgradeContext.class); - EasyMock.expect(upgradeContext.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes(); - EasyMock.expect(upgradeContext.getCluster()).andReturn(cluster).anyTimes(); - EasyMock.expect(upgradeContext.getDirection()).andReturn(Direction.UPGRADE).anyTimes(); - EasyMock.expect(upgradeContext.getUpgradePack()).andReturn(upgradePack).anyTimes(); - EasyMock.expect(upgradeContext.getRepositoryVersion()).andReturn(repoVersion211).anyTimes(); - EasyMock.expect(upgradeContext.getTargetRepositoryVersion(EasyMock.anyString())).andReturn(repoVersion220).anyTimes(); - - Map<String, Map<String, String>> expectedConfigurations = expectedConfigurationsCapture.getValue(); - Map<String, String> expectedFooType = expectedConfigurations.get("foo-site"); - Map<String, String> expectedBarType = expectedConfigurations.get("bar-site"); - Map<String, String> expectedBazType = expectedConfigurations.get("baz-site"); - - // As the upgrade pack did not have any Flume updates, its configs should not be updated. - assertFalse(expectedConfigurations.containsKey("flume-env")); - - // the really important values are one-new and three-changed; one-new - // indicates that the new stack value is changed since it was not customized - // while three-changed represents that the customized value was preserved - // even though the stack value changed - assertEquals("one-new", expectedFooType.get("1")); - assertEquals("one-one", expectedFooType.get("11")); - assertEquals("two", expectedBarType.get("2")); - assertEquals("three-changed", expectedBazType.get("3")); - } - - /** * @param amc * @return the provider */ http://git-wip-us.apache.org/repos/asf/ambari/blob/770c519a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java index f306d69..54b16a9 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java @@ -18,7 +18,6 @@ package org.apache.ambari.server.serveraction.upgrades; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -47,12 +46,14 @@ import org.apache.ambari.server.controller.ServiceConfigVersionResponse; import org.apache.ambari.server.orm.GuiceJpaInitializer; import org.apache.ambari.server.orm.InMemoryDefaultTestModule; import org.apache.ambari.server.orm.OrmTestHelper; +import org.apache.ambari.server.orm.dao.HostComponentStateDAO; import org.apache.ambari.server.orm.dao.HostDAO; import org.apache.ambari.server.orm.dao.HostVersionDAO; import org.apache.ambari.server.orm.dao.RepositoryVersionDAO; import org.apache.ambari.server.orm.dao.RequestDAO; import org.apache.ambari.server.orm.dao.StackDAO; import org.apache.ambari.server.orm.dao.UpgradeDAO; +import org.apache.ambari.server.orm.entities.HostComponentStateEntity; import org.apache.ambari.server.orm.entities.HostVersionEntity; import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; import org.apache.ambari.server.orm.entities.RequestEntity; @@ -74,6 +75,7 @@ import org.apache.ambari.server.state.ServiceComponentHostFactory; import org.apache.ambari.server.state.ServiceFactory; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.State; +import org.apache.ambari.server.state.UpgradeState; import org.apache.ambari.server.state.stack.UpgradePack; import org.apache.ambari.server.state.stack.upgrade.UpgradeType; import org.apache.ambari.server.utils.EventBusSynchronizer; @@ -139,6 +141,9 @@ public class UpgradeActionTest { @Inject private ConfigFactory configFactory; + @Inject + private HostComponentStateDAO hostComponentStateDAO; + private RepositoryVersionEntity repositoryVersion2110; private RepositoryVersionEntity repositoryVersion2111; private RepositoryVersionEntity repositoryVersion2201; @@ -417,9 +422,29 @@ public class UpgradeActionTest { finalizeUpgradeAction.setExecutionCommand(executionCommand); finalizeUpgradeAction.setHostRoleCommand(hostRoleCommand); + // this should fail since the host versions have not moved to current CommandReport report = finalizeUpgradeAction.execute(null); - assertNotNull(report); + assertEquals(HostRoleStatus.FAILED.name(), report.getStatus()); + + List<HostVersionEntity> hostVersions = hostVersionDAO.findHostVersionByClusterAndRepository( + cluster.getClusterId(), repositoryVersion2111); + + for (HostVersionEntity hostVersion : hostVersions) { + hostVersion.setState(RepositoryVersionState.CURRENT); + } + + report = finalizeUpgradeAction.execute(null); assertEquals(HostRoleStatus.COMPLETED.name(), report.getStatus()); + + hostVersions = hostVersionDAO.findHostVersionByClusterAndRepository(cluster.getClusterId(), + repositoryVersion2111); + + for (HostVersionEntity hostVersion : hostVersions) { + Collection<HostComponentStateEntity> hostComponentStates = hostComponentStateDAO.findByHost(hostVersion.getHostName()); + for (HostComponentStateEntity hostComponentStateEntity: hostComponentStates) { + assertEquals(UpgradeState.NONE, hostComponentStateEntity.getUpgradeState()); + } + } } /** @@ -472,218 +497,6 @@ public class UpgradeActionTest { assertEquals(HostRoleStatus.COMPLETED.name(), report.getStatus()); } - @Test - public void testFinalizeUpgradeAcrossStacks() throws Exception { - StackId sourceStack = HDP_21_STACK; - StackId targetStack = HDP_22_STACK; - String sourceRepo = HDP_2_1_1_0; - String targetRepo = HDP_2_2_0_1; - String hostName = "h1"; - - makeCrossStackUpgradeClusterAndSourceRepo(sourceStack, sourceRepo, hostName); - makeCrossStackUpgradeTargetRepo(targetStack, targetRepo, hostName); - - Cluster cluster = clusters.getCluster(clusterName); - - // setup the cluster for the upgrade across stacks - cluster.setCurrentStackVersion(sourceStack); - cluster.setDesiredStackVersion(targetStack); - - createUpgrade(cluster, repositoryVersion2201); - - Map<String, String> commandParams = new HashMap<>(); - ExecutionCommand executionCommand = new ExecutionCommand(); - executionCommand.setCommandParams(commandParams); - executionCommand.setClusterName(clusterName); - - HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null, null, null); - - hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(executionCommand)); - - finalizeUpgradeAction.setExecutionCommand(executionCommand); - finalizeUpgradeAction.setHostRoleCommand(hostRoleCommand); - - CommandReport report = finalizeUpgradeAction.execute(null); - assertNotNull(report); - assertEquals(HostRoleStatus.COMPLETED.name(), report.getStatus()); - - StackId currentStackId = cluster.getCurrentStackVersion(); - StackId desiredStackId = cluster.getDesiredStackVersion(); - - // verify current/desired stacks are updated to the new stack - assertEquals(desiredStackId, currentStackId); - assertEquals(targetStack, currentStackId); - assertEquals(targetStack, desiredStackId); - } - - /** - * Tests some of the action items are completed when finalizing downgrade - * across stacks (HDP 2.2 -> HDP 2.3). - * - * @throws Exception - */ - @Test - public void testFinalizeDowngradeAcrossStacks() throws Exception { - StackId sourceStack = HDP_21_STACK; - StackId targetStack = HDP_22_STACK; - String sourceRepo = HDP_2_1_1_0; - String targetRepo = HDP_2_2_0_1; - String hostName = "h1"; - - makeCrossStackUpgradeClusterAndSourceRepo(sourceStack, sourceRepo, hostName); - Cluster cluster = clusters.getCluster(clusterName); - - // install HDFS with some components - Service service = installService(cluster, "HDFS"); - addServiceComponent(cluster, service, "NAMENODE"); - addServiceComponent(cluster, service, "DATANODE"); - createNewServiceComponentHost(cluster, "HDFS", "NAMENODE", "h1"); - createNewServiceComponentHost(cluster, "HDFS", "DATANODE", "h1"); - - makeCrossStackUpgradeTargetRepo(targetStack, targetRepo, hostName); - - createUpgrade(cluster, repositoryVersion2201); - - // create some configs - createConfigs(cluster); - - // setup the cluster for the upgrade across stacks - cluster.setCurrentStackVersion(sourceStack); - cluster.setDesiredStackVersion(targetStack); - - // now that the desired version is set, we can create some new configs in - // the new stack version - createConfigs(cluster); - - // verify we have configs in both HDP stacks - cluster = clusters.getCluster(clusterName); - Collection<Config> configs = cluster.getAllConfigs(); - assertEquals(8, configs.size()); - - Map<String, String> commandParams = new HashMap<>(); - ExecutionCommand executionCommand = new ExecutionCommand(); - executionCommand.setCommandParams(commandParams); - executionCommand.setClusterName(clusterName); - - HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null, null, null); - - hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(executionCommand)); - - HostVersionDAO dao = m_injector.getInstance(HostVersionDAO.class); - - List<HostVersionEntity> hosts = dao.findByClusterStackAndVersion(clusterName, targetStack, targetRepo); - assertFalse(hosts.isEmpty()); - for (HostVersionEntity hve : hosts) { - assertTrue(hve.getState() == RepositoryVersionState.INSTALLED); - } - - finalizeUpgradeAction.setExecutionCommand(executionCommand); - finalizeUpgradeAction.setHostRoleCommand(hostRoleCommand); - - CommandReport report = finalizeUpgradeAction.execute(null); - assertNotNull(report); - assertEquals(HostRoleStatus.COMPLETED.name(), report.getStatus()); - - StackId currentStackId = cluster.getCurrentStackVersion(); - StackId desiredStackId = cluster.getDesiredStackVersion(); - - // verify current/desired stacks are back to normal - assertEquals(desiredStackId, currentStackId); - assertEquals(sourceStack, currentStackId); - assertEquals(sourceStack, desiredStackId); - - // verify we have configs in only 1 stack - cluster = clusters.getCluster(clusterName); - configs = cluster.getAllConfigs(); - assertEquals(4, configs.size()); - - hosts = dao.findByClusterStackAndVersion(clusterName, targetStack, targetRepo); - assertFalse(hosts.isEmpty()); - for (HostVersionEntity hve : hosts) { - assertTrue(hve.getState() == RepositoryVersionState.INSTALLED); - } - } - - /** - * Tests that finalization can occur when the cluster state is - * {@link RepositoryVersionState#UPGRADING} if all of the hosts and components - * are reporting correct versions and states. - * - * @throws Exception - */ - @Test - public void testFinalizeUpgradeWithClusterStateInconsistencies() throws Exception { - StackId sourceStack = HDP_21_STACK; - StackId targetStack = HDP_22_STACK; - String sourceRepo = HDP_2_1_1_0; - String targetRepo = HDP_2_2_0_1; - String hostName = "h1"; - - makeCrossStackUpgradeClusterAndSourceRepo(sourceStack, sourceRepo, hostName); - - Cluster cluster = clusters.getCluster(clusterName); - - Service service = installService(cluster, "HDFS"); - addServiceComponent(cluster, service, "NAMENODE"); - addServiceComponent(cluster, service, "DATANODE"); - createNewServiceComponentHost(cluster, "HDFS", "NAMENODE", "h1"); - createNewServiceComponentHost(cluster, "HDFS", "DATANODE", "h1"); - - makeCrossStackUpgradeTargetRepo(targetStack, targetRepo, hostName); - // create some configs - createConfigs(cluster); - - // setup the cluster for the upgrade across stacks - cluster.setCurrentStackVersion(sourceStack); - cluster.setDesiredStackVersion(targetStack); - - createUpgrade(cluster, repositoryVersion2201); - - // set the SCH versions to the new stack so that the finalize action is - // happy - cluster.getServiceComponentHosts("HDFS", "NAMENODE").get(0).setVersion(targetRepo); - cluster.getServiceComponentHosts("HDFS", "DATANODE").get(0).setVersion(targetRepo); - - // inject an unhappy path where the cluster repo version is still UPGRADING - // even though all of the hosts are UPGRADED - - - // verify the conditions for the test are met properly - List<HostVersionEntity> hostVersions = hostVersionDAO.findByClusterStackAndVersion(clusterName, HDP_22_STACK, targetRepo); - - assertTrue(hostVersions.size() > 0); - for (HostVersionEntity hostVersion : hostVersions) { - assertEquals(RepositoryVersionState.INSTALLED, hostVersion.getState()); - } - - // now finalize and ensure we can transition from UPGRADING to UPGRADED - // automatically before CURRENT - Map<String, String> commandParams = new HashMap<>(); - ExecutionCommand executionCommand = new ExecutionCommand(); - executionCommand.setCommandParams(commandParams); - executionCommand.setClusterName(clusterName); - - HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null, null, null); - - hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(executionCommand)); - - finalizeUpgradeAction.setExecutionCommand(executionCommand); - finalizeUpgradeAction.setHostRoleCommand(hostRoleCommand); - - CommandReport report = finalizeUpgradeAction.execute(null); - assertNotNull(report); - assertEquals(HostRoleStatus.COMPLETED.name(), report.getStatus()); - - StackId currentStackId = cluster.getCurrentStackVersion(); - StackId desiredStackId = cluster.getDesiredStackVersion(); - - // verify current/desired stacks are updated to the new stack - assertEquals(desiredStackId, currentStackId); - assertEquals(targetStack, currentStackId); - assertEquals(targetStack, desiredStackId); - } - - private ServiceComponentHost createNewServiceComponentHost(Cluster cluster, String svc, String svcComponent, String hostName) throws AmbariException { Assert.assertNotNull(cluster.getConfigGroups()); http://git-wip-us.apache.org/repos/asf/ambari/blob/770c519a/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java index 24c529d..cab1c8d 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java @@ -17,7 +17,9 @@ */ package org.apache.ambari.server.state; +import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -50,7 +52,10 @@ import org.apache.ambari.server.controller.ConfigurationRequest; import org.apache.ambari.server.orm.GuiceJpaInitializer; import org.apache.ambari.server.orm.InMemoryDefaultTestModule; import org.apache.ambari.server.orm.OrmTestHelper; +import org.apache.ambari.server.orm.dao.ServiceConfigDAO; +import org.apache.ambari.server.orm.entities.ClusterConfigEntity; import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; +import org.apache.ambari.server.orm.entities.ServiceConfigEntity; import org.apache.ambari.server.security.TestAuthenticationFactory; import org.apache.ambari.server.security.authorization.AuthorizationException; import org.apache.ambari.server.stack.HostsType; @@ -80,6 +85,7 @@ import org.apache.ambari.server.state.stack.upgrade.UpgradeType; import org.apache.ambari.server.utils.EventBusSynchronizer; import org.easymock.Capture; import org.easymock.EasyMock; +import org.easymock.EasyMockSupport; import org.easymock.IAnswer; import org.junit.After; import org.junit.Before; @@ -94,13 +100,14 @@ import com.google.inject.Binder; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; +import com.google.inject.Provider; import com.google.inject.assistedinject.FactoryModuleBuilder; import com.google.inject.util.Modules; /** * Tests the {@link UpgradeHelper} class */ -public class UpgradeHelperTest { +public class UpgradeHelperTest extends EasyMockSupport { private static final StackId STACK_ID_HDP_211 = new StackId("HDP-2.1.1"); private static final StackId STACK_ID_HDP_220 = new StackId("HDP-2.2.0"); @@ -460,7 +467,7 @@ public class UpgradeHelperTest { // use a "real" master host resolver here so that we can actually test MM MasterHostResolver masterHostResolver = new MasterHostResolver(cluster, null, context); - EasyMock.expect(context.getResolver()).andReturn(masterHostResolver).anyTimes(); + expect(context.getResolver()).andReturn(masterHostResolver).anyTimes(); replay(context); List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context); @@ -1560,7 +1567,7 @@ public class UpgradeHelperTest { UpgradeType.HOST_ORDERED, repositoryVersion2110); MasterHostResolver resolver = new MasterHostResolver(c, m_configHelper, context); - EasyMock.expect(context.getResolver()).andReturn(resolver).anyTimes(); + expect(context.getResolver()).andReturn(resolver).anyTimes(); replay(context); HostsType ht = resolver.getMasterAndHosts("ZOOKEEPER", "ZOOKEEPER_SERVER"); @@ -1635,7 +1642,7 @@ public class UpgradeHelperTest { // use a "real" master host resolver here so that we can actually test MM MasterHostResolver mhr = new MockMasterHostResolver(c, m_configHelper, context); - EasyMock.expect(context.getResolver()).andReturn(mhr).anyTimes(); + expect(context.getResolver()).andReturn(mhr).anyTimes(); replay(context); @@ -1704,7 +1711,7 @@ public class UpgradeHelperTest { // use a "real" master host resolver here so that we can actually test MM MasterHostResolver mhr = new BadMasterHostResolver(c, m_configHelper, context); - EasyMock.expect(context.getResolver()).andReturn(mhr).anyTimes(); + expect(context.getResolver()).andReturn(mhr).anyTimes(); replay(context); HostsType ht = mhr.getMasterAndHosts("HDFS", "NAMENODE"); @@ -1842,7 +1849,7 @@ public class UpgradeHelperTest { // use a "real" master host resolver here so that we can actually test MM MasterHostResolver masterHostResolver = new MasterHostResolver(c, m_configHelper, context); - EasyMock.expect(context.getResolver()).andReturn(masterHostResolver).anyTimes(); + expect(context.getResolver()).andReturn(masterHostResolver).anyTimes(); replay(context); List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgradePack, context); @@ -1858,7 +1865,7 @@ public class UpgradeHelperTest { // use a "real" master host resolver here so that we can actually test MM masterHostResolver = new MasterHostResolver(c, m_configHelper, context); - EasyMock.expect(context.getResolver()).andReturn(masterHostResolver).anyTimes(); + expect(context.getResolver()).andReturn(masterHostResolver).anyTimes(); replay(context); groups = m_upgradeHelper.createSequence(upgradePack, context); @@ -2124,7 +2131,7 @@ public class UpgradeHelperTest { UpgradeType.HOST_ORDERED, repoVersion220); MasterHostResolver resolver = new MasterHostResolver(c, m_configHelper, context); - EasyMock.expect(context.getResolver()).andReturn(resolver).anyTimes(); + expect(context.getResolver()).andReturn(resolver).anyTimes(); replay(context); @@ -2168,7 +2175,7 @@ public class UpgradeHelperTest { repoVersion211); resolver = new MasterHostResolver(c, m_configHelper, context); - EasyMock.expect(context.getResolver()).andReturn(resolver).anyTimes(); + expect(context.getResolver()).andReturn(resolver).anyTimes(); replay(context); groups = m_upgradeHelper.createSequence(upgradePack, context); @@ -2185,7 +2192,7 @@ public class UpgradeHelperTest { repoVersion211); resolver = new MasterHostResolver(c, m_configHelper, context); - EasyMock.expect(context.getResolver()).andReturn(resolver).anyTimes(); + expect(context.getResolver()).andReturn(resolver).anyTimes(); replay(context); groups = m_upgradeHelper.createSequence(upgradePack, context); @@ -2243,6 +2250,182 @@ public class UpgradeHelperTest { } /** + * Tests merging configurations between existing and new stack values on + * upgrade. + * + * @throws Exception + */ + @Test + public void testMergeConfigurations() 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<>(); + Map<String, String> stack211BazType = new HashMap<>(); + stack211Configs.put("foo-site", stack211FooType); + stack211Configs.put("bar-site", stack211BarType); + stack211Configs.put("baz-site", stack211BazType); + stack211FooType.put("1", "one"); + stack211FooType.put("1A", "one-A"); + stack211BarType.put("2", "two"); + stack211BazType.put("3", "three"); + + Map<String, Map<String, String>> stack220Configs = new HashMap<>(); + Map<String, String> stack220FooType = new HashMap<>(); + Map<String, String> stack220BazType = new HashMap<>(); + stack220Configs.put("foo-site", stack220FooType); + stack220Configs.put("baz-site", stack220BazType); + stack220FooType.put("1", "one-new"); + stack220FooType.put("1A1", "one-A-one"); + stack220BazType.put("3", "three-new"); + + Map<String, String> existingFooType = new HashMap<>(); + Map<String, String> existingBarType = new HashMap<>(); + Map<String, String> existingBazType = new HashMap<>(); + + ClusterConfigEntity fooConfigEntity = createNiceMock(ClusterConfigEntity.class); + ClusterConfigEntity barConfigEntity = createNiceMock(ClusterConfigEntity.class); + ClusterConfigEntity bazConfigEntity = createNiceMock(ClusterConfigEntity.class); + + expect(fooConfigEntity.getType()).andReturn("foo-site"); + expect(barConfigEntity.getType()).andReturn("bar-site"); + expect(bazConfigEntity.getType()).andReturn("baz-site"); + + Config fooConfig = createNiceMock(Config.class); + Config barConfig = createNiceMock(Config.class); + Config bazConfig = createNiceMock(Config.class); + + existingFooType.put("1", "one"); + existingFooType.put("1A", "one-A"); + existingBarType.put("2", "two"); + existingBazType.put("3", "three-changed"); + + expect(fooConfig.getType()).andReturn("foo-site").atLeastOnce(); + expect(barConfig.getType()).andReturn("bar-site").atLeastOnce(); + expect(bazConfig.getType()).andReturn("baz-site").atLeastOnce(); + expect(fooConfig.getProperties()).andReturn(existingFooType); + expect(barConfig.getProperties()).andReturn(existingBarType); + expect(bazConfig.getProperties()).andReturn(existingBazType); + + Map<String, DesiredConfig> desiredConfigurations = new HashMap<>(); + desiredConfigurations.put("foo-site", null); + desiredConfigurations.put("bar-site", null); + desiredConfigurations.put("baz-site", null); + + Service zookeeper = createNiceMock(Service.class); + expect(zookeeper.getName()).andReturn("ZOOKEEPER").atLeastOnce(); + expect(zookeeper.getServiceComponents()).andReturn( + new HashMap<String, ServiceComponent>()).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.getDesiredConfigByType("baz-site")).andReturn(bazConfig); + expect(cluster.getService("ZOOKEEPER")).andReturn(zookeeper); + expect(cluster.getDesiredConfigByType("foo-type")).andReturn(fooConfig); + expect(cluster.getDesiredConfigByType("bar-type")).andReturn(barConfig); + expect(cluster.getDesiredConfigByType("baz-type")).andReturn(bazConfig); + + // setup the config helper for placeholder resolution + @SuppressWarnings("unchecked") + Provider<ConfigHelper> configHelperProvider = EasyMock.createNiceMock(Provider.class); + ConfigHelper configHelper = EasyMock.createNiceMock(ConfigHelper.class); + + expect(configHelperProvider.get()).andStubReturn(configHelper); + + 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(); + + configHelper.createConfigTypes(EasyMock.anyObject(Cluster.class), + EasyMock.anyObject(AmbariManagementController.class), EasyMock.anyObject(StackId.class), + EasyMock.capture(expectedConfigurationsCapture), EasyMock.anyObject(String.class), + EasyMock.anyObject(String.class)); + + expectLastCall().once(); + EasyMock.replay(configHelperProvider, configHelper); + + // mock the service config DAO and replay it + ServiceConfigEntity zookeeperServiceConfig = createNiceMock(ServiceConfigEntity.class); + expect(zookeeperServiceConfig.getClusterConfigEntities()).andReturn( + Lists.newArrayList(fooConfigEntity, barConfigEntity, bazConfigEntity)); + + ServiceConfigDAO serviceConfigDAOMock; + serviceConfigDAOMock = EasyMock.createNiceMock(ServiceConfigDAO.class); + + List<ServiceConfigEntity> latestServiceConfigs = Lists.newArrayList(zookeeperServiceConfig); + expect(serviceConfigDAOMock.getLastServiceConfigsForService(EasyMock.anyLong(), + eq("ZOOKEEPER"))).andReturn(latestServiceConfigs).once(); + + replay(serviceConfigDAOMock); + + Map<String, UpgradePack> upgradePacks = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1"); + UpgradePack upgradePack = upgradePacks.get("upgrade_to_new_stack"); + + 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.getRepositoryType()).andReturn(RepositoryType.STANDARD).anyTimes(); + expect(context.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes(); + expect(context.getHostRoleCommandFactory()).andStubReturn(injector.getInstance(HostRoleCommandFactory.class)); + expect(context.getRoleGraphFactory()).andStubReturn(injector.getInstance(RoleGraphFactory.class)); + expect(context.getUpgradePack()).andReturn(upgradePack).atLeastOnce(); + + replayAll(); + + UpgradeHelper upgradeHelper = injector.getInstance(UpgradeHelper.class); + upgradeHelper.m_serviceConfigDAO = serviceConfigDAOMock; + upgradeHelper.m_configHelperProvider = configHelperProvider; + 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"); + Map<String, String> expectedBazType = expectedConfigurations.get("baz-site"); + + // As the upgrade pack did not have any Flume updates, its configs should + // not be updated. + assertEquals(3, expectedConfigurations.size()); + + // the really important values are one-new and three-changed; one-new + // indicates that the new stack value is changed since it was not customized + // while three-changed represents that the customized value was preserved + // even though the stack value changed + assertEquals("one-new", expectedFooType.get("1")); + assertEquals("one-A", expectedFooType.get("1A")); + assertEquals("two", expectedBarType.get("2")); + assertEquals("three-changed", expectedBazType.get("3")); + } + + /** * @param cluster * @param direction * @param type @@ -2304,19 +2487,21 @@ public class UpgradeHelperTest { UpgradeType type, RepositoryVersionEntity repositoryVersion, final RepositoryType repositoryType, Set<String> services, MasterHostResolver resolver, boolean replay) { UpgradeContext context = EasyMock.createNiceMock(UpgradeContext.class); - EasyMock.expect(context.getCluster()).andReturn(cluster).anyTimes(); - EasyMock.expect(context.getType()).andReturn(type).anyTimes(); - EasyMock.expect(context.getDirection()).andReturn(direction).anyTimes(); - EasyMock.expect(context.getRepositoryVersion()).andReturn(repositoryVersion).anyTimes(); - EasyMock.expect(context.getSupportedServices()).andReturn(services).anyTimes(); - EasyMock.expect(context.getRepositoryType()).andReturn(repositoryType).anyTimes(); - EasyMock.expect(context.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes(); - EasyMock.expect(context.getHostRoleCommandFactory()).andStubReturn(injector.getInstance(HostRoleCommandFactory.class)); - EasyMock.expect(context.getRoleGraphFactory()).andStubReturn(injector.getInstance(RoleGraphFactory.class)); + expect(context.getCluster()).andReturn(cluster).anyTimes(); + expect(context.getType()).andReturn(type).anyTimes(); + expect(context.getDirection()).andReturn(direction).anyTimes(); + expect(context.getRepositoryVersion()).andReturn(repositoryVersion).anyTimes(); + expect(context.getSupportedServices()).andReturn(services).anyTimes(); + expect(context.getRepositoryType()).andReturn(repositoryType).anyTimes(); + expect(context.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes(); + expect(context.getHostRoleCommandFactory()).andStubReturn( + injector.getInstance(HostRoleCommandFactory.class)); + expect(context.getRoleGraphFactory()).andStubReturn( + injector.getInstance(RoleGraphFactory.class)); // only set this if supplied if (null != resolver) { - EasyMock.expect(context.getResolver()).andReturn(resolver).anyTimes(); + expect(context.getResolver()).andReturn(resolver).anyTimes(); } final Map<String, RepositoryVersionEntity> targetRepositoryVersions = new HashMap<>(); @@ -2325,7 +2510,7 @@ public class UpgradeHelperTest { } final Capture<String> repoVersionServiceName = EasyMock.newCapture(); - EasyMock.expect( + expect( context.getTargetRepositoryVersion(EasyMock.capture(repoVersionServiceName))).andAnswer( new IAnswer<RepositoryVersionEntity>() { @Override @@ -2335,7 +2520,7 @@ public class UpgradeHelperTest { }).anyTimes(); final Capture<String> serviceNameSupported = EasyMock.newCapture(); - EasyMock.expect(context.isServiceSupported(EasyMock.capture(serviceNameSupported))).andAnswer( + expect(context.isServiceSupported(EasyMock.capture(serviceNameSupported))).andAnswer( new IAnswer<Boolean>() { @Override public Boolean answer() { @@ -2349,7 +2534,7 @@ public class UpgradeHelperTest { final Capture<String> serviceDisplayNameArg2 = EasyMock.newCapture(); context.setServiceDisplay(EasyMock.capture(serviceDisplayNameArg1), EasyMock.capture(serviceDisplayNameArg2)); - EasyMock.expectLastCall().andAnswer( + expectLastCall().andAnswer( new IAnswer<Object>() { @Override public Object answer() { @@ -2367,7 +2552,7 @@ public class UpgradeHelperTest { context.setComponentDisplay(EasyMock.capture(componentDisplayNameArg1), EasyMock.capture(componentDisplayNameArg2), EasyMock.capture(componentDisplayNameArg3)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + expectLastCall().andAnswer(new IAnswer<Object>() { @Override public Object answer() { componentNames.put( @@ -2378,7 +2563,7 @@ public class UpgradeHelperTest { }).anyTimes(); final Capture<String> getServiceDisplayArgument1 = EasyMock.newCapture(); - EasyMock.expect( + expect( context.getServiceDisplay(EasyMock.capture(getServiceDisplayArgument1))).andAnswer( new IAnswer<String>() { @Override @@ -2389,7 +2574,7 @@ public class UpgradeHelperTest { final Capture<String> getComponentDisplayArgument1 = EasyMock.newCapture(); final Capture<String> getComponentDisplayArgument2 = EasyMock.newCapture(); - EasyMock.expect(context.getComponentDisplay(EasyMock.capture(getComponentDisplayArgument1), + expect(context.getComponentDisplay(EasyMock.capture(getComponentDisplayArgument1), EasyMock.capture(getComponentDisplayArgument2))).andAnswer(new IAnswer<String>() { @Override public String answer() { @@ -2399,7 +2584,7 @@ public class UpgradeHelperTest { }).anyTimes(); final Capture<UpgradeScope> isScopedCapture = EasyMock.newCapture(); - EasyMock.expect(context.isScoped(EasyMock.capture(isScopedCapture))).andStubAnswer( + expect(context.isScoped(EasyMock.capture(isScopedCapture))).andStubAnswer( new IAnswer<Boolean>() { @Override public Boolean answer() throws Throwable {