void doPostGetHeadUpdateDeleteUndeleteTest(int contentSize, Account toPostAccount, Container toPostContainer,
      String serviceId, boolean isPrivate, String expectedAccountName, String expectedContainerName,
      boolean multipartPost) throws Exception {
    ByteBuffer content = ByteBuffer.wrap(TestUtils.getRandomBytes(contentSize));
    String contentType = "application/octet-stream";
    String ownerId = "postGetHeadDeleteOwnerID";
    String accountNameInPost = toPostAccount != null ? toPostAccount.getName() : null;
    String containerNameInPost = toPostContainer != null ? toPostContainer.getName() : null;
    HttpHeaders headers = new DefaultHttpHeaders();
    setAmbryHeadersForPut(headers, TTL_SECS, isPrivate, serviceId, contentType, ownerId, accountNameInPost,
        containerNameInPost);
    String blobId;
    byte[] usermetadata = null;
    if (multipartPost) {
      usermetadata = TestUtils.getRandomString(32).getBytes();
      blobId = multipartPostBlobAndVerify(headers, content, ByteBuffer.wrap(usermetadata));
    } else {
      headers.add(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + "key1", "value1");
      headers.add(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + "key2", "value2");
      if (toPostContainer != null && !toPostContainer.getUserMetadataKeysToNotPrefixInResponse().isEmpty()) {
        for (String key : toPostContainer.getUserMetadataKeysToNotPrefixInResponse()) {
          headers.add(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + key, "value");
        }
      }
      blobId = postBlobAndVerify(headers, content, contentSize);
    }
    headers.add(RestUtils.Headers.BLOB_SIZE, content.capacity());
    headers.add(RestUtils.Headers.LIFE_VERSION, "0");
    doVariousGetAndVerify(blobId, headers, isPrivate, content, contentSize, expectedAccountName, expectedContainerName,
        usermetadata, toPostContainer);
    updateBlobTtlAndVerify(blobId, headers, isPrivate, expectedAccountName, expectedContainerName, usermetadata,
        toPostContainer);
    deleteBlobAndVerify(blobId);

    // check GET, HEAD, TTL update and DELETE after delete.
    verifyOperationsAfterDelete(blobId, headers, isPrivate, expectedAccountName, expectedContainerName, content,
        usermetadata, false, toPostContainer);
    // Undelete it
    headers.add(RestUtils.Headers.LIFE_VERSION, "1");
    undeleteBlobAndVerify(blobId, headers, isPrivate, expectedAccountName, expectedContainerName, usermetadata,
        toPostContainer);
  }
Utility to test blob POST, GET, HEAD and DELETE operations for a specified size
@param contentSize the size of the blob to be tested
@param toPostAccount the {@link Account} to use in post headers. Can be {@code null} if only using service ID.
@param toPostContainer the {@link Container} to use in post headers. Can be {@code null} if only using service ID.
@param serviceId the serviceId to use for the POST
@param isPrivate the isPrivate flag to pass as part of the POST
@param expectedAccountName the expected account name in some response.
@param expectedContainerName the expected container name in some responses.
@param multipartPost {@code true} if multipart POST is desired, {@code false} otherwise.
@throws Exception
ambry-frontend/src/integration-test/java/com/github/ambry/frontend/FrontendIntegrationTestBase.java