DatastoreDeadBlobFinder extends ComponentSupport implements DeadBlobFinder<Asset> { @Override public List<DeadBlobResult<Asset>> find(@NotNull final Repository repository, final boolean ignoreMissingBlobRefs) { checkNotNull(repository); List<DeadBlobResult<Asset>> deadBlobCandidates = identifySuspects(repository, ignoreMissingBlobRefs); return verifySuspects(deadBlobCandidates, repository); } @Inject  DatastoreDeadBlobFinder(final BlobStoreManager blobStoreManager); @Override List<DeadBlobResult<Asset>> find(@NotNull final Repository repository, final boolean ignoreMissingBlobRefs);  }
@Test public void noErrorsIfBlobExistsAndMatchesChecksum() { mockAssetBrowse(); commonBlobMock(); List<DeadBlobResult<Asset>> result = deadBlobFinder.find(repository); assertThat(result, hasSize(0)); }
@Test public void errorsIfBlobSha1DisagreesWithDb() { mockAssetBrowse(); mockAssetReload(); when(blob.getMetrics()).thenReturn(blobMetrics); when(blob.getInputStream()).thenReturn(blobStream); when(assetBlob.checksums()).thenReturn(Collections.singletonMap(HashAlgorithm.SHA1.toString(), "1235")); List<DeadBlobResult<Asset>> result = deadBlobFinder.find(repository); assertThat(result, hasSize(1)); assertThat(result.get(0).getAsset().path(), is("foo")); assertThat(result.get(0).getResultState(), is(SHA1_DISAGREEMENT)); }
@Test public void errorsIfBlobInputStreamIsNotAvailable() throws IOException { InputStream is = mock(InputStream.class); when(is.available()).thenReturn(0); mockAssetBrowse(); commonBlobMock(2, is); mockAssetReload(); List<DeadBlobResult<Asset>> result = deadBlobFinder.find(repository); assertThat(result, hasSize(1)); assertThat(result.get(0).getAsset().path(), is("foo")); assertThat(result.get(0).getResultState(), is(UNAVAILABLE_BLOB)); }
@Test public void doNotCheckAvailabilityOfInputStreamIfContentLengthIsZero() throws IOException { mockAssetBrowse(); InputStream stream = mock(InputStream.class); commonBlobMock(1, stream, new BlobMetrics(DateTime.now(), "1234", 0)); List<DeadBlobResult<Asset>> result = deadBlobFinder.find(repository); assertThat(result, empty()); verify(stream, never()).available(); }
@Test public void missingAssetBlobRefIsAnErrorIfNotIgnored() { when(asset.blob()).thenReturn(Optional.empty()); mockAssetBrowse(); mockAssetReload(); List<DeadBlobResult<Asset>> result = deadBlobFinder.find(repository, false); assertThat(result, hasSize(1)); assertThat(result.get(0).getAsset().path(), is("foo")); assertThat(result.get(0).getResultState(), is(MISSING_BLOB_REF)); assertThat(result.get(0).getErrorMessage(), is("Blob not found.")); }
@Test public void missingAssetBlobRefIsNotAnErrorIfIgnoredNugetCase() { when(asset.blob()).thenReturn(Optional.empty()); mockAssetBrowse(); List<DeadBlobResult<Asset>> result = deadBlobFinder.find(repository, true); assertThat(result, empty()); }
@Test public void passingInANullRepositoryResultsInAnError() { thrown.expect(NullPointerException.class); deadBlobFinder.find(null); verifyNoMoreInteractions(blobStoreManager); }
@Test public void anAssetCanBeDeletedWhileTheSystemIsInspected() throws IOException { InputStream is = mock(InputStream.class); when(is.available()).thenThrow(new IOException("cannot read inputstream")); mockAssetBrowse(); commonBlobMock(1, is); mockAssetReload(null); List<DeadBlobResult<Asset>> result = deadBlobFinder.find(repository, true); assertThat(result, hasSize(1)); assertNull(result.get(0).getAsset()); assertThat(result.get(0).getResultState(), is(ASSET_DELETED)); }
@Test public void anAssetBlobCanBeDeletedWhileTheSystemIsInspected() { AssetBlob missingAssetBlob = mockAssetBlob(mock(AssetBlob.class)); when(asset.blob()).thenReturn(Optional.of(missingAssetBlob)); FluentAsset reloadedAsset = createAsset(assetBlob); Blob reloadedBlob = mock(Blob.class); when(reloadedBlob.getMetrics()).thenReturn(blobMetrics); BlobId missingBlobId = reloadedAsset.blob().get().blobRef().getBlobId(); when(blobStore.get(missingBlobId)).thenReturn(reloadedBlob); mockAssetBrowse(); mockAssetReload(reloadedAsset); when(reloadedBlob.getMetrics()).thenReturn(blobMetrics); when(reloadedBlob.getInputStream()).thenThrow(new BlobStoreException("Blob has been deleted", new BlobId("foo"))); List<DeadBlobResult<Asset>> result = deadBlobFinder.find(repository, true); assertThat(result, hasSize(1)); assertThat(result.get(0).getResultState(), is(DELETED)); }