Return-Path: X-Original-To: apmail-ambari-commits-archive@www.apache.org Delivered-To: apmail-ambari-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id A35061871F for ; Wed, 4 Nov 2015 21:41:48 +0000 (UTC) Received: (qmail 47145 invoked by uid 500); 4 Nov 2015 21:41:48 -0000 Delivered-To: apmail-ambari-commits-archive@ambari.apache.org Received: (qmail 47118 invoked by uid 500); 4 Nov 2015 21:41:48 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 47109 invoked by uid 99); 4 Nov 2015 21:41:48 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 04 Nov 2015 21:41:48 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 41389DFCC9; Wed, 4 Nov 2015 21:41:48 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jluniya@apache.org To: commits@ambari.apache.org Message-Id: <6aa0ac6ab95241d1a8cda2ac3292f850@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: ambari git commit: AMBARI-13708: RU/EU: invalid state transition, INSTALL_FAILED (cannot Finalize) (jluniya) Date: Wed, 4 Nov 2015 21:41:48 +0000 (UTC) Repository: ambari Updated Branches: refs/heads/branch-2.1 36681a57e -> d0c0a5edf AMBARI-13708: RU/EU: invalid state transition, INSTALL_FAILED (cannot Finalize) (jluniya) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d0c0a5ed Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d0c0a5ed Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d0c0a5ed Branch: refs/heads/branch-2.1 Commit: d0c0a5edf4a39d11bbba1a6027d900d377470a3f Parents: 36681a5 Author: Jayush Luniya Authored: Wed Nov 4 13:40:48 2015 -0800 Committer: Jayush Luniya Committed: Wed Nov 4 13:41:39 2015 -0800 ---------------------------------------------------------------------- .../server/checks/AbstractCheckDescriptor.java | 4 + .../ambari/server/checks/CheckDescription.java | 7 + .../checks/ComponentsInstallationCheck.java | 37 ++-- .../server/checks/InstallPackagesCheck.java | 95 ++++++++++ .../server/state/cluster/ClusterImpl.java | 7 + .../checks/ComponentsInstallationCheckTest.java | 42 +++++ .../server/checks/InstallPackagesCheckTest.java | 179 +++++++++++++++++++ .../ambari/server/state/CheckHelperTest.java | 2 + 8 files changed, 357 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/d0c0a5ed/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java index 760a971..c29d64c 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java @@ -26,6 +26,7 @@ import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.controller.PrereqCheckRequest; import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.orm.dao.ClusterVersionDAO; import org.apache.ambari.server.orm.dao.HostVersionDAO; import org.apache.ambari.server.orm.dao.RepositoryVersionDAO; import org.apache.ambari.server.state.Cluster; @@ -57,6 +58,9 @@ public abstract class AbstractCheckDescriptor { Provider clustersProvider; @Inject + Provider clusterVersionDAOProvider; + + @Inject Provider hostVersionDaoProvider; @Inject http://git-wip-us.apache.org/repos/asf/ambari/blob/d0c0a5ed/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java index b7389e5..603b279 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java @@ -146,6 +146,13 @@ public enum CheckDescription { "The following Services must be reinstalled: {{fails}}. Try to reinstall the service components in INSTALL_FAILED state."); }}), + INSTALL_PACKAGES_CHECK(PrereqCheckType.CLUSTER, + "Install packages must be re-run", + new HashMap() {{ + put(AbstractCheckDescriptor.DEFAULT, + "Re-run Install Packages before starting upgrade"); + }}), + SERVICES_YARN_WP(PrereqCheckType.SERVICE, "YARN work preserving restart should be enabled", new HashMap() {{ http://git-wip-us.apache.org/repos/asf/ambari/blob/d0c0a5ed/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsInstallationCheck.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsInstallationCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsInstallationCheck.java index 07f4d05..3517537 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsInstallationCheck.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsInstallationCheck.java @@ -29,7 +29,8 @@ import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.controller.PrereqCheckRequest; import org.apache.ambari.server.orm.models.HostComponentSummary; import org.apache.ambari.server.state.Cluster; -import org.apache.ambari.server.state.ComponentInfo; +import org.apache.ambari.server.state.Host; +import org.apache.ambari.server.state.MaintenanceState; import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.ServiceComponent; import org.apache.ambari.server.state.StackId; @@ -41,7 +42,7 @@ import org.apache.commons.lang.StringUtils; import com.google.inject.Singleton; /** - * Checks that services are up. + * Checks that service components are installed. */ @Singleton @UpgradeCheck(group = UpgradeCheckGroup.LIVELINESS, order = 2.0f, required = true) @@ -58,7 +59,6 @@ public class ComponentsInstallationCheck extends AbstractCheckDescriptor { public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException { final String clusterName = request.getClusterName(); final Cluster cluster = clustersProvider.get().getCluster(clusterName); - List errorMessages = new ArrayList(); Set failedServiceNames = new HashSet(); StackId stackId = cluster.getCurrentStackVersion(); @@ -68,20 +68,25 @@ public class ComponentsInstallationCheck extends AbstractCheckDescriptor { for (Map.Entry serviceEntry : cluster.getServices().entrySet()) { final Service service = serviceEntry.getValue(); - Map serviceComponents = service.getServiceComponents(); + // Skip service if it is in maintenance mode + if (service.getMaintenanceState() != MaintenanceState.ON) { + Map serviceComponents = service.getServiceComponents(); + for (Map.Entry component : serviceComponents.entrySet()) { + ServiceComponent serviceComponent = component.getValue(); + if (serviceComponent.isVersionAdvertised()) { + List hostComponentSummaries = HostComponentSummary.getHostComponentSummaries( + service.getName(), serviceComponent.getName()); - for (Map.Entry component : serviceComponents.entrySet()) { - ServiceComponent serviceComponent = component.getValue(); - - if (serviceComponent.isVersionAdvertised()) { - List hostComponentSummaries = HostComponentSummary.getHostComponentSummaries( - service.getName(), serviceComponent.getName()); - - for(HostComponentSummary hcs : hostComponentSummaries) { - if (State.INSTALL_FAILED == hcs.getCurrentState()) { - failedServiceNames.add(service.getName()); - installFailedHostComponents.add(MessageFormat.format( - "[{0}:{1} on {2}]", service.getName(), serviceComponent.getName(), hcs.getHostName())); + for (HostComponentSummary hcs : hostComponentSummaries) { + // Skip host if it is in maintenance mode + Host host = clustersProvider.get().getHost(hcs.getHostName()); + if (host.getMaintenanceState(cluster.getClusterId()) != MaintenanceState.ON) { + if (hcs.getCurrentState() == State.INSTALL_FAILED) { + failedServiceNames.add(service.getName()); + installFailedHostComponents.add(MessageFormat.format( + "[{0}:{1} on {2}]", service.getName(), serviceComponent.getName(), hcs.getHostName())); + } + } } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/d0c0a5ed/ambari-server/src/main/java/org/apache/ambari/server/checks/InstallPackagesCheck.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/InstallPackagesCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/InstallPackagesCheck.java new file mode 100644 index 0000000..15b6140 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/InstallPackagesCheck.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ambari.server.checks; + +import java.text.MessageFormat; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.controller.PrereqCheckRequest; +import org.apache.ambari.server.orm.entities.ClusterVersionEntity; +import org.apache.ambari.server.orm.entities.HostVersionEntity; +import org.apache.ambari.server.state.Cluster; +import org.apache.ambari.server.state.Host; +import org.apache.ambari.server.state.MaintenanceState; +import org.apache.ambari.server.state.RepositoryVersionState; +import org.apache.ambari.server.state.StackId; +import org.apache.ambari.server.state.stack.PrereqCheckStatus; +import org.apache.ambari.server.state.stack.PrerequisiteCheck; +import org.apache.commons.lang.StringUtils; + +import com.google.inject.Singleton; + +/** + * Checks if Install Packages needs to be re-run + */ +@Singleton +@UpgradeCheck(group = UpgradeCheckGroup.DEFAULT, order = 2.0f, required = true) +public class InstallPackagesCheck extends AbstractCheckDescriptor { + + /** + * Constructor. + */ + public InstallPackagesCheck() { + super(CheckDescription.INSTALL_PACKAGES_CHECK); + } + + @Override + public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException { + final String clusterName = request.getClusterName(); + final Cluster cluster = clustersProvider.get().getCluster(clusterName); + final StackId targetStackId = request.getTargetStackId(); + final String repoVersion = request.getRepositoryVersion(); + final ClusterVersionEntity clusterVersion = clusterVersionDAOProvider.get().findByClusterAndStackAndVersion( + clusterName, targetStackId, repoVersion); + final Set failedHosts = new HashSet(); + + for (Host host : cluster.getHosts()) { + if (host.getMaintenanceState(cluster.getClusterId()) != MaintenanceState.ON) { + for (HostVersionEntity hve : hostVersionDaoProvider.get().findByHost(host.getHostName())) { + if (hve.getRepositoryVersion().getVersion().equals(request.getRepositoryVersion()) + && hve.getState() == RepositoryVersionState.INSTALL_FAILED) { + failedHosts.add(host.getHostName()); + } + } + } + } + + if (!failedHosts.isEmpty()) { + String message = MessageFormat.format("Hosts in cluster [{0},{1},{2},{3}] are in INSTALL_FAILED state because " + + "Install Packages had failed. Please re-run Install Packages, if necessary place following hosts " + + "in Maintenance mode: {4}", cluster.getClusterName(), targetStackId.getStackName(), + targetStackId.getStackVersion(), repoVersion, StringUtils.join(failedHosts, ", ")); + prerequisiteCheck.setFailedOn(new LinkedHashSet(failedHosts)); + prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL); + prerequisiteCheck.setFailReason(message); + } else if (clusterVersion.getState() == RepositoryVersionState.INSTALL_FAILED) { + String message = MessageFormat.format("Cluster [{0},{1},{2},{3}] is in INSTALL_FAILED state because " + + "Install Packages failed. Please re-run Install Packages even if you placed the failed hosts " + + "in Maintenance mode.", cluster.getClusterName(), targetStackId.getStackName(), + targetStackId.getStackVersion(), repoVersion); + LinkedHashSet failedOn = new LinkedHashSet(); + failedOn.add(cluster.getClusterName()); + prerequisiteCheck.setFailedOn(failedOn); + prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL); + prerequisiteCheck.setFailReason(message); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/d0c0a5ed/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java index 56b724f..63c62a9 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java @@ -1335,8 +1335,14 @@ public class ClusterImpl implements Cluster { hostVersionDAO.findByClusterStackAndVersion(getClusterName(), stackId, version); Set hostsWithState = new HashSet(); + Set hostsInMaintenanceState = new HashSet<>(); for (HostVersionEntity hostVersionEntity : hostVersionEntities) { String hostname = hostVersionEntity.getHostEntity().getHostName(); + Host host = hosts.get(hostname); + if(host != null && host.getMaintenanceState(getClusterId()) == MaintenanceState.ON) { + hostsInMaintenanceState.add(hostname); + continue; + } hostsWithState.add(hostname); RepositoryVersionState hostState = hostVersionEntity.getState(); @@ -1351,6 +1357,7 @@ public class ClusterImpl implements Cluster { hostsWithoutHostVersion.addAll(hosts.keySet()); hostsWithoutHostVersion.removeAll(hostsWithState); + hostsWithoutHostVersion.removeAll(hostsInMaintenanceState); // Ensure that all of the hosts without a Host Version only have // Components that do not advertise a version. http://git-wip-us.apache.org/repos/asf/ambari/blob/d0c0a5ed/ambari-server/src/test/java/org/apache/ambari/server/checks/ComponentsInstallationCheckTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ComponentsInstallationCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ComponentsInstallationCheckTest.java index e5a999a..5c93f44 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/checks/ComponentsInstallationCheckTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ComponentsInstallationCheckTest.java @@ -30,6 +30,8 @@ import org.apache.ambari.server.orm.models.HostComponentSummary; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; import org.apache.ambari.server.state.ComponentInfo; +import org.apache.ambari.server.state.Host; +import org.apache.ambari.server.state.MaintenanceState; import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.ServiceComponent; import org.apache.ambari.server.state.StackId; @@ -102,6 +104,9 @@ public class ComponentsInstallationCheckTest { final Service hdfsService = Mockito.mock(Service.class); final Service tezService = Mockito.mock(Service.class); final Service amsService = Mockito.mock(Service.class); + Mockito.when(hdfsService.getMaintenanceState()).thenReturn(MaintenanceState.OFF); + Mockito.when(tezService.getMaintenanceState()).thenReturn(MaintenanceState.OFF); + Mockito.when(amsService.getMaintenanceState()).thenReturn(MaintenanceState.OFF); HashMap clusterServices = new HashMap(); clusterServices.put("HDFS", hdfsService); @@ -210,6 +215,25 @@ public class ComponentsInstallationCheckTest { allHostComponentSummaries.add(hcsMetricsCollector); allHostComponentSummaries.add(hcsMetricsMonitor); + final Map hosts = new HashMap(); + final Host host1 = Mockito.mock(Host.class); + final Host host2 = Mockito.mock(Host.class); + final Host host3 = Mockito.mock(Host.class); + Mockito.when(host1.getMaintenanceState(1L)).thenReturn(MaintenanceState.OFF); + Mockito.when(host2.getMaintenanceState(1L)).thenReturn(MaintenanceState.OFF); + Mockito.when(host3.getMaintenanceState(1L)).thenReturn(MaintenanceState.OFF); + hosts.put("host1", host1); + hosts.put("host2", host2); + hosts.put("host3", host3); + Mockito.when(hcsNameNode.getHostName()).thenReturn("host1"); + Mockito.when(hcsDataNode1.getHostName()).thenReturn("host1"); + Mockito.when(hcsDataNode2.getHostName()).thenReturn("host2"); + Mockito.when(hcsDataNode3.getHostName()).thenReturn("host3"); + Mockito.when(hcsZKFC.getHostName()).thenReturn("host1"); + Mockito.when(hcsTezClient.getHostName()).thenReturn("host2"); + Mockito.when(hcsMetricsCollector.getHostName()).thenReturn("host3"); + Mockito.when(hcsMetricsMonitor.getHostName()).thenReturn("host3"); + // Mock the static method Mockito.when(HostComponentSummary.getHostComponentSummaries("HDFS", "NAMENODE")).thenReturn(Arrays.asList(hcsNameNode)); Mockito.when(HostComponentSummary.getHostComponentSummaries("HDFS", "DATANODE")).thenReturn(Arrays.asList(hcsDataNode1, hcsDataNode2, hcsDataNode3)); @@ -217,6 +241,9 @@ public class ComponentsInstallationCheckTest { Mockito.when(HostComponentSummary.getHostComponentSummaries("TEZ", "TEZ_CLIENT")).thenReturn(Arrays.asList(hcsTezClient)); Mockito.when(HostComponentSummary.getHostComponentSummaries("AMBARI_METRICS", "METRICS_COLLECTOR")).thenReturn(Arrays.asList(hcsMetricsCollector)); Mockito.when(HostComponentSummary.getHostComponentSummaries("AMBARI_METRICS", "METRICS_MONITOR")).thenReturn(Arrays.asList(hcsMetricsMonitor)); + for (String hostName : hosts.keySet()) { + Mockito.when(clusters.getHost(hostName)).thenReturn(hosts.get(hostName)); + } // Case 1. Initialize with good values for (HostComponentSummary hcs : allHostComponentSummaries) { @@ -241,5 +268,20 @@ public class ComponentsInstallationCheckTest { componentsInstallationCheck.perform(check, new PrereqCheckRequest("cluster")); Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus()); Assert.assertTrue(check.getFailReason().indexOf("Service components in INSTALL_FAILED state") > -1); + + // Case 4: Change TEZ client state to INSTALL_FAILED and place TEZ in Maintenance mode, should succeed + Mockito.when(tezService.getMaintenanceState()).thenReturn(MaintenanceState.ON); + Mockito.when(hcsTezClient.getCurrentState()).thenReturn(State.INSTALL_FAILED); + check = new PrerequisiteCheck(null, null); + componentsInstallationCheck.perform(check, new PrereqCheckRequest("cluster")); + Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus()); + + // Case 5: Change TEZ client state to INSTALL_FAILED and place host2 in Maintenance mode, should succeed + Mockito.when(tezService.getMaintenanceState()).thenReturn(MaintenanceState.OFF); + Mockito.when(host2.getMaintenanceState(1L)).thenReturn(MaintenanceState.ON); + Mockito.when(hcsTezClient.getCurrentState()).thenReturn(State.INSTALL_FAILED); + check = new PrerequisiteCheck(null, null); + componentsInstallationCheck.perform(check, new PrereqCheckRequest("cluster")); + Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus()); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/d0c0a5ed/ambari-server/src/test/java/org/apache/ambari/server/checks/InstallPackagesCheckTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/InstallPackagesCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/InstallPackagesCheckTest.java new file mode 100644 index 0000000..18672e3 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/InstallPackagesCheckTest.java @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ambari.server.checks; + +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + +import org.apache.ambari.server.api.services.AmbariMetaInfo; +import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.controller.PrereqCheckRequest; +import org.apache.ambari.server.orm.dao.ClusterVersionDAO; +import org.apache.ambari.server.orm.dao.HostVersionDAO; +import org.apache.ambari.server.orm.entities.ClusterVersionEntity; +import org.apache.ambari.server.orm.entities.HostVersionEntity; +import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; +import org.apache.ambari.server.orm.models.HostComponentSummary; +import org.apache.ambari.server.state.Cluster; +import org.apache.ambari.server.state.Clusters; +import org.apache.ambari.server.state.Host; +import org.apache.ambari.server.state.MaintenanceState; +import org.apache.ambari.server.state.RepositoryVersionState; +import org.apache.ambari.server.state.StackId; +import org.apache.ambari.server.state.stack.PrereqCheckStatus; +import org.apache.ambari.server.state.stack.PrerequisiteCheck; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.google.inject.Provider; + +/** + * Unit tests for InstallPackagesCheck + * + */ +@RunWith(PowerMockRunner.class) // Allow mocking static methods +@PrepareForTest(HostComponentSummary.class) // This class has a static method that will be mocked +public class InstallPackagesCheckTest { + private final Clusters clusters = Mockito.mock(Clusters.class); + private final ClusterVersionDAO clusterVersionDAO = Mockito.mock(ClusterVersionDAO.class); + private final HostVersionDAO hostVersionDAO = Mockito.mock(HostVersionDAO.class); + private AmbariMetaInfo ambariMetaInfo = Mockito.mock(AmbariMetaInfo.class); + private StackId sourceStackId = new StackId("HDP", "2.2"); + private StackId targetStackId = new StackId("HDP", "2.2"); + private String repositoryVersion = "2.2.6.0-1234"; + private String clusterName = "cluster"; + + @Test + public void testIsApplicable() throws Exception { + PrereqCheckRequest checkRequest = new PrereqCheckRequest(clusterName); + checkRequest.setRepositoryVersion(repositoryVersion); + checkRequest.setSourceStackId(sourceStackId); + checkRequest.setTargetStackId(targetStackId); + InstallPackagesCheck ipc = new InstallPackagesCheck(); + Configuration config = Mockito.mock(Configuration.class); + Mockito.when(config.getRollingUpgradeMinStack()).thenReturn("HDP-2.2"); + Mockito.when(config.getRollingUpgradeMaxStack()).thenReturn(""); + ipc.config = config; + + Assert.assertTrue(ipc.isApplicable(checkRequest)); + } + + @Test + public void testPerform() throws Exception { + PowerMockito.mockStatic(HostComponentSummary.class); + + final InstallPackagesCheck installPackagesCheck = new InstallPackagesCheck(); + installPackagesCheck.clustersProvider = new Provider() { + + @Override + public Clusters get() { + return clusters; + } + }; + + installPackagesCheck.ambariMetaInfo = new Provider() { + @Override + public AmbariMetaInfo get() { + return ambariMetaInfo; + } + }; + + installPackagesCheck.clusterVersionDAOProvider = new Provider() { + @Override + public ClusterVersionDAO get() { + return clusterVersionDAO; + } + }; + + installPackagesCheck.hostVersionDaoProvider = new Provider() { + @Override + public HostVersionDAO get() { + return hostVersionDAO; + } + }; + + final Cluster cluster = Mockito.mock(Cluster.class); + Mockito.when(cluster.getClusterName()).thenReturn(clusterName); + Mockito.when(cluster.getClusterId()).thenReturn(1L); + Mockito.when(cluster.getCurrentStackVersion()).thenReturn(new StackId("HDP", "2.2")); + Mockito.when(clusters.getCluster(clusterName)).thenReturn(cluster); + ClusterVersionEntity clusterVersionEntity = Mockito.mock(ClusterVersionEntity.class); + Mockito.when(clusterVersionEntity.getState()).thenReturn(RepositoryVersionState.INSTALLED); + Mockito.when(clusterVersionDAO.findByClusterAndStackAndVersion( + clusterName, targetStackId, repositoryVersion)).thenReturn(clusterVersionEntity); + final List hostNames = new ArrayList(); + hostNames.add("host1"); + hostNames.add("host2"); + hostNames.add("host3"); + RepositoryVersionEntity rve = Mockito.mock(RepositoryVersionEntity.class); + Mockito.when(rve.getVersion()).thenReturn(repositoryVersion); + + final List hosts = new ArrayList(); + final List hostVersionEntities = new ArrayList(); + for(String hostName : hostNames) { + Host host = Mockito.mock(Host.class); + host.setHostName(hostName); + Mockito.when(host.getHostName()).thenReturn(hostName); + Mockito.when(host.getMaintenanceState(1L)).thenReturn(MaintenanceState.OFF); + hosts.add(host); + HostVersionEntity hve = Mockito.mock(HostVersionEntity.class); + Mockito.when(hve.getRepositoryVersion()).thenReturn(rve); + Mockito.when(hve.getState()).thenReturn(RepositoryVersionState.INSTALLED); + hostVersionEntities.add(hve); + Mockito.when(hostVersionDAO.findByHost(hostName)).thenReturn(Collections.singletonList(hve)); + } + Mockito.when(cluster.getHosts()).thenReturn(hosts); + + PrereqCheckRequest checkRequest = new PrereqCheckRequest(clusterName); + checkRequest.setRepositoryVersion(repositoryVersion); + checkRequest.setSourceStackId(sourceStackId); + checkRequest.setTargetStackId(targetStackId); + + // Case 1. Initialize with good values + PrerequisiteCheck check = new PrerequisiteCheck(null, null); + installPackagesCheck.perform(check, checkRequest); + Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus()); + + // Case 2: Install Packages failed on host1 + Mockito.when(hostVersionEntities.get(0).getState()).thenReturn(RepositoryVersionState.INSTALL_FAILED); + Mockito.when(clusterVersionEntity.getState()).thenReturn(RepositoryVersionState.INSTALL_FAILED); + check = new PrerequisiteCheck(null, null); + installPackagesCheck.perform(check, checkRequest); + Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus()); + Assert.assertNotNull(check.getFailedOn()); + Assert.assertTrue(check.getFailedOn().contains("host1")); + + // Case 3: Install Packages failed on host1 and host1 was put in Maintenance Mode + Mockito.when(hostVersionEntities.get(0).getState()).thenReturn(RepositoryVersionState.INSTALL_FAILED); + Mockito.when(hosts.get(0).getMaintenanceState(1L)).thenReturn(MaintenanceState.ON); + Mockito.when(clusterVersionEntity.getState()).thenReturn(RepositoryVersionState.INSTALL_FAILED); + check = new PrerequisiteCheck(null, null); + installPackagesCheck.perform(check, checkRequest); + Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus()); + Assert.assertNotNull(check.getFailedOn()); + Assert.assertTrue(check.getFailedOn().contains(clusterName)); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/d0c0a5ed/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java index 7668545..0176f94 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java @@ -31,6 +31,7 @@ import org.apache.ambari.server.checks.CheckDescription; import org.apache.ambari.server.checks.ServicesUpCheck; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.PrereqCheckRequest; +import org.apache.ambari.server.orm.dao.ClusterVersionDAO; import org.apache.ambari.server.orm.dao.HostVersionDAO; import org.apache.ambari.server.orm.dao.RepositoryVersionDAO; import org.apache.ambari.server.state.stack.OsFamily; @@ -125,6 +126,7 @@ public class CheckHelperTest { @Override protected void configure() { bind(Clusters.class).toInstance(clusters); + bind(ClusterVersionDAO.class).toProvider(Providers.of(null)); bind(HostVersionDAO.class).toProvider(Providers.of(null)); bind(RepositoryVersionDAO.class).toProvider(Providers.of(null)); bind(RepositoryVersionHelper.class).toProvider(Providers.of(null));