You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2015/09/12 15:50:02 UTC

[2/2] ambari git commit: AMBARI-13078 - Upgrade Packs Should Define Skippable Failed Slave/Clients (jonathanhurley)

AMBARI-13078 - Upgrade Packs Should Define Skippable Failed Slave/Clients (jonathanhurley)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e7b946a9
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e7b946a9
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e7b946a9

Branch: refs/heads/branch-2.1
Commit: e7b946a986ac7b25dac3dab1b7df8cfe89888b12
Parents: e96f5bd
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Sep 11 14:39:52 2015 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Sat Sep 12 09:46:12 2015 -0400

----------------------------------------------------------------------
 .../internal/UpgradeResourceProvider.java       |  10 +-
 .../server/orm/entities/UpgradeGroupEntity.java |  13 ++
 .../ambari/server/state/stack/UpgradePack.java  |  45 ++++-
 .../stacks/HDP/2.2/upgrades/upgrade-2.2.xml     |   3 +-
 .../stacks/HDP/2.2/upgrades/upgrade-2.3.xml     |   3 +
 .../stacks/HDP/2.3/upgrades/upgrade-2.3.xml     |   2 +
 .../internal/UpgradeResourceProviderTest.java   | 171 ++++++++++++-------
 .../server/state/stack/UpgradePackTest.java     |  27 ++-
 .../upgrades/upgrade_test_skip_failures.xml     |  52 ++++++
 9 files changed, 246 insertions(+), 80 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/e7b946a9/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index 48e9e1a..653419b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -660,13 +660,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
 
     // optionally skip failures - this can be supplied on either the request or
-    // in the upgrade pack explicitely
-    boolean skipComponentFailures = false;
-    boolean skipServiceCheckFailures = false;
+    // in the upgrade pack explicitely, however the request will always override
+    // the upgrade pack if explicitely specified
+    boolean skipComponentFailures = pack.isComponentFailureAutoSkipped();
+    boolean skipServiceCheckFailures = pack.isServiceCheckFailureAutoSkipped();
+
+    // only override the upgrade pack if set on the request
     if (requestMap.containsKey(UPGRADE_SKIP_FAILURES)) {
       skipComponentFailures = Boolean.parseBoolean((String) requestMap.get(UPGRADE_SKIP_FAILURES));
     }
 
+    // only override the upgrade pack if set on the request
     if (requestMap.containsKey(UPGRADE_SKIP_SC_FAILURES)) {
       skipServiceCheckFailures = Boolean.parseBoolean(
           (String) requestMap.get(UPGRADE_SKIP_SC_FAILURES));

http://git-wip-us.apache.org/repos/asf/ambari/blob/e7b946a9/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeGroupEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeGroupEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeGroupEntity.java
index 7b57184..96f96d5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeGroupEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeGroupEntity.java
@@ -129,5 +129,18 @@ public class UpgradeGroupEntity {
     upgradeItems = items;
   }
 
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String toString() {
+    StringBuilder buffer = new StringBuilder("UpgradeGroupEntity{");
+    buffer.append("upgradeGroupId=").append(upgradeGroupId);
+    buffer.append(", upgradeId=").append(upgradeId);
+    buffer.append(", groupName=").append(groupName);
+    buffer.append(", groupTitle=").append(groupTitle);
+    buffer.append("}");
+    return buffer.toString();
+  }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e7b946a9/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
index 3e9aa5f..5b65732 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
@@ -50,7 +50,6 @@ public class UpgradePack {
   @XmlElement(name="target-stack")
   private String targetStack;
 
-
   @XmlElementWrapper(name="order")
   @XmlElement(name="group")
   private List<Grouping> groups;
@@ -59,13 +58,30 @@ public class UpgradePack {
   @XmlElement(name="service")
   private List<ProcessingService> processing;
 
+  /**
+   * {@code true} to automatically skip slave/client component failures. The
+   * default is {@code false}.
+   */
+  @XmlElement(name = "skip-failures")
+  private boolean skipFailures = false;
+
+  /**
+   * {@code true} to automatically skip service check failures. The default is
+   * {@code false}.
+   */
+  @XmlElement(name = "skip-service-check-failures")
+  private boolean skipServiceCheckFailures = false;
+
   @XmlTransient
   private Map<String, List<String>> m_orders = null;
+
   @XmlTransient
   private Map<String, Map<String, ProcessingComponent>> m_process = null;
+
   @XmlTransient
   private boolean m_resolvedGroups = false;
 
+
   /**
    * @return the target version for the upgrade pack
    */
@@ -81,9 +97,30 @@ public class UpgradePack {
   }
 
   /**
-   * Gets the groups defined for the upgrade pack.  If a direction is defined
-   * for a group, it must match the supplied direction to be returned
-   * @param direction the direction to return the ordered groups
+   * Gets whether skippable components that failed are automatically skipped.
+   *
+   * @return the skipComponentFailures
+   */
+  public boolean isComponentFailureAutoSkipped() {
+    return skipFailures;
+  }
+
+  /**
+   * Gets whether skippable service checks that failed are automatically
+   * skipped.
+   *
+   * @return the skipServiceCheckFailures
+   */
+  public boolean isServiceCheckFailureAutoSkipped() {
+    return skipServiceCheckFailures;
+  }
+
+  /**
+   * Gets the groups defined for the upgrade pack. If a direction is defined for
+   * a group, it must match the supplied direction to be returned
+   * 
+   * @param direction
+   *          the direction to return the ordered groups
    * @return the list of groups
    */
   public List<Grouping> getGroups(Direction direction) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/e7b946a9/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.2.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.2.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.2.xml
index 7d2b9aa..3837e63 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.2.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.2.xml
@@ -19,9 +19,10 @@
 
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <target>2.2.*.*</target>
+  <skip-failures>false</skip-failures>
+  <skip-service-check-failures>false</skip-service-check-failures>
 
   <order>
-
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
       <direction>UPGRADE</direction>
       <execute-stage service="HDFS" component="NAMENODE" title="Pre Upgrade HDFS">

http://git-wip-us.apache.org/repos/asf/ambari/blob/e7b946a9/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml
index c9b09b5..e7c55a6 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml
@@ -20,6 +20,9 @@
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <target>2.3.*.*</target>
   <target-stack>HDP-2.3</target-stack>
+  <skip-failures>false</skip-failures>
+  <skip-service-check-failures>false</skip-service-check-failures>
+
   <order>
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
       <direction>UPGRADE</direction>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e7b946a9/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.3.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.3.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.3.xml
index 3b48322..acc65a6 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.3.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.3.xml
@@ -19,6 +19,8 @@
 
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <target>2.3.*.*</target>
+  <skip-failures>false</skip-failures>
+  <skip-service-check-failures>false</skip-service-check-failures>
 
   <order>
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">

http://git-wip-us.apache.org/repos/asf/ambari/blob/e7b946a9/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 cf0cf4c..9873104 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
@@ -36,7 +36,6 @@ import java.util.Set;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
-import org.apache.ambari.server.actionmanager.RequestStatus;
 import org.apache.ambari.server.actionmanager.Stage;
 import org.apache.ambari.server.api.resources.UpgradeResourceDefinition;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -44,6 +43,7 @@ import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariServer;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.RequestStatus;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
@@ -64,6 +64,7 @@ import org.apache.ambari.server.orm.entities.StageEntity;
 import org.apache.ambari.server.orm.entities.UpgradeEntity;
 import org.apache.ambari.server.orm.entities.UpgradeGroupEntity;
 import org.apache.ambari.server.orm.entities.UpgradeItemEntity;
+import org.apache.ambari.server.serveraction.upgrades.AutoSkipFailedSummaryAction;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
@@ -233,90 +234,43 @@ public class UpgradeResourceProviderTest {
     injector = null;
   }
 
-  private org.apache.ambari.server.controller.spi.RequestStatus testCreateResources() throws Exception {
-
+  @Test
+  public void testCreateResourcesWithAutoSkipFailures() throws Exception {
     Cluster cluster = clusters.getCluster("c1");
 
-    List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
-    assertEquals(0, upgrades.size());
-
     Map<String, Object> requestProps = new HashMap<String, Object>();
     requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
     requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.1.1.1");
+    requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_FAILURES, Boolean.TRUE.toString());
+    requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_SC_FAILURES, Boolean.TRUE.toString());
 
     ResourceProvider upgradeResourceProvider = createProvider(amc);
-
     Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
-    org.apache.ambari.server.controller.spi.RequestStatus status = upgradeResourceProvider.createResources(request);
+    upgradeResourceProvider.createResources(request);
 
-    upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
+    List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
     assertEquals(1, upgrades.size());
 
     UpgradeEntity entity = upgrades.get(0);
     assertEquals(cluster.getClusterId(), entity.getClusterId().longValue());
 
-    StageDAO stageDAO = injector.getInstance(StageDAO.class);
-    List<StageEntity> stageEntities = stageDAO.findByRequestId(entity.getRequestId());
-    Gson gson = new Gson();
-    for (StageEntity se : stageEntities) {
-      Map<String, String> map = gson.<Map<String, String>>fromJson(se.getCommandParamsStage(), Map.class);
-      assertTrue(map.containsKey("upgrade_direction"));
-      assertEquals("upgrade", map.get("upgrade_direction"));
-    }
-
     List<UpgradeGroupEntity> upgradeGroups = entity.getUpgradeGroups();
     assertEquals(3, upgradeGroups.size());
 
-    UpgradeGroupEntity group = upgradeGroups.get(1);
-    assertEquals(4, group.getItems().size());
-
-    assertTrue(group.getItems().get(0).getText().contains(
-        "placeholder of placeholder-rendered-properly"));
-
-    assertTrue(group.getItems().get(1).getText().contains("Restarting"));
-    assertTrue(group.getItems().get(2).getText().contains("Skipping"));
-    assertTrue(group.getItems().get(3).getText().contains("Service Check"));
-
-    ActionManager am = injector.getInstance(ActionManager.class);
-    List<Long> requests = am.getRequestsByStatus(RequestStatus.IN_PROGRESS, 100, true);
-
-    assertEquals(1, requests.size());
-    assertEquals(requests.get(0), entity.getRequestId());
+    UpgradeGroupEntity zookeeperGroup = upgradeGroups.get(1);
+    assertEquals("ZOOKEEPER", zookeeperGroup.getName());
 
-    List<Stage> stages = am.getRequestStatus(requests.get(0).longValue());
-
-    assertEquals(8, stages.size());
+    List<UpgradeItemEntity> upgradeItems = zookeeperGroup.getItems();
+    assertEquals(5, upgradeItems.size());
 
-    List<HostRoleCommand> tasks = am.getRequestTasks(requests.get(0).longValue());
-    // same number of tasks as stages here
-    assertEquals(8, tasks.size());
-
-    Set<Long> slaveStageIds = new HashSet<Long>();
-
-    UpgradeGroupEntity coreSlavesGroup = upgradeGroups.get(1);
-
-    for (UpgradeItemEntity itemEntity : coreSlavesGroup.getItems()) {
-      slaveStageIds.add(itemEntity.getStageId());
-    }
-
-    for (Stage stage : stages) {
-
-      // For this test the core slaves group stages should be skippable and NOT allow retry.
-      assertEquals(slaveStageIds.contains(stage.getStageId()), stage.isSkippable());
-
-      for (Map<String, HostRoleCommand> taskMap : stage.getHostRoleCommands().values()) {
-
-        for (HostRoleCommand task : taskMap.values()) {
-          assertEquals(!slaveStageIds.contains(stage.getStageId()), task.isRetryAllowed());
-        }
-      }
-    }
-    return status;
+    // the last upgrade item is the skipped failure check
+    UpgradeItemEntity skippedFailureCheck = upgradeItems.get(upgradeItems.size() - 1);
+    skippedFailureCheck.getTasks().contains(AutoSkipFailedSummaryAction.class.getName());
   }
 
   @Test
   public void testGetResources() throws Exception {
-    org.apache.ambari.server.controller.spi.RequestStatus status = testCreateResources();
+    RequestStatus status = testCreateResources();
 
     Set<Resource> createdResources = status.getAssociatedResources();
     assertEquals(1, createdResources.size());
@@ -482,7 +436,8 @@ public class UpgradeResourceProviderTest {
     ResourceProvider upgradeResourceProvider = createProvider(amc);
 
     Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
-    org.apache.ambari.server.controller.spi.RequestStatus status = upgradeResourceProvider.createResources(request);
+    RequestStatus status = upgradeResourceProvider.createResources(
+        request);
 
     List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
     assertEquals(1, upgrades.size());
@@ -531,7 +486,7 @@ public class UpgradeResourceProviderTest {
 
   @Test
   public void testAbort() throws Exception {
-    org.apache.ambari.server.controller.spi.RequestStatus status = testCreateResources();
+    RequestStatus status = testCreateResources();
 
     Set<Resource> createdResources = status.getAssociatedResources();
     assertEquals(1, createdResources.size());
@@ -553,7 +508,7 @@ public class UpgradeResourceProviderTest {
 
   @Test
   public void testRetry() throws Exception {
-    org.apache.ambari.server.controller.spi.RequestStatus status = testCreateResources();
+    RequestStatus status = testCreateResources();
 
     Set<Resource> createdResources = status.getAssociatedResources();
     assertEquals(1, createdResources.size());
@@ -653,7 +608,7 @@ public class UpgradeResourceProviderTest {
 
   @Test
   public void testPercents() throws Exception {
-    org.apache.ambari.server.controller.spi.RequestStatus status = testCreateResources();
+    RequestStatus status = testCreateResources();
 
     Set<Resource> createdResources = status.getAssociatedResources();
     assertEquals(1, createdResources.size());
@@ -888,6 +843,90 @@ public class UpgradeResourceProviderTest {
     return new UpgradeResourceProvider(amc);
   }
 
+  private RequestStatus testCreateResources() throws Exception {
+
+    Cluster cluster = clusters.getCluster("c1");
+
+    List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
+    assertEquals(0, upgrades.size());
+
+    Map<String, Object> requestProps = new HashMap<String, Object>();
+    requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
+    requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.1.1.1");
+
+    ResourceProvider upgradeResourceProvider = createProvider(amc);
+
+    Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
+    RequestStatus status = upgradeResourceProvider.createResources(request);
+
+    upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
+    assertEquals(1, upgrades.size());
+
+    UpgradeEntity entity = upgrades.get(0);
+    assertEquals(cluster.getClusterId(), entity.getClusterId().longValue());
+
+    StageDAO stageDAO = injector.getInstance(StageDAO.class);
+    List<StageEntity> stageEntities = stageDAO.findByRequestId(entity.getRequestId());
+    Gson gson = new Gson();
+    for (StageEntity se : stageEntities) {
+      Map<String, String> map = gson.<Map<String, String>> fromJson(se.getCommandParamsStage(),
+          Map.class);
+      assertTrue(map.containsKey("upgrade_direction"));
+      assertEquals("upgrade", map.get("upgrade_direction"));
+    }
+
+    List<UpgradeGroupEntity> upgradeGroups = entity.getUpgradeGroups();
+    assertEquals(3, upgradeGroups.size());
+
+    UpgradeGroupEntity group = upgradeGroups.get(1);
+    assertEquals(4, group.getItems().size());
+
+    assertTrue(
+        group.getItems().get(0).getText().contains("placeholder of placeholder-rendered-properly"));
+
+    assertTrue(group.getItems().get(1).getText().contains("Restarting"));
+    assertTrue(group.getItems().get(2).getText().contains("Skipping"));
+    assertTrue(group.getItems().get(3).getText().contains("Service Check"));
+
+    ActionManager am = injector.getInstance(ActionManager.class);
+    List<Long> requests = am.getRequestsByStatus(
+        org.apache.ambari.server.actionmanager.RequestStatus.IN_PROGRESS, 100, true);
+
+    assertEquals(1, requests.size());
+    assertEquals(requests.get(0), entity.getRequestId());
+
+    List<Stage> stages = am.getRequestStatus(requests.get(0).longValue());
+
+    assertEquals(8, stages.size());
+
+    List<HostRoleCommand> tasks = am.getRequestTasks(requests.get(0).longValue());
+    // same number of tasks as stages here
+    assertEquals(8, tasks.size());
+
+    Set<Long> slaveStageIds = new HashSet<Long>();
+
+    UpgradeGroupEntity coreSlavesGroup = upgradeGroups.get(1);
+
+    for (UpgradeItemEntity itemEntity : coreSlavesGroup.getItems()) {
+      slaveStageIds.add(itemEntity.getStageId());
+    }
+
+    for (Stage stage : stages) {
+
+      // For this test the core slaves group stages should be skippable and NOT
+      // allow retry.
+      assertEquals(slaveStageIds.contains(stage.getStageId()), stage.isSkippable());
+
+      for (Map<String, HostRoleCommand> taskMap : stage.getHostRoleCommands().values()) {
+
+        for (HostRoleCommand task : taskMap.values()) {
+          assertEquals(!slaveStageIds.contains(stage.getStageId()), task.isRetryAllowed());
+        }
+      }
+    }
+    return status;
+  }
+
   /**
    *
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/e7b946a9/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java
index e073b43..9ae78c4 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java
@@ -44,6 +44,7 @@ import org.apache.ambari.server.state.stack.upgrade.ServiceCheckGrouping;
 import org.apache.ambari.server.state.stack.upgrade.Task;
 import org.apache.ambari.server.state.stack.upgrade.TransferOperation;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -156,12 +157,12 @@ public class UpgradePackTest {
     assertEquals(4, ct.getTransfers().size());
 
     /*
-            <transfer operation="COPY" from-key="copy-key" to-key="copy-key-to" />
-            <transfer operation="COPY" from-type="my-site" from-key="my-copy-key" to-key="my-copy-key-to" />
-            <transfer operation="MOVE" from-key="move-key" to-key="move-key-to" />
-            <transfer operation="DELETE" delete-key="delete-key">
-              <keep-key>important-key</keep-key>
-            </transfer>
+    <transfer operation="COPY" from-key="copy-key" to-key="copy-key-to" />
+    <transfer operation="COPY" from-type="my-site" from-key="my-copy-key" to-key="my-copy-key-to" />
+    <transfer operation="MOVE" from-key="move-key" to-key="move-key-to" />
+    <transfer operation="DELETE" delete-key="delete-key">
+      <keep-key>important-key</keep-key>
+    </transfer>
     */
     Transfer t1 = ct.getTransfers().get(0);
     assertEquals(TransferOperation.COPY, t1.operation);
@@ -283,7 +284,21 @@ public class UpgradePackTest {
     group = groups.get(2);
     assertEquals(ClusterGrouping.class, group.getClass());
     assertEquals("Finalize Upgrade", group.title);
+  }
+
+  @Test
+  public void testSkippableFailures() throws Exception {
+    Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
+    Set<String> keys = upgrades.keySet();
+    for (String key : keys) {
+      Assert.assertFalse(upgrades.get(key).isComponentFailureAutoSkipped());
+      Assert.assertFalse(upgrades.get(key).isServiceCheckFailureAutoSkipped());
+    }
 
+    upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.2.0");
+    UpgradePack upgradePack = upgrades.get("upgrade_test_skip_failures");
+    Assert.assertTrue(upgradePack.isComponentFailureAutoSkipped());
+    Assert.assertTrue(upgradePack.isServiceCheckFailureAutoSkipped());
   }
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e7b946a9/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_skip_failures.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_skip_failures.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_skip_failures.xml
new file mode 100644
index 0000000..467e63a
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_skip_failures.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+   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.
+-->
+<upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <target>2.2.*</target>
+  <skip-failures>true</skip-failures>
+  <skip-service-check-failures>true</skip-service-check-failures>
+  
+  <order>
+    <group name="ZOOKEEPER" title="Zookeeper">
+      <skippable>true</skippable>
+      <allow-retry>false</allow-retry>
+      <service name="ZOOKEEPER">
+        <component>ZOOKEEPER_SERVER</component>
+        <component>ZOOKEEPER_CLIENT</component>
+      </service>
+    </group>
+  </order>  
+
+  <processing>
+    <service name="ZOOKEEPER">
+      <component name="ZOOKEEPER_SERVER">
+        <pre-upgrade>
+          <task xsi:type="manual">
+            <summary>SUMMARY OF PREPARE</summary>
+            <message>This is a manual task with a placeholder of {{foo/bar}}</message>
+          </task>
+        </pre-upgrade>
+        <upgrade>
+          <task xsi:type="restart" />
+        </upgrade>
+        <post-upgrade>
+          <task xsi:type="configure" />
+        </post-upgrade>
+      </component>
+    </service>
+  </processing>
+</upgrade>