2121import java .io .FileWriter ;
2222import java .io .IOException ;
2323import java .io .InputStreamReader ;
24+ import java .lang .Runtime .Version ;
2425import java .nio .file .Files ;
2526import java .nio .file .LinkOption ;
2627import java .nio .file .attribute .BasicFileAttributeView ;
3031import java .time .temporal .ChronoUnit ;
3132import java .util .Arrays ;
3233import java .util .Collections ;
34+ import java .util .EnumSet ;
3335import java .util .Iterator ;
3436import java .util .concurrent .TimeUnit ;
3537import java .util .function .Consumer ;
3840
3941import org .junit .jupiter .api .BeforeEach ;
4042import org .junit .jupiter .api .Test ;
43+ import org .junit .jupiter .api .condition .JRE ;
44+ import org .junit .jupiter .api .condition .OS ;
4145import org .junit .jupiter .api .extension .ExtendWith ;
4246import org .junit .jupiter .api .io .TempDir ;
4347import org .mockito .Mock ;
5963@ ExtendWith (MockitoExtension .class )
6064class ExtractCommandTests {
6165
62- private static final FileTime CREATION_TIME = FileTime . from ( Instant .now (). minus ( 3 , ChronoUnit . DAYS ) );
66+ private static final Instant NOW = Instant .now ();
6367
64- private static final FileTime LAST_MODIFIED_TIME = FileTime .from (Instant . now (). minus (2 , ChronoUnit .DAYS ));
68+ private static final FileTime CREATION_TIME = FileTime .from (NOW . minus (3 , ChronoUnit .DAYS ));
6569
66- private static final FileTime LAST_ACCESS_TIME = FileTime .from (Instant .now ().minus (1 , ChronoUnit .DAYS ));
70+ private static final FileTime LAST_MODIFIED_TIME = FileTime .from (NOW .minus (2 , ChronoUnit .DAYS ));
71+
72+ private static final FileTime LAST_ACCESS_TIME = FileTime .from (NOW .minus (1 , ChronoUnit .DAYS ));
6773
6874 @ TempDir
6975 File temp ;
@@ -107,10 +113,11 @@ private void timeAttributes(File file) {
107113 .readAttributes ();
108114 assertThat (basicAttributes .lastModifiedTime ().to (TimeUnit .SECONDS ))
109115 .isEqualTo (LAST_MODIFIED_TIME .to (TimeUnit .SECONDS ));
110- assertThat (basicAttributes .creationTime ().to (TimeUnit .SECONDS )).satisfiesAnyOf (
111- (creationTime ) -> assertThat (creationTime ).isEqualTo (CREATION_TIME .to (TimeUnit .SECONDS )),
112- // On macOS (at least) the creation time is the last modified time
113- (creationTime ) -> assertThat (creationTime ).isEqualTo (LAST_MODIFIED_TIME .to (TimeUnit .SECONDS )));
116+ FileTime expectedCreationTime = expectedCreationTime ();
117+ if (expectedCreationTime != null ) {
118+ assertThat (basicAttributes .creationTime ().to (TimeUnit .SECONDS ))
119+ .isEqualTo (expectedCreationTime .to (TimeUnit .SECONDS ));
120+ }
114121 assertThat (basicAttributes .lastAccessTime ().to (TimeUnit .SECONDS ))
115122 .isEqualTo (LAST_ACCESS_TIME .to (TimeUnit .SECONDS ));
116123 }
@@ -119,6 +126,22 @@ private void timeAttributes(File file) {
119126 }
120127 }
121128
129+ private FileTime expectedCreationTime () {
130+ // macOS uses last modified time until Java 20 where it uses creation time.
131+ // https://github.com/openjdk/jdk21u-dev/commit/6397d564a5dab07f81bf4c69b116ebfabb2446ba
132+ if (OS .MAC .isCurrentOs ()) {
133+ return (EnumSet .range (JRE .JAVA_17 , JRE .JAVA_19 ).contains (JRE .currentVersion ())) ? LAST_MODIFIED_TIME
134+ : CREATION_TIME ;
135+ }
136+ if (OS .LINUX .isCurrentOs ()) {
137+ // Linux uses the modified time until Java 21.0.2 where a bug means that it
138+ // uses the birth time which it has not set, preventing us from verifying it.
139+ // https://github.com/openjdk/jdk21u-dev/commit/4cf572e3b99b675418e456e7815fb6fd79245e30
140+ return (Runtime .version ().compareTo (Version .parse ("21.0.2" )) >= 0 ) ? null : LAST_MODIFIED_TIME ;
141+ }
142+ return CREATION_TIME ;
143+ }
144+
122145 @ Test
123146 void runWhenHasDestinationOptionExtractsLayers () {
124147 given (this .context .getArchiveFile ()).willReturn (this .jarFile );
0 commit comments