diff --git a/pkl-core/src/main/java/org/pkl/core/packages/PackageResolvers.java b/pkl-core/src/main/java/org/pkl/core/packages/PackageResolvers.java index fbf3d085..797aa234 100644 --- a/pkl-core/src/main/java/org/pkl/core/packages/PackageResolvers.java +++ b/pkl-core/src/main/java/org/pkl/core/packages/PackageResolvers.java @@ -455,10 +455,9 @@ final class PackageResolvers { private byte[] downloadUriToPathAndComputeChecksum(URI downloadUri, Path path) throws IOException, SecurityManagerException { - Files.createDirectories(path.getParent()); var inputStream = openExternalUri(downloadUri); try (var digestInputStream = newDigestInputStream(inputStream)) { - Files.copy(digestInputStream, path); + Files.copy(digestInputStream, path, StandardCopyOption.REPLACE_EXISTING); return digestInputStream.getMessageDigest().digest(); } } @@ -472,7 +471,7 @@ final class PackageResolvers { } try (var in = inputStream) { Files.createDirectories(path.getParent()); - Files.copy(in, path); + Files.copy(in, path, StandardCopyOption.REPLACE_EXISTING); if (checksums != null) { var digestInputStream = (DigestInputStream) inputStream; var checksumBytes = digestInputStream.getMessageDigest().digest(); @@ -490,7 +489,10 @@ final class PackageResolvers { if (Files.exists(cachePath)) { return cachePath; } - var tmpPath = tmpDir.resolve(metadataRelativePath); + Files.createDirectories(tmpDir); + var tmpPath = + Files.createTempFile( + tmpDir, IoUtils.encodePath(packageUri.toString().replaceAll("/", "-")), ".json"); try { downloadMetadata(packageUri, requestUri, tmpPath, checksums); Files.createDirectories(cachePath.getParent()); @@ -539,7 +541,10 @@ final class PackageResolvers { if (Files.exists(cachePath)) { return cachePath; } - var tmpPath = tmpDir.resolve(relativePath); + Files.createDirectories(tmpDir); + var tmpPath = + Files.createTempFile( + tmpDir, IoUtils.encodePath(packageUri.toString().replaceAll("/", "-")), ".zip"); try { var checksumBytes = downloadUriToPathAndComputeChecksum(dependencyMetadata.getPackageZipUrl(), tmpPath); diff --git a/pkl-core/src/test/kotlin/org/pkl/core/packages/PackageResolversTest.kt b/pkl-core/src/test/kotlin/org/pkl/core/packages/PackageResolversTest.kt index f4aaa20c..38bc8446 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/packages/PackageResolversTest.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/packages/PackageResolversTest.kt @@ -22,10 +22,9 @@ import kotlin.io.path.exists import kotlin.io.path.readBytes import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatCode -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.* +import org.junit.jupiter.api.parallel.Execution +import org.junit.jupiter.api.parallel.ExecutionMode import org.pkl.commons.deleteRecursively import org.pkl.commons.readString import org.pkl.commons.test.FileTestUtils @@ -60,7 +59,9 @@ class PackageResolversTest { } } - @Test + // execute test 3 times to check concurrent writes + @RepeatedTest(3) + @Execution(ExecutionMode.CONCURRENT) fun `get module bytes`() { val expectedBirdModule = packageRoot.resolve("birds@0.5.0/package/Bird.pkl").readString(StandardCharsets.UTF_8)