### Question:
BlobPuller implements RegistryEndpointProvider<Void> { @Override public Void handleResponse(Response response) throws IOException, UnexpectedBlobDigestException { blobSizeListener.accept(response.getContentLength()); try (OutputStream outputStream = new NotifyingOutputStream(destinationOutputStream, writtenByteCountListener)) { BlobDescriptor receivedBlobDescriptor = Digests.computeDigest(response.getBody(), outputStream); if (!blobDigest.equals(receivedBlobDescriptor.getDigest())) { throw new UnexpectedBlobDigestException( "The pulled BLOB has digest '" + receivedBlobDescriptor.getDigest() + "', but the request digest was '" + blobDigest + "'"); } } return null; } BlobPuller(
      RegistryEndpointRequestProperties registryEndpointRequestProperties,
      DescriptorDigest blobDigest,
      OutputStream destinationOutputStream,
      Consumer<Long> blobSizeListener,
      Consumer<Long> writtenByteCountListener); @Override Void handleResponse(Response response); @Override @Nullable BlobHttpContent getContent(); @Override List<String> getAccept(); @Override URL getApiRoute(String apiRouteBase); @Override String getHttpMethod(); @Override String getActionDescription(); @Override Void handleHttpResponseException(ResponseException responseException);  }### Answer:
@Test public void testHandleResponse() throws IOException, UnexpectedBlobDigestException { InputStream blobContent = new ByteArrayInputStream("some BLOB content".getBytes(StandardCharsets.UTF_8)); DescriptorDigest testBlobDigest = Digests.computeDigest(blobContent).getDigest(); blobContent.reset(); Response mockResponse = Mockito.mock(Response.class); Mockito.when(mockResponse.getContentLength()).thenReturn((long) "some BLOB content".length()); Mockito.when(mockResponse.getBody()).thenReturn(blobContent); LongAdder byteCount = new LongAdder(); BlobPuller blobPuller = new BlobPuller( fakeRegistryEndpointRequestProperties, testBlobDigest, layerOutputStream, size -> Assert.assertEquals("some BLOB content".length(), size.longValue()), byteCount::add); blobPuller.handleResponse(mockResponse); Assert.assertEquals( "some BLOB content", new String(layerContentOutputStream.toByteArray(), StandardCharsets.UTF_8)); Assert.assertEquals(testBlobDigest, layerOutputStream.computeDigest().getDigest()); Assert.assertEquals("some BLOB content".length(), byteCount.sum()); }
@Test public void testHandleResponse_unexpectedDigest() throws IOException { InputStream blobContent = new ByteArrayInputStream("some BLOB content".getBytes(StandardCharsets.UTF_8)); DescriptorDigest testBlobDigest = Digests.computeDigest(blobContent).getDigest(); blobContent.reset(); Response mockResponse = Mockito.mock(Response.class); Mockito.when(mockResponse.getBody()).thenReturn(blobContent); try { testBlobPuller.handleResponse(mockResponse); Assert.fail("Receiving an unexpected digest should fail"); } catch (UnexpectedBlobDigestException ex) { Assert.assertEquals( "The pulled BLOB has digest '" + testBlobDigest + "', but the request digest was '" + fakeDigest + "'", ex.getMessage()); } }