|
10 | 10 | import java.nio.file.Files; |
11 | 11 | import java.nio.file.Path; |
12 | 12 | import java.nio.file.Paths; |
| 13 | +import java.nio.file.attribute.BasicFileAttributes; |
| 14 | +import java.nio.file.attribute.FileTime; |
| 15 | +import java.time.Instant; |
13 | 16 | import java.util.Collections; |
14 | 17 | import java.util.Map; |
15 | 18 | import org.junit.jupiter.api.Assertions; |
16 | 19 | import org.junit.jupiter.api.Test; |
17 | 20 | import org.junit.jupiter.api.condition.DisabledOnOs; |
18 | | -import org.junit.jupiter.api.condition.EnabledForJreRange; |
19 | | -import org.junit.jupiter.api.condition.JRE; |
20 | 21 | import org.junit.jupiter.api.condition.OS; |
21 | 22 |
|
22 | 23 | class ZipUtilsTest { |
@@ -105,10 +106,8 @@ public void testNewNonCompressedZip() throws Exception { |
105 | 106 | } |
106 | 107 | } |
107 | 108 |
|
108 | | - // on Java 11, passing an invalid value does not make the method fail |
109 | | - @EnabledForJreRange(min = JRE.JAVA_17) |
110 | 109 | @Test |
111 | | - public void tesIllegalEnv() { |
| 110 | + public void testIllegalEnv() { |
112 | 111 | assertThrows(IllegalArgumentException.class, () -> { |
113 | 112 | final Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir")); |
114 | 113 | final Path zipPath = Paths.get(tmpDir.toString(), "ziputilstest-" + System.currentTimeMillis() + ".jar"); |
@@ -176,8 +175,145 @@ public void testNewZipForNonExistentParentDir() throws Exception { |
176 | 175 | } |
177 | 176 | } |
178 | 177 |
|
| 178 | + @Test |
| 179 | + public void testCreateNewReproducibleZipFileSystem() throws Exception { |
| 180 | + final Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir")); |
| 181 | + final Path zipPath = Paths.get(tmpDir.toString(), "ziputilstest-" + System.currentTimeMillis() + ".jar"); |
| 182 | + final Instant referenceTimestamp = Instant.parse("2010-04-09T10:15:30.00Z"); |
| 183 | + |
| 184 | + try { |
| 185 | + try (final FileSystem fs = ZipUtils.createNewReproducibleZipFileSystem(zipPath, referenceTimestamp)) { |
| 186 | + final Path someFileInZip = fs.getPath("hello.txt"); |
| 187 | + Files.write(someFileInZip, "hello".getBytes(StandardCharsets.UTF_8)); |
| 188 | + } |
| 189 | + // now just verify that the content was actually written out |
| 190 | + try (final FileSystem fs = ZipUtils.newFileSystem(zipPath)) { |
| 191 | + assertFileExistsWithContent(fs.getPath("hello.txt"), "hello", referenceTimestamp); |
| 192 | + } |
| 193 | + } finally { |
| 194 | + Files.deleteIfExists(zipPath); |
| 195 | + } |
| 196 | + } |
| 197 | + |
| 198 | + @Test |
| 199 | + public void testCreateNewReproducibleZipFileSystemNullEntryTime() throws Exception { |
| 200 | + final Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir")); |
| 201 | + final Path zipPath = Paths.get(tmpDir.toString(), "ziputilstest-" + System.currentTimeMillis() + ".jar"); |
| 202 | + |
| 203 | + try { |
| 204 | + try (final FileSystem fs = ZipUtils.createNewReproducibleZipFileSystem(zipPath, null)) { |
| 205 | + final Path someFileInZip = fs.getPath("hello.txt"); |
| 206 | + Files.write(someFileInZip, "hello".getBytes(StandardCharsets.UTF_8)); |
| 207 | + } |
| 208 | + // now just verify that the content was actually written out |
| 209 | + try (final FileSystem fs = ZipUtils.newFileSystem(zipPath)) { |
| 210 | + assertFileExistsWithContent(fs.getPath("hello.txt"), "hello"); |
| 211 | + } |
| 212 | + } finally { |
| 213 | + Files.deleteIfExists(zipPath); |
| 214 | + } |
| 215 | + } |
| 216 | + |
| 217 | + @Test |
| 218 | + public void testCreateNewReproducibleZipFileSystemNonCompressedZip() throws Exception { |
| 219 | + final Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir")); |
| 220 | + final Path zipPath = Paths.get(tmpDir.toString(), "ziputilstest-" + System.currentTimeMillis() + ".jar"); |
| 221 | + final Instant referenceTimestamp = Instant.parse("2010-04-09T10:15:30.00Z"); |
| 222 | + try { |
| 223 | + try (final FileSystem fs = ZipUtils.createNewReproducibleZipFileSystem(zipPath, |
| 224 | + Map.of("compressionMethod", "STORED"), |
| 225 | + referenceTimestamp)) { |
| 226 | + final Path someFileInZip = fs.getPath("hello.txt"); |
| 227 | + Files.write(someFileInZip, "hello".getBytes(StandardCharsets.UTF_8)); |
| 228 | + } |
| 229 | + // now just verify that the content was actually written out |
| 230 | + try (final FileSystem fs = ZipUtils.newFileSystem(zipPath)) { |
| 231 | + Path helloFilePath = fs.getPath("hello.txt"); |
| 232 | + assertFileExistsWithContent(helloFilePath, "hello", referenceTimestamp); |
| 233 | + } |
| 234 | + |
| 235 | + } finally { |
| 236 | + Files.deleteIfExists(zipPath); |
| 237 | + } |
| 238 | + } |
| 239 | + |
| 240 | + @Test |
| 241 | + public void testCreateNewReproducibleZipFileSystemIllegalEnv() { |
| 242 | + assertThrows(IllegalArgumentException.class, () -> { |
| 243 | + final Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir")); |
| 244 | + final Path zipPath = Paths.get(tmpDir.toString(), "ziputilstest-" + System.currentTimeMillis() + ".jar"); |
| 245 | + final Instant referenceTimestamp = Instant.parse("2010-04-09T10:15:30.00Z"); |
| 246 | + try { |
| 247 | + try (final FileSystem fs = ZipUtils.createNewReproducibleZipFileSystem(zipPath, |
| 248 | + Map.of("compressionMethod", "DUMMY"), referenceTimestamp)) { |
| 249 | + final Path someFileInZip = fs.getPath("hello.txt"); |
| 250 | + Files.write(someFileInZip, "hello".getBytes(StandardCharsets.UTF_8)); |
| 251 | + } |
| 252 | + } finally { |
| 253 | + Files.deleteIfExists(zipPath); |
| 254 | + } |
| 255 | + }); |
| 256 | + } |
| 257 | + |
| 258 | + /** |
| 259 | + * Windows does not support question marks in file names |
| 260 | + */ |
| 261 | + @Test |
| 262 | + @DisabledOnOs(OS.WINDOWS) |
| 263 | + public void testCreateNewReproducibleZipFileSystemWithQuestionMark() throws Exception { |
| 264 | + final Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir")); |
| 265 | + final Path zipPath = Paths.get(tmpDir.toString(), "ziputils?test-" + System.currentTimeMillis() + ".jar"); |
| 266 | + final Instant referenceTimestamp = Instant.parse("2010-04-09T10:15:30.00Z"); |
| 267 | + try { |
| 268 | + try (final FileSystem fs = ZipUtils.createNewReproducibleZipFileSystem(zipPath, referenceTimestamp)) { |
| 269 | + final Path someFileInZip = fs.getPath("hello.txt"); |
| 270 | + Files.write(someFileInZip, "hello".getBytes(StandardCharsets.UTF_8)); |
| 271 | + } |
| 272 | + // now just verify that the content was actually written out |
| 273 | + try (final FileSystem fs = ZipUtils.newFileSystem(zipPath)) { |
| 274 | + assertFileExistsWithContent(fs.getPath("hello.txt"), "hello", referenceTimestamp); |
| 275 | + } |
| 276 | + } finally { |
| 277 | + Files.deleteIfExists(zipPath); |
| 278 | + } |
| 279 | + } |
| 280 | + |
| 281 | + @Test |
| 282 | + public void testCreateNewReproducibleZipFileSystemForNonExistentParentDir() throws Exception { |
| 283 | + final Path tmpDir = Files.createTempDirectory(null); |
| 284 | + final Path nonExistentLevel1Dir = tmpDir.resolve("non-existent-level1"); |
| 285 | + final Path nonExistentLevel2Dir = nonExistentLevel1Dir.resolve("non-existent-level2"); |
| 286 | + final Path zipPath = Paths.get(nonExistentLevel2Dir.toString(), "ziputilstest-nonexistentdirs.jar"); |
| 287 | + final Instant referenceTimestamp = Instant.parse("2010-04-09T10:15:30.00Z"); |
| 288 | + try { |
| 289 | + try (final FileSystem fs = ZipUtils.createNewReproducibleZipFileSystem(zipPath, referenceTimestamp)) { |
| 290 | + final Path someFileInZip = fs.getPath("hello.txt"); |
| 291 | + Files.write(someFileInZip, "hello".getBytes(StandardCharsets.UTF_8)); |
| 292 | + } |
| 293 | + // now just verify that the content was actually written out |
| 294 | + try (final FileSystem fs = ZipUtils.newFileSystem(zipPath)) { |
| 295 | + assertFileExistsWithContent(fs.getPath("hello.txt"), "hello", referenceTimestamp); |
| 296 | + } |
| 297 | + } finally { |
| 298 | + Files.deleteIfExists(zipPath); |
| 299 | + } |
| 300 | + } |
| 301 | + |
179 | 302 | private static void assertFileExistsWithContent(final Path path, final String content) throws IOException { |
| 303 | + assertFileExistsWithContent(path, content, null); |
| 304 | + } |
| 305 | + |
| 306 | + private static void assertFileExistsWithContent(final Path path, final String content, Instant referenceTimestamp) |
| 307 | + throws IOException { |
180 | 308 | final String readContent = Files.readString(path); |
| 309 | + BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class); |
| 310 | + |
181 | 311 | assertEquals(content, readContent, "Unexpected content in " + path); |
| 312 | + |
| 313 | + if (referenceTimestamp != null) { |
| 314 | + assertEquals(FileTime.from(referenceTimestamp), attr.lastAccessTime(), "Unexpected lastAccessTime in " + path); |
| 315 | + assertEquals(FileTime.from(referenceTimestamp), attr.lastModifiedTime(), "Unexpected lastModifiedTime in " + path); |
| 316 | + assertEquals(FileTime.from(referenceTimestamp), attr.creationTime(), "Unexpected creationTime in " + path); |
| 317 | + } |
182 | 318 | } |
183 | 319 | } |
0 commit comments