1
1
/*
2
- * Copyright (c) 2019, 2020 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2019, 2024 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
22
22
*/
23
23
24
24
/* @test
25
- * @bug 8181493 8231174
25
+ * @bug 8181493 8231174 8343417
26
26
* @summary Verify that nanosecond precision is maintained for file timestamps
27
27
* @requires (os.family == "linux") | (os.family == "mac") | (os.family == "windows")
28
+ * @library ../.. /test/lib
29
+ * @build jdk.test.lib.Platform
28
30
* @modules java.base/sun.nio.fs:+open
31
+ * @run main SetTimesNanos
29
32
*/
30
33
31
34
import java .io .IOException ;
36
39
import java .nio .file .attribute .BasicFileAttributes ;
37
40
import java .nio .file .attribute .BasicFileAttributeView ;
38
41
import java .nio .file .attribute .FileTime ;
42
+ import java .util .List ;
39
43
import java .util .Set ;
40
- import java .util .concurrent .TimeUnit ;
44
+
45
+ import static java .nio .file .LinkOption .*;
46
+ import static java .util .concurrent .TimeUnit .*;
47
+
48
+ import jdk .test .lib .Platform ;
49
+ import jtreg .SkippedException ;
41
50
42
51
public class SetTimesNanos {
43
- private static final boolean IS_WINDOWS =
44
- System .getProperty ("os.name" ).startsWith ("Windows" );
45
52
46
53
public static void main (String [] args ) throws Exception {
47
- if (!IS_WINDOWS ) {
54
+ if (!Platform . isWindows () ) {
48
55
// Check whether futimens() system call is supported
49
56
Class unixNativeDispatcherClass =
50
57
Class .forName ("sun.nio.fs.UnixNativeDispatcher" );
51
58
Method futimensSupported =
52
59
unixNativeDispatcherClass .getDeclaredMethod ("futimensSupported" );
53
60
futimensSupported .setAccessible (true );
54
61
if (!(boolean )futimensSupported .invoke (null )) {
55
- System .err .println ("futimens() not supported; skipping test" );
56
- return ;
62
+ throw new SkippedException ("futimens() not supported" );
57
63
}
58
64
}
59
65
@@ -63,30 +69,34 @@ public static void main(String[] args) throws Exception {
63
69
System .out .format ("FileStore: \" %s\" on %s (%s)%n" ,
64
70
dir , store .name (), store .type ());
65
71
66
- Set <String > testedTypes = IS_WINDOWS ?
72
+ Set <String > testedTypes = Platform . isWindows () ?
67
73
Set .of ("NTFS" ) : Set .of ("apfs" , "ext4" , "xfs" , "zfs" );
68
74
if (!testedTypes .contains (store .type ())) {
69
- System .err .format ("%s not in %s; skipping test" , store .type (), testedTypes );
70
- return ;
75
+ throw new SkippedException (store .type () + " not in " + testedTypes );
71
76
}
72
77
73
78
testNanos (dir );
74
79
75
80
Path file = Files .createFile (dir .resolve ("test.dat" ));
76
81
testNanos (file );
82
+
83
+ if (Platform .isLinux ()) {
84
+ testNanosLink (false );
85
+ testNanosLink (true );
86
+ }
77
87
}
78
88
79
89
private static void testNanos (Path path ) throws IOException {
80
90
// Set modification and access times
81
91
// Time stamp = "2017-01-01 01:01:01.123456789";
82
92
long timeNanos = 1_483_261_261L *1_000_000_000L + 123_456_789L ;
83
- FileTime pathTime = FileTime .from (timeNanos , TimeUnit . NANOSECONDS );
93
+ FileTime pathTime = FileTime .from (timeNanos , NANOSECONDS );
84
94
BasicFileAttributeView view =
85
95
Files .getFileAttributeView (path , BasicFileAttributeView .class );
86
96
view .setTimes (pathTime , pathTime , null );
87
97
88
98
// Windows file time resolution is 100ns so truncate
89
- if (IS_WINDOWS ) {
99
+ if (Platform . isWindows () ) {
90
100
timeNanos = 100L *(timeNanos /100L );
91
101
}
92
102
@@ -99,12 +109,50 @@ private static void testNanos(Path path) throws IOException {
99
109
FileTime [] times = new FileTime [] {attrs .lastModifiedTime (),
100
110
attrs .lastAccessTime ()};
101
111
for (int i = 0 ; i < timeNames .length ; i ++) {
102
- long nanos = times [i ].to (TimeUnit . NANOSECONDS );
112
+ long nanos = times [i ].to (NANOSECONDS );
103
113
if (nanos != timeNanos ) {
104
114
throw new RuntimeException ("Expected " + timeNames [i ] +
105
115
" timestamp to be '" + timeNanos + "', but was '" +
106
116
nanos + "'" );
107
117
}
108
118
}
109
119
}
120
+
121
+ private static void testNanosLink (boolean absolute ) throws IOException {
122
+ System .out .println ("absolute: " + absolute );
123
+
124
+ var target = Path .of ("target" );
125
+ var symlink = Path .of ("symlink" );
126
+ if (absolute )
127
+ symlink = symlink .toAbsolutePath ();
128
+
129
+ try {
130
+ Files .createFile (target );
131
+ Files .createSymbolicLink (symlink , target );
132
+
133
+ var newTime = FileTime .from (1730417633157646106L , NANOSECONDS );
134
+ System .out .println ("newTime: " + newTime .to (NANOSECONDS ));
135
+
136
+ for (Path p : List .of (target , symlink )) {
137
+ System .out .println ("p: " + p );
138
+
139
+ var view = Files .getFileAttributeView (p ,
140
+ BasicFileAttributeView .class , NOFOLLOW_LINKS );
141
+ view .setTimes (newTime , newTime , null );
142
+ var attrs = view .readAttributes ();
143
+
144
+ if (!attrs .lastAccessTime ().equals (newTime ))
145
+ throw new RuntimeException ("Last access time "
146
+ + attrs .lastAccessTime ()
147
+ + " != " + newTime );
148
+ if (!attrs .lastAccessTime ().equals (newTime ))
149
+ throw new RuntimeException ("Last modified time "
150
+ + attrs .lastModifiedTime ()
151
+ + " != " + newTime );
152
+ }
153
+ } finally {
154
+ Files .deleteIfExists (target );
155
+ Files .deleteIfExists (symlink );
156
+ }
157
+ }
110
158
}
0 commit comments