@Test
  public void testThreadLocalMetadataCache() throws CloudStorageException, StoreException {
    String data = "hello world!";
    HashMap<BlobId, CloudBlobMetadata> blobs = createBlob(data, 5);
    int iter = 1;
    for (BlobId blob : blobs.keySet()) {
      CloudBlobMetadata metadata = blobs.get(blob);
      short version = metadata.getLifeVersion();
      // put blob
      azureClient.uploadBlob(blob, data.length(), metadata,
          new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)));
      assertEquals(metadata, getBlobMetadata(blob)); // same content; md-cache miss
      assertFalse(getBlobMetadata(blob).isTtlUpdated());
      assertFalse(getBlobMetadata(blob).isDeleted());
      assertFalse(getBlobMetadata(blob).isUndeleted());

      // remove TTL
      azureClient.updateBlobExpiration(blob, Utils.Infinite_Time, null); // md-cache hit
      verifyConstantMetadataFields(metadata, getBlobMetadata(blob)); // md-cache miss
      assertTrue(getBlobMetadata(blob).isTtlUpdated());
      assertFalse(getBlobMetadata(blob).isDeleted());
      assertFalse(getBlobMetadata(blob).isUndeleted());

      // delete blob
      long now = System.currentTimeMillis();
      azureClient.deleteBlob(blob, now, (short) (version + 1), null); // md-cache hit
      verifyConstantMetadataFields(metadata, getBlobMetadata(blob)); // md-cache miss
      assertTrue(getBlobMetadata(blob).isTtlUpdated());
      assertTrue(getBlobMetadata(blob).isDeleted());
      assertFalse(getBlobMetadata(blob).isUndeleted());
      assertEquals(now, getBlobMetadata(blob).getDeletionTime());

      // undelete blob
      azureClient.undeleteBlob(blob, (short) (version + 2), null); // md-cache hit
      verifyConstantMetadataFields(metadata, getBlobMetadata(blob)); // md-cache miss
      assertTrue(getBlobMetadata(blob).isTtlUpdated());
      assertFalse(getBlobMetadata(blob).isDeleted());
      assertTrue(getBlobMetadata(blob).isUndeleted());

      assertEquals(4*iter, azureMetrics.blobGetPropertiesSuccessRate.getCount()); // num cache_misses
      iter += 1;
    }
  }
Tests thread-local metadata cache by fetching blob metadata from azure
@throws CloudStorageException
ambry-cloud/src/test/java/com/github/ambry/cloud/VcrReplicaThreadTest.java