@Test
  public void testAddContainer() throws Exception {
    assumeTrue(!useNewZNodePath);
    accountService = mockHelixAccountServiceFactory.getAccountService();
    assertEquals("The number of account in HelixAccountService is incorrect", 0,
        accountService.getAllAccounts().size());
    // create three containers for testing
    Container activeContainer =
        new ContainerBuilder((short) (refContainer.getId() + 1), "active", Container.ContainerStatus.ACTIVE, "",
            refAccount.getId()).build();
    Container inactiveContainer =
        new ContainerBuilder((short) (refContainer.getId() + 2), "inactive", Container.ContainerStatus.INACTIVE, "",
            refAccount.getId()).build();
    Container deleteInProgressContainer1 =
        new ContainerBuilder((short) (refContainer.getId() + 3), "within-retention-period",
            ContainerStatus.DELETE_IN_PROGRESS, "", refAccount.getId()).setDeleteTriggerTime(System.currentTimeMillis())
            .build();
    Container deleteInProgressContainer2 =
        new ContainerBuilder((short) (refContainer.getId() + 4), "past-retention-period",
            ContainerStatus.DELETE_IN_PROGRESS, "", refAccount.getId()).setDeleteTriggerTime(
            System.currentTimeMillis() - TimeUnit.DAYS.toMillis(15)).build();
    refAccount.updateContainerMap(
        Arrays.asList(activeContainer, inactiveContainer, deleteInProgressContainer1, deleteInProgressContainer2));
    // add an account with single container
    accountService.updateAccounts(Collections.singletonList(refAccount));

    Container brandNewContainer = new ContainerBuilder(activeContainer).setId(UNKNOWN_CONTAINER_ID).build();

    // 1. test invalid input
    try {
      accountService.updateContainers("", null);
      fail("should fail because input is invalid");
    } catch (AccountServiceException e) {
      assertEquals("Mismatch in error code", AccountServiceErrorCode.BadRequest, e.getErrorCode());
    }

    // 2. test account is not found
    String fakeAccountName = refAccountName + "fake";
    Container containerToAdd1 =
        new ContainerBuilder(UNKNOWN_CONTAINER_ID, "newContainer", ContainerStatus.ACTIVE, "description",
            refParentAccountId).build();
    try {
      accountService.updateContainers(fakeAccountName, Collections.singleton(containerToAdd1));
      fail("should fail because account is not found");
    } catch (AccountServiceException e) {
      assertEquals("Mismatch in error code", AccountServiceErrorCode.NotFound, e.getErrorCode());
    }

    // 3. test containers already exist with INACTIVE and DELETE_IN_PROGRESS state
    Container duplicateInactiveContainer = new ContainerBuilder(inactiveContainer).setId(UNKNOWN_CONTAINER_ID).build();
    Container duplicateDeleteInProgressContainer1 =
        new ContainerBuilder(deleteInProgressContainer1).setId(UNKNOWN_CONTAINER_ID).build();
    Container duplicateDeleteInProgressContainer2 =
        new ContainerBuilder(deleteInProgressContainer2).setId(UNKNOWN_CONTAINER_ID).build();
    try {
      accountService.updateContainers(refAccountName, Collections.singleton(duplicateInactiveContainer));
      fail("Should fail because the existing container has been marked INACTIVE.");
    } catch (AccountServiceException ase) {
      assertEquals("Mismatch in error code", AccountServiceErrorCode.ResourceHasGone, ase.getErrorCode());
    }
    try {
      accountService.updateContainers(refAccountName, Collections.singleton(duplicateDeleteInProgressContainer1));
      fail("Should fail because the existing container has been marked DELETE_IN_PROGRESS.");
    } catch (AccountServiceException ase) {
      assertEquals("Mismatch in error code", AccountServiceErrorCode.MethodNotAllowed, ase.getErrorCode());
    }
    try {
      accountService.updateContainers(refAccountName, Collections.singleton(duplicateDeleteInProgressContainer2));
      fail("Should fail because the existing container has been marked DELETE_IN_PROGRESS and past retention time");
    } catch (AccountServiceException ase) {
      assertEquals("Mismatch in error code", AccountServiceErrorCode.ResourceHasGone, ase.getErrorCode());
    }
    // 4. test conflict container (new container with existing name but different attributes)
    Container conflictContainer = new ContainerBuilder(brandNewContainer).setBackupEnabled(true).build();
    try {
      accountService.updateContainers(refAccountName, Collections.singleton(conflictContainer));
      fail("should fail because there is a conflicting container");
    } catch (AccountServiceException e) {
      assertEquals("Mismatch in error code", AccountServiceErrorCode.ResourceConflict, e.getErrorCode());
    }

    // 5. test adding same container twice, should be no-op and return result should include container with id
    Collection<Container> addedContainers =
        accountService.updateContainers(refAccountName, Collections.singleton(brandNewContainer));
    assertEquals("Mismatch in return count", 1, addedContainers.size());
    for (Container container : addedContainers) {
      assertEquals("Mismatch in account id", refAccountId, container.getParentAccountId());
      assertEquals("Mismatch in container id", activeContainer.getId(), container.getId());
      assertEquals("Mismatch in container name", activeContainer.getName(), container.getName());
    }

    // 6. test adding a different container (failure case due to ZK update failure)
    MockHelixPropertyStore<ZNRecord> mockHelixStore =
        mockHelixAccountServiceFactory.getHelixStore(ZK_CONNECT_STRING, storeConfig);
    mockHelixStore.setExceptionDuringUpdater(true);
    try {
      accountService.updateContainers(refAccountName, Collections.singleton(containerToAdd1));
      fail("should fail because exception occurs when updating ZK");
    } catch (AccountServiceException e) {
      assertEquals("Mismatch in error code", AccountServiceErrorCode.InternalError, e.getErrorCode());
    }
    mockHelixStore.setExceptionDuringUpdater(false);

    // 7. test adding 2 different containers (success case)
    Container containerToAdd2 =
        new ContainerBuilder(UNKNOWN_CONTAINER_ID, "newContainer2", ContainerStatus.ACTIVE, "description",
            refParentAccountId).build();
    addedContainers = accountService.updateContainers(refAccountName, Arrays.asList(containerToAdd1, containerToAdd2));
    for (Container container : addedContainers) {
      assertEquals("Mismatch in account id", refAccountId, container.getParentAccountId());
    }
  }
Test adding container to an existing account.
ambry-account/src/test/java/com/github/ambry/account/HelixAccountServiceTest.java