ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jlun...@apache.org
Subject ambari git commit: AMBARI-13708: RU/EU: invalid state transition, INSTALL_FAILED (cannot Finalize) (jluniya)
Date Wed, 04 Nov 2015 21:41:48 GMT
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 <jluniya@hortonworks.com>
Authored: Wed Nov 4 13:40:48 2015 -0800
Committer: Jayush Luniya <jluniya@hortonworks.com>
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<Clusters> clustersProvider;
 
   @Inject
+  Provider<ClusterVersionDAO> clusterVersionDAOProvider;
+
+  @Inject
   Provider<HostVersionDAO> 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<String, String>() {{
+        put(AbstractCheckDescriptor.DEFAULT,
+            "Re-run Install Packages before starting upgrade");
+      }}),
+
   SERVICES_YARN_WP(PrereqCheckType.SERVICE,
       "YARN work preserving restart should be enabled",
       new HashMap<String, String>() {{

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<String> errorMessages = new ArrayList<String>();
     Set<String> failedServiceNames = new HashSet<String>();
 
     StackId stackId = cluster.getCurrentStackVersion();
@@ -68,20 +68,25 @@ public class ComponentsInstallationCheck extends AbstractCheckDescriptor
{
 
     for (Map.Entry<String, Service> serviceEntry : cluster.getServices().entrySet())
{
       final Service service = serviceEntry.getValue();
-      Map<String, ServiceComponent> serviceComponents = service.getServiceComponents();
+      // Skip service if it is in maintenance mode
+      if (service.getMaintenanceState() != MaintenanceState.ON) {
+        Map<String, ServiceComponent> serviceComponents = service.getServiceComponents();
+        for (Map.Entry<String, ServiceComponent> component : serviceComponents.entrySet())
{
+          ServiceComponent serviceComponent = component.getValue();
+          if (serviceComponent.isVersionAdvertised()) {
+            List<HostComponentSummary> hostComponentSummaries = HostComponentSummary.getHostComponentSummaries(
+                service.getName(), serviceComponent.getName());
 
-      for (Map.Entry<String, ServiceComponent> component : serviceComponents.entrySet())
{
-        ServiceComponent serviceComponent = component.getValue();
-
-        if (serviceComponent.isVersionAdvertised()) {
-          List<HostComponentSummary> 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<String> failedHosts = new HashSet<String>();
+
+    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<String>(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<String> failedOn = new LinkedHashSet<String>();
+      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<String> hostsWithState = new HashSet<String>();
+      Set<String> 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<String, Service> clusterServices = new HashMap<String, Service>();
     clusterServices.put("HDFS", hdfsService);
@@ -210,6 +215,25 @@ public class ComponentsInstallationCheckTest {
     allHostComponentSummaries.add(hcsMetricsCollector);
     allHostComponentSummaries.add(hcsMetricsMonitor);
 
+    final Map<String, Host> hosts = new HashMap<String, Host>();
+    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<Clusters>() {
+
+      @Override
+      public Clusters get() {
+        return clusters;
+      }
+    };
+
+    installPackagesCheck.ambariMetaInfo = new Provider<AmbariMetaInfo>() {
+      @Override
+      public AmbariMetaInfo get() {
+        return ambariMetaInfo;
+      }
+    };
+
+    installPackagesCheck.clusterVersionDAOProvider = new Provider<ClusterVersionDAO>()
{
+      @Override
+      public ClusterVersionDAO get() {
+        return clusterVersionDAO;
+      }
+    };
+
+    installPackagesCheck.hostVersionDaoProvider = new Provider<HostVersionDAO>() {
+      @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<String> hostNames = new ArrayList<String>();
+    hostNames.add("host1");
+    hostNames.add("host2");
+    hostNames.add("host3");
+    RepositoryVersionEntity rve = Mockito.mock(RepositoryVersionEntity.class);
+    Mockito.when(rve.getVersion()).thenReturn(repositoryVersion);
+
+    final List<Host> hosts = new ArrayList<Host>();
+    final List<HostVersionEntity> hostVersionEntities = new ArrayList<HostVersionEntity>();
+    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.<ClusterVersionDAO>of(null));
         bind(HostVersionDAO.class).toProvider(Providers.<HostVersionDAO>of(null));
         bind(RepositoryVersionDAO.class).toProvider(Providers.<RepositoryVersionDAO>of(null));
         bind(RepositoryVersionHelper.class).toProvider(Providers.<RepositoryVersionHelper>of(null));


Mime
View raw message