You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2014/11/11 21:47:30 UTC

ambari git commit: AMBARI-8270. Create DAO and Unit Tests for ClusterVersion (alejandro)

Repository: ambari
Updated Branches:
  refs/heads/trunk e4ededeb6 -> 1b320cc7a


AMBARI-8270. Create DAO and Unit Tests for ClusterVersion (alejandro)


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

Branch: refs/heads/trunk
Commit: 1b320cc7acfb5cae696662c2d3fd0924ceb4c2fc
Parents: e4edede
Author: Alejandro Fernandez <af...@hortonworks.com>
Authored: Mon Nov 10 18:22:12 2014 -0800
Committer: Alejandro Fernandez <af...@hortonworks.com>
Committed: Tue Nov 11 12:47:13 2014 -0800

----------------------------------------------------------------------
 .../server/orm/dao/ClusterVersionDAO.java       | 169 +++++++++++++
 .../orm/entities/ClusterVersionEntity.java      |  52 +++-
 .../server/orm/entities/HostVersionEntity.java  |   1 -
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |   2 +-
 .../server/orm/dao/ClusterVersionDAOTest.java   | 241 +++++++++++++++++++
 5 files changed, 462 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/1b320cc7/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
new file mode 100644
index 0000000..b39497c
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
@@ -0,0 +1,169 @@
+/**
+ * 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.orm.dao;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
+import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.state.ClusterVersionState;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.NonUniqueResultException;
+import javax.persistence.TypedQuery;
+import java.util.List;
+
+/**
+ * The {@link ClusterVersionDAO} class manages the {@link ClusterVersionEntity} instances associated with a cluster.
+ * Each cluster can have multiple stack versions {@link ClusterVersionState#INSTALLED},
+ * exactly one stack version that is {@link ClusterVersionState#CURRENT}, and at most one
+ * stack version that is {@link ClusterVersionState#UPGRADING}.
+ */
+@Singleton
+public class ClusterVersionDAO {
+  @Inject
+  Provider<EntityManager> entityManagerProvider;
+  @Inject
+  DaoUtils daoUtils;
+
+  /**
+   * Get the object with the given id.
+   *
+   * @param id Primary key id
+   * @return Return the object with the given primary key
+   */
+  @RequiresSession
+  public ClusterVersionEntity findByPK(long id) {
+    return entityManagerProvider.get().find(ClusterVersionEntity.class, id);
+  }
+
+  /**
+   * Retrieve all of the cluster versions for the given stack and version.
+   *
+   * @param stack Stack name (e.g., HDP)
+   * @param version Stack version (e.g., 2.2.0.1-995)
+   * @return Return a list of cluster versions that match the stack and version.
+   */
+  @RequiresSession
+  public List<ClusterVersionEntity> findByStackAndVersion(String stack, String version) {
+    final TypedQuery<ClusterVersionEntity> query = entityManagerProvider.get().createNamedQuery("clusterVersionByStackVersion", ClusterVersionEntity.class);
+    query.setParameter("stack", stack);
+    query.setParameter("version", version);
+    
+    return daoUtils.selectList(query);
+  }
+
+  /**
+   * Get the cluster version for the given cluster name, stack name, and stack version.
+   *
+   * @param clusterName Cluster name
+   * @param stack Stack name (e.g., HDP)
+   * @param version Stack version (e.g., 2.2.0.1-995)
+   * @return Return all of the cluster versions associated with the given cluster.
+   */
+  @RequiresSession
+  public ClusterVersionEntity findByClusterAndStackAndVersion(String  clusterName, String stack, String version) {
+    final TypedQuery<ClusterVersionEntity> query = entityManagerProvider.get()
+        .createNamedQuery("clusterVersionByClusterAndStackAndVersion", ClusterVersionEntity.class);
+    query.setParameter("clusterName", clusterName);
+    query.setParameter("stack", stack);
+    query.setParameter("version", version);
+
+    return daoUtils.selectSingle(query);
+  }
+
+  /**
+   * Retrieve the single cluster version whose state is {@link ClusterVersionState#CURRENT}, of which there should be exactly one at all times
+   * for the given cluster.
+   *
+   * @param clusterName Cluster name
+   * @return Returns the single cluster version for this cluster whose state is {@link ClusterVersionState#CURRENT}, or {@code null} otherwise.
+   */
+  @RequiresSession
+  public ClusterVersionEntity findByClusterAndStateCurrent(String clusterName) {
+    final TypedQuery<ClusterVersionEntity> query = entityManagerProvider.get()
+        .createNamedQuery("clusterVersionByClusterAndState", ClusterVersionEntity.class);
+    query.setParameter("clusterName", clusterName);
+    query.setParameter("state", ClusterVersionState.CURRENT);
+
+    try {
+      List results = query.getResultList();
+      if (results.isEmpty()) {
+        return null;
+      } else {
+        if (results.size() == 1) {
+          return (ClusterVersionEntity) results.get(0);
+        }
+      }
+      throw new NonUniqueResultException();
+    } catch (NoResultException ignored) {
+      return null;
+    }
+  }
+
+  /**
+   * Retrieve all of the cluster versions for the cluster with the given name and a state.
+   *
+   * @param clusterName Cluster name
+   * @param state Cluster version state
+   * @return Returns a list of cluster versions for the given cluster and a state.
+   */
+  @RequiresSession
+  public List<ClusterVersionEntity> findByClusterAndState(String clusterName, ClusterVersionState state) {
+    final TypedQuery<ClusterVersionEntity> query = entityManagerProvider.get()
+        .createNamedQuery("clusterVersionByClusterAndState", ClusterVersionEntity.class);
+    query.setParameter("clusterName", clusterName);
+    query.setParameter("state", state);
+
+    return daoUtils.selectList(query);
+  }
+
+  @RequiresSession
+  public List<ClusterVersionEntity> findAll() {
+    return daoUtils.selectAll(entityManagerProvider.get(), ClusterVersionEntity.class);
+  }
+
+  @Transactional
+  public void refresh(ClusterVersionEntity clusterVersionEntity) {
+    entityManagerProvider.get().refresh(clusterVersionEntity);
+  }
+
+  @Transactional
+  public void create(ClusterVersionEntity clusterVersionEntity) {
+    entityManagerProvider.get().persist(clusterVersionEntity);
+  }
+
+  @Transactional
+  public ClusterVersionEntity merge(ClusterVersionEntity clusterVersionEntity) {
+    return entityManagerProvider.get().merge(clusterVersionEntity);
+  }
+
+  @Transactional
+  public void remove(ClusterVersionEntity clusterVersionEntity) {
+    entityManagerProvider.get().remove(merge(clusterVersionEntity));
+  }
+
+  @Transactional
+  public void removeByPK(long id) {
+    remove(findByPK(id));
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/1b320cc7/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java
index 9daa70e..46476da 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java
@@ -30,6 +30,8 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
+import javax.persistence.NamedQuery;
+import javax.persistence.NamedQueries;
 import javax.persistence.TableGenerator;
 import javax.persistence.Table;
 import javax.persistence.Temporal;
@@ -47,6 +49,16 @@ import static org.apache.commons.lang.StringUtils.defaultString;
     , initialValue = 0
     , allocationSize = 1
 )
+@NamedQueries({
+    @NamedQuery(name = "clusterVersionByClusterAndStackAndVersion", query =
+        "SELECT clusterVersion FROM ClusterVersionEntity clusterVersion JOIN clusterVersion.clusterEntity cluster " +
+        "WHERE cluster.clusterName=:clusterName AND clusterVersion.stack=:stack AND clusterVersion.version=:version"),
+    @NamedQuery(name = "clusterVersionByClusterAndState", query =
+        "SELECT clusterVersion FROM ClusterVersionEntity clusterVersion JOIN clusterVersion.clusterEntity cluster " +
+        "WHERE cluster.clusterName=:clusterName AND clusterVersion.state=:state"),
+    @NamedQuery(name = "clusterVersionByStackVersion",
+        query = "SELECT clusterVersion FROM ClusterVersionEntity clusterVersion WHERE clusterVersion.stack=:stack AND clusterVersion.version=:version"),
+})
 public class ClusterVersionEntity {
 
   @Id
@@ -54,7 +66,6 @@ public class ClusterVersionEntity {
   @GeneratedValue(strategy = GenerationType.TABLE, generator = "cluster_version_id_generator")
   private Long id;
 
-  @Id
   @Column(name = "cluster_id", nullable = false, insertable = false, updatable = false)
   private Long clusterId;
 
@@ -86,6 +97,45 @@ public class ClusterVersionEntity {
   @Column(name = "user_name", insertable = true, updatable = true)
   private String userName = "";
 
+  /**
+   * Empty constructor primarily used by unit tests.
+   */
+  public ClusterVersionEntity() {
+  }
+
+  /**
+   * Full constructor that doesn't have the endTime
+   * @param cluster Cluster entity
+   * @param stack Stack name (e.g., HDP)
+   * @param version Stack version (e.g., 2.2.0.0-995)
+   * @param state Cluster version state
+   * @param startTime Time the cluster version reached its first state
+   * @param userName User who performed the action
+   */
+  public ClusterVersionEntity(ClusterEntity cluster, String stack, String version, ClusterVersionState state, long startTime, String userName) {
+    this.clusterId = cluster.getClusterId();
+    this.clusterEntity = cluster;
+    this.stack = stack;
+    this.version = version;
+    this.state = state;
+    this.startTime = startTime;
+    this.userName = userName;
+  }
+
+  /**
+   * Full constructor that does have the endTime
+   * @param cluster Cluster entity
+   * @param stack Stack name (e.g., HDP)
+   * @param version Stack version (e.g., 2.2.0.0-995)
+   * @param state Cluster version state
+   * @param startTime Time the cluster version reached its first state
+   * @param endTime Time the cluster version finalized its state
+   * @param userName User who performed the action
+   */
+  public ClusterVersionEntity(ClusterEntity cluster, String stack, String version, ClusterVersionState state, long startTime, long endTime, String userName) {
+    this(cluster, stack, version, state, startTime, userName);
+    this.endTime = endTime;
+  }
 
   public Long getId() {
     return id;

http://git-wip-us.apache.org/repos/asf/ambari/blob/1b320cc7/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
index f0a0695..6bad11b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
@@ -51,7 +51,6 @@ public class HostVersionEntity {
   private Long id;
 
   @Column(name = "host_name", nullable = false, insertable = false, updatable = false)
-  @Id
   private String hostName;
 
   @ManyToOne

http://git-wip-us.apache.org/repos/asf/ambari/blob/1b320cc7/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index 641e3f0..9b7f6a1 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -367,7 +367,7 @@ BEGIN;
   union all
   select 'config_id_seq', 1
   union all
-  select 'repo_version_id_seq', 0;
+  select 'repo_version_id_seq', 0
   union all
   select 'cluster_version_id_seq', 0
   union all

http://git-wip-us.apache.org/repos/asf/ambari/blob/1b320cc7/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java
new file mode 100644
index 0000000..15fcb41
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java
@@ -0,0 +1,241 @@
+/**
+ * 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.orm.dao;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+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.entities.ClusterEntity;
+import org.apache.ambari.server.state.ClusterVersionState;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.junit.Assert;
+
+
+/**
+ * ClusterVersionDAO unit tests.
+ */
+public class ClusterVersionDAOTest {
+
+  private static Injector injector;
+  private ClusterVersionDAO clusterVersionDAO;
+  private ClusterDAO clusterDAO;
+  private OrmTestHelper helper;
+
+  private long clusterId;
+  ClusterEntity cluster;
+  private int lastStep = -1;
+
+  ClusterVersionEntity cvA;
+  long cvAId = 0L;
+
+  ClusterVersionEntity cvB;
+  long cvBId = 0L;
+
+  ClusterVersionEntity cvC;
+  long cvCId = 0L;
+
+  @Before
+  public void before() {
+    injector = Guice.createInjector(new InMemoryDefaultTestModule());
+    clusterVersionDAO = injector.getInstance(ClusterVersionDAO.class);
+    clusterDAO = injector.getInstance(ClusterDAO.class);
+    helper = injector.getInstance(OrmTestHelper.class);
+    injector.getInstance(GuiceJpaInitializer.class);
+  }
+
+  /**
+   * Helper function to transition the cluster through several cluster versions.
+   * @param currStep Step to go to is a value from 1 - 7, inclusive.
+   */
+  private void createRecordsUntilStep(int currStep) {
+    // Fresh install on A
+    if (currStep >= 1 && lastStep <= 0) {
+      clusterId = helper.createCluster();
+      cluster = clusterDAO.findById(clusterId);
+
+      cvA = new ClusterVersionEntity(cluster, "HDP", "2.2.0.0-995", ClusterVersionState.CURRENT, System.currentTimeMillis(), System.currentTimeMillis(), "admin");
+      clusterVersionDAO.create(cvA);
+      cvAId = cvA.getId();
+    } else {
+      cluster = clusterDAO.findById(clusterId);
+      cvA = clusterVersionDAO.findByPK(cvAId);
+    }
+
+    // Install B
+    if (currStep >= 2) {
+      if (lastStep <= 1) {
+        cvB = new ClusterVersionEntity(cluster, "HDP", "2.2.0.1-998", ClusterVersionState.INSTALLED, System.currentTimeMillis(), System.currentTimeMillis(), "admin");
+        clusterVersionDAO.create(cvB);
+        cvBId = cvB.getId();
+      } else {
+        cvB = clusterVersionDAO.findByPK(cvBId);
+      }
+    }
+
+    // Switch from A to B
+    if (currStep >= 3 && lastStep <= 2) {
+      cvA.setState(ClusterVersionState.CURRENT.INSTALLED);
+      cvB.setState(ClusterVersionState.CURRENT.CURRENT);
+      clusterVersionDAO.merge(cvA);
+      clusterVersionDAO.merge(cvB);
+    }
+
+    // Start upgrading C
+    if (currStep >= 4) {
+      if (lastStep <= 3) {
+        cvC = new ClusterVersionEntity(cluster, "HDP", "2.2.1.0-100", ClusterVersionState.UPGRADING, System.currentTimeMillis(), "admin");
+        clusterVersionDAO.create(cvC);
+        cvCId = cvC.getId();
+      } else {
+        cvC = clusterVersionDAO.findByPK(cvCId);
+      }
+    }
+
+    // Fail upgrade for C
+    if (currStep >= 5 && lastStep <= 4) {
+        cvC.setState(ClusterVersionState.CURRENT.UPGRADE_FAILED);
+        cvC.setEndTime(System.currentTimeMillis());
+        clusterVersionDAO.merge(cvC);
+    }
+
+    // Retry upgrade on C
+    if (currStep >= 6 && lastStep <= 5) {
+        cvC.setState(ClusterVersionState.CURRENT.UPGRADING);
+        cvC.setEndTime(0L);
+        clusterVersionDAO.merge(cvC);
+    }
+
+    // Finalize upgrade on C to make it the current cluster version
+    if (currStep >= 7 && lastStep <= 6) {
+        cvC.setState(ClusterVersionState.CURRENT);
+        cvC.setEndTime(System.currentTimeMillis());
+        clusterVersionDAO.merge(cvC);
+
+        cvA.setState(ClusterVersionState.INSTALLED);
+        cvB.setState(ClusterVersionState.INSTALLED);
+        clusterVersionDAO.merge(cvA);
+        clusterVersionDAO.merge(cvB);
+    }
+
+    this.lastStep = currStep;
+  }
+
+  @Test
+  public void testFindByStackAndVersion() {
+    createRecordsUntilStep(1);
+    Assert.assertEquals(0, clusterVersionDAO.findByStackAndVersion("non existing", "non existing").size());
+    Assert.assertEquals(1, clusterVersionDAO.findByStackAndVersion("HDP", "2.2.0.0-995").size());
+  }
+
+  @Test
+  public void TestFindByClusterAndStackAndVersion() {
+    createRecordsUntilStep(1);
+    Assert.assertNull(clusterVersionDAO.findByClusterAndStackAndVersion(cluster.getClusterName(), "non existing", "non existing"));
+    Assert.assertNotNull(clusterVersionDAO.findByClusterAndStackAndVersion(cluster.getClusterName(), "HDP", "2.2.0.0-995"));
+  }
+
+  /**
+   * At all times the cluster should have a cluster version whose state is {@link ClusterVersionState#CURRENT}
+   */
+  @Test
+  public void TestFindByClusterAndStateCurrent() {
+    createRecordsUntilStep(1);
+    Assert.assertNotNull(clusterVersionDAO.findByClusterAndStateCurrent(cluster.getClusterName()));
+
+    createRecordsUntilStep(2);
+    Assert.assertNotNull(clusterVersionDAO.findByClusterAndStateCurrent(cluster.getClusterName()));
+
+    createRecordsUntilStep(3);
+    Assert.assertNotNull(clusterVersionDAO.findByClusterAndStateCurrent(cluster.getClusterName()));
+
+    createRecordsUntilStep(4);
+    Assert.assertNotNull(clusterVersionDAO.findByClusterAndStateCurrent(cluster.getClusterName()));
+
+    createRecordsUntilStep(5);
+    Assert.assertNotNull(clusterVersionDAO.findByClusterAndStateCurrent(cluster.getClusterName()));
+
+    createRecordsUntilStep(6);
+    Assert.assertNotNull(clusterVersionDAO.findByClusterAndStateCurrent(cluster.getClusterName()));
+
+    createRecordsUntilStep(7);
+    Assert.assertNotNull(clusterVersionDAO.findByClusterAndStateCurrent(cluster.getClusterName()));
+  }
+
+  /**
+   * Test the state of certain cluster versions.
+   */
+  @Test
+  public void TestFindByClusterAndState() {
+    createRecordsUntilStep(1);
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.CURRENT).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.INSTALLED).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADING).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADE_FAILED).size());
+
+    createRecordsUntilStep(2);
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.CURRENT).size());
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.INSTALLED).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADING).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADE_FAILED).size());
+
+    createRecordsUntilStep(3);
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.CURRENT).size());
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.INSTALLED).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADING).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADE_FAILED).size());
+
+    createRecordsUntilStep(4);
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.CURRENT).size());
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.INSTALLED).size());
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADING).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADE_FAILED).size());
+
+    createRecordsUntilStep(5);
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.CURRENT).size());
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.INSTALLED).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADING).size());
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADE_FAILED).size());
+
+    createRecordsUntilStep(6);
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.CURRENT).size());
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.INSTALLED).size());
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADING).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADE_FAILED).size());
+
+    createRecordsUntilStep(7);
+    Assert.assertEquals(1, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.CURRENT).size());
+    Assert.assertEquals(2, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.INSTALLED).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADING).size());
+    Assert.assertEquals(0, clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), ClusterVersionState.UPGRADE_FAILED).size());
+  }
+
+  @After
+  public void after() {
+    injector.getInstance(PersistService.class).stop();
+    injector = null;
+  }
+}
\ No newline at end of file