diff --git a/plugins/maven-dependency-resolver/build.gradle b/plugins/maven-dependency-resolver/build.gradle index 8896b652b73..9096b75c83e 100644 --- a/plugins/maven-dependency-resolver/build.gradle +++ b/plugins/maven-dependency-resolver/build.gradle @@ -49,8 +49,11 @@ afterEvaluate { dependencies { api project(":pluginapi") api project(":utils") + api "com.google.auto.value:auto-value-annotations:1.10.1" api "com.google.guava:guava:$guavaJREVersion" + annotationProcessor "com.google.auto.value:auto-value:1.10.1" + testImplementation "junit:junit:$junitVersion" testImplementation "org.mockito:mockito-core:$mockitoVersion" testImplementation "com.google.truth:truth:$truthVersion" diff --git a/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java b/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java index 60f852dbcc9..adeda9e78fb 100644 --- a/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java +++ b/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java @@ -2,6 +2,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; +import com.google.auto.value.AutoValue; import com.google.common.base.Strings; import com.google.common.hash.HashCode; import com.google.common.hash.Hashing; @@ -24,6 +25,7 @@ import java.util.Base64; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; +import javax.annotation.Nonnull; import org.robolectric.util.Logger; /** @@ -82,15 +84,27 @@ public void fetchArtifact(MavenJarArtifact artifact) { return Futures.immediateFuture(null); } createArtifactSubdirectory(artifact, localRepositoryDir); - boolean pomValid = + ValidationResult pomResult = validateStagedFiles(artifact.pomPath(), artifact.pomSha512Path()); - if (!pomValid) { - throw new AssertionError("SHA512 mismatch for POM file fetched in " + artifact); + if (!pomResult.isSuccess()) { + throw new AssertionError( + "SHA-512 mismatch for POM file for " + + artifact + + ", expected SHA-512=" + + pomResult.expectedHashCode() + + ", actual SHA-512=" + + pomResult.calculatedHashCode()); } - boolean jarValid = + ValidationResult jarResult = validateStagedFiles(artifact.jarPath(), artifact.jarSha512Path()); - if (!jarValid) { - throw new AssertionError("SHA512 mismatch for JAR file fetched in " + artifact); + if (!jarResult.isSuccess()) { + throw new AssertionError( + "SHA-512 mismatch for POM file for " + + artifact + + ", expected SHA-512=" + + jarResult.expectedHashCode() + + ", actual SHA-512=" + + jarResult.calculatedHashCode()); } Logger.info( String.format( @@ -123,7 +137,8 @@ private void removeArtifactFiles(File repositoryDir, MavenJarArtifact artifact) new File(repositoryDir, artifact.pomSha512Path()).delete(); } - private boolean validateStagedFiles(String filePath, String sha512Path) throws IOException { + private ValidationResult validateStagedFiles(String filePath, String sha512Path) + throws IOException { File tempFile = new File(this.stagingRepositoryDir, filePath); File sha512File = new File(this.stagingRepositoryDir, sha512Path); @@ -131,7 +146,24 @@ private boolean validateStagedFiles(String filePath, String sha512Path) throws I HashCode.fromString(new String(Files.asByteSource(sha512File).read(), UTF_8)); HashCode actual = Files.asByteSource(tempFile).hash(Hashing.sha512()); - return expected.equals(actual); + return ValidationResult.create(expected.equals(actual), expected.toString(), actual.toString()); + } + + @AutoValue + abstract static class ValidationResult { + abstract boolean isSuccess(); + + @Nonnull + abstract String expectedHashCode(); + + @Nonnull + abstract String calculatedHashCode(); + + static ValidationResult create( + boolean isSuccess, String expectedHashCode, String calculatedHashCode) { + return new AutoValue_MavenArtifactFetcher_ValidationResult( + isSuccess, expectedHashCode, calculatedHashCode); + } } private void createArtifactSubdirectory(MavenJarArtifact artifact, File repositoryDir) @@ -218,6 +250,9 @@ public ListenableFuture call() throws Exception { try (InputStream inputStream = connection.getInputStream(); FileOutputStream outputStream = new FileOutputStream(localFile)) { ByteStreams.copy(inputStream, outputStream); + // Ensure all contents are written to disk. + outputStream.flush(); + outputStream.getFD().sync(); } return Futures.immediateFuture(null); }