@Test
  public void testConcurrentUpdates() throws Exception {
    PartitionId partitionId = new MockPartitionId(testPartition, MockClusterMap.DEFAULT_PARTITION_CLASS);
    BlobId blobId = new BlobId(BLOB_ID_V6, BlobIdType.NATIVE, dataCenterId, accountId, containerId, partitionId, false,
        BlobDataType.DATACHUNK);
    InputStream inputStream = getBlobInputStream(blobSize);
    long now = System.currentTimeMillis();
    CloudBlobMetadata cloudBlobMetadata =
        new CloudBlobMetadata(blobId, now, now + 60000, blobSize, CloudBlobMetadata.EncryptionOrigin.NONE);
    uploadBlobWithRetry(blobId, blobSize, cloudBlobMetadata, inputStream, cloudRequestAgent, azureDest);
    // Different instance to simulate concurrent update in separate session.
    AzureCloudDestination concurrentUpdater = getAzureDestination(verifiableProperties);
    String fieldName = CloudBlobMetadata.FIELD_UPLOAD_TIME;
    long newUploadTime = now++;

    // Case 1: concurrent modification to blob metadata.
    azureDest.getAzureBlobDataAccessor()
        .setUpdateCallback(() -> concurrentUpdater.getAzureBlobDataAccessor()
            .updateBlobMetadataAsync(blobId, Collections.singletonMap(fieldName, newUploadTime), dummyCloudUpdateValidator)
            .join());
    try {
      azureDest.updateBlobExpiration(blobId, ++now, dummyCloudUpdateValidator);
      fail("Expected 412 error");
    } catch (CloudStorageException csex) {
      // TODO: check nested exception is BlobStorageException with status code 412
      assertEquals("Expected update conflict", 1, azureDest.getAzureMetrics().blobUpdateConflictCount.getCount());
    }
    // Case 2: concurrent modification to Cosmos record.
    azureDest.getCosmosDataAccessor()
        .setUpdateCallback(() -> concurrentUpdater.getCosmosDataAccessor()
            .updateMetadataAsync(blobId, Collections.singletonMap(fieldName, Long.toString(newUploadTime)))
            .join());
    try {
      azureDest.updateBlobExpiration(blobId, ++now, dummyCloudUpdateValidator);
      fail("Expected 412 error");
    } catch (CloudStorageException csex) {
      assertEquals("Expected update conflict", 2, azureDest.getAzureMetrics().blobUpdateConflictCount.getCount());
    }
    azureDest.getCosmosDataAccessor().setUpdateCallback(null);
    try {
      azureDest.updateBlobExpiration(blobId, ++now, dummyCloudUpdateValidator);
    } catch (Exception ex) {
      fail("Expected update to succeed.");
    }
    assertEquals("Expected no new update conflict", 2, azureDest.getAzureMetrics().blobUpdateConflictCount.getCount());
  }
Test that concurrent updates fail when the precondition does not match.
We don't test retries here since CloudBlobStoreTest covers that.
ambry-cloud/src/test/java/com/github/ambry/cloud/azure/AzureIntegrationTest.java