blob: 3f965b3cce5dcda1fdcd4789ead7d462b6efd2ec [file] [log] [blame]
sherman21984b02013-05-29 19:50:47 -07001/*
sherman19560202015-03-18 09:46:09 -07002 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
sherman21984b02013-05-29 19:50:47 -07003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * @test
shermand940d0f2015-04-07 08:52:44 -070026 * @bug 4759491 6303183 7012868 8015666 8023713 8068790 8074694 8076641
sherman21984b02013-05-29 19:50:47 -070027 * @summary Test ZOS and ZIS timestamp in extra field correctly
28 */
29
30import java.io.*;
sherman57eb3812013-08-08 12:03:04 -070031import java.nio.file.Files;
32import java.nio.file.Path;
33import java.nio.file.Paths;
34import java.nio.file.attribute.FileTime;
sherman45e33882013-08-28 09:46:55 -070035import java.util.Arrays;
sherman21984b02013-05-29 19:50:47 -070036import java.util.TimeZone;
37import java.util.concurrent.TimeUnit;
38import java.util.zip.ZipEntry;
sherman57eb3812013-08-08 12:03:04 -070039import java.util.zip.ZipFile;
sherman21984b02013-05-29 19:50:47 -070040import java.util.zip.ZipInputStream;
41import java.util.zip.ZipOutputStream;
42
sherman21984b02013-05-29 19:50:47 -070043public class TestExtraTime {
44
45 public static void main(String[] args) throws Throwable{
46
47 File src = new File(System.getProperty("test.src", "."), "TestExtraTime.java");
48 if (src.exists()) {
sherman57eb3812013-08-08 12:03:04 -070049 long time = src.lastModified();
50 FileTime mtime = FileTime.from(time, TimeUnit.MILLISECONDS);
51 FileTime atime = FileTime.from(time + 300000, TimeUnit.MILLISECONDS);
52 FileTime ctime = FileTime.from(time - 300000, TimeUnit.MILLISECONDS);
53 TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
54
sherman45e33882013-08-28 09:46:55 -070055 for (byte[] extra : new byte[][] { null, new byte[] {1, 2, 3}}) {
56 test(mtime, null, null, null, extra);
57 // ms-dos 1980 epoch problem
58 test(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null, extra);
59 // non-default tz
60 test(mtime, null, null, tz, extra);
sherman57eb3812013-08-08 12:03:04 -070061
sherman45e33882013-08-28 09:46:55 -070062 test(mtime, atime, null, null, extra);
63 test(mtime, null, ctime, null, extra);
64 test(mtime, atime, ctime, null, extra);
sherman57eb3812013-08-08 12:03:04 -070065
sherman45e33882013-08-28 09:46:55 -070066 test(mtime, atime, null, tz, extra);
67 test(mtime, null, ctime, tz, extra);
68 test(mtime, atime, ctime, tz, extra);
69 }
sherman21984b02013-05-29 19:50:47 -070070 }
redestadb3be0a22015-02-21 13:46:24 +010071
72 testNullHandling();
shermand940d0f2015-04-07 08:52:44 -070073 testTagOnlyHandling();
sherman19560202015-03-18 09:46:09 -070074 testTimeConversions();
sherman21984b02013-05-29 19:50:47 -070075 }
76
sherman57eb3812013-08-08 12:03:04 -070077 static void test(FileTime mtime, FileTime atime, FileTime ctime,
sherman45e33882013-08-28 09:46:55 -070078 TimeZone tz, byte[] extra) throws Throwable {
sherman57eb3812013-08-08 12:03:04 -070079 System.out.printf("--------------------%nTesting: [%s]/[%s]/[%s]%n",
80 mtime, atime, ctime);
sherman21984b02013-05-29 19:50:47 -070081 TimeZone tz0 = TimeZone.getDefault();
82 if (tz != null) {
83 TimeZone.setDefault(tz);
84 }
85 ByteArrayOutputStream baos = new ByteArrayOutputStream();
86 ZipOutputStream zos = new ZipOutputStream(baos);
sherman45e33882013-08-28 09:46:55 -070087 ZipEntry ze = new ZipEntry("TestExtraTime.java");
88 ze.setExtra(extra);
sherman57eb3812013-08-08 12:03:04 -070089 ze.setLastModifiedTime(mtime);
90 if (atime != null)
91 ze.setLastAccessTime(atime);
92 if (ctime != null)
93 ze.setCreationTime(ctime);
sherman21984b02013-05-29 19:50:47 -070094 zos.putNextEntry(ze);
95 zos.write(new byte[] { 1,2 ,3, 4});
sherman45e33882013-08-28 09:46:55 -070096
97 // append an extra entry to help check if the length and data
98 // of the extra field are being correctly written (in previous
99 // entry).
100 if (extra != null) {
101 ze = new ZipEntry("TestExtraEntry");
102 zos.putNextEntry(ze);
103 }
sherman21984b02013-05-29 19:50:47 -0700104 zos.close();
105 if (tz != null) {
106 TimeZone.setDefault(tz0);
107 }
sherman57eb3812013-08-08 12:03:04 -0700108 // ZipInputStream
sherman21984b02013-05-29 19:50:47 -0700109 ZipInputStream zis = new ZipInputStream(
110 new ByteArrayInputStream(baos.toByteArray()));
111 ze = zis.getNextEntry();
112 zis.close();
sherman45e33882013-08-28 09:46:55 -0700113 check(mtime, atime, ctime, ze, extra);
sherman21984b02013-05-29 19:50:47 -0700114
sherman57eb3812013-08-08 12:03:04 -0700115 // ZipFile
116 Path zpath = Paths.get(System.getProperty("test.dir", "."),
sherman45e33882013-08-28 09:46:55 -0700117 "TestExtraTime.zip");
sherman57eb3812013-08-08 12:03:04 -0700118 Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
119 ZipFile zf = new ZipFile(zpath.toFile());
sherman45e33882013-08-28 09:46:55 -0700120 ze = zf.getEntry("TestExtraTime.java");
sherman57eb3812013-08-08 12:03:04 -0700121 // ZipFile read entry from cen, which does not have a/ctime,
122 // for now.
sherman45e33882013-08-28 09:46:55 -0700123 check(mtime, null, null, ze, extra);
sherman57eb3812013-08-08 12:03:04 -0700124 zf.close();
125 Files.delete(zpath);
126 }
sherman21984b02013-05-29 19:50:47 -0700127
sherman57eb3812013-08-08 12:03:04 -0700128 static void check(FileTime mtime, FileTime atime, FileTime ctime,
sherman45e33882013-08-28 09:46:55 -0700129 ZipEntry ze, byte[] extra) {
sherman57eb3812013-08-08 12:03:04 -0700130 /*
131 System.out.printf(" mtime [%tc]: [%tc]/[%tc]%n",
132 mtime.to(TimeUnit.MILLISECONDS),
133 ze.getTime(),
134 ze.getLastModifiedTime().to(TimeUnit.MILLISECONDS));
135 */
136 if (mtime.to(TimeUnit.SECONDS) !=
137 ze.getLastModifiedTime().to(TimeUnit.SECONDS))
138 throw new RuntimeException("Timestamp: storing mtime failed!");
139 if (atime != null &&
140 atime.to(TimeUnit.SECONDS) !=
141 ze.getLastAccessTime().to(TimeUnit.SECONDS))
142 throw new RuntimeException("Timestamp: storing atime failed!");
143 if (ctime != null &&
144 ctime.to(TimeUnit.SECONDS) !=
145 ze.getCreationTime().to(TimeUnit.SECONDS))
146 throw new RuntimeException("Timestamp: storing ctime failed!");
sherman45e33882013-08-28 09:46:55 -0700147 if (extra != null) {
148 // if extra data exists, the current implementation put it at
149 // the end of the extra data array (implementation detail)
150 byte[] extra1 = ze.getExtra();
151 if (extra1 == null || extra1.length < extra.length ||
152 !Arrays.equals(Arrays.copyOfRange(extra1,
153 extra1.length - extra.length,
154 extra1.length),
155 extra)) {
156 throw new RuntimeException("Timestamp: storing extra field failed!");
157 }
158 }
sherman21984b02013-05-29 19:50:47 -0700159 }
redestadb3be0a22015-02-21 13:46:24 +0100160
161 static void testNullHandling() {
162 ZipEntry ze = new ZipEntry("TestExtraTime.java");
163 try {
164 ze.setLastAccessTime(null);
165 throw new RuntimeException("setLastAccessTime(null) should throw NPE");
166 } catch (NullPointerException ignored) {
167 // pass
168 }
169 try {
170 ze.setCreationTime(null);
171 throw new RuntimeException("setCreationTime(null) should throw NPE");
172 } catch (NullPointerException ignored) {
173 // pass
174 }
175 try {
176 ze.setLastModifiedTime(null);
177 throw new RuntimeException("setLastModifiedTime(null) should throw NPE");
178 } catch (NullPointerException ignored) {
179 // pass
180 }
181 }
sherman19560202015-03-18 09:46:09 -0700182
183 // verify that setting and getting any time is possible as per the intent
184 // of 4759491
185 static void testTimeConversions() {
186 // Sample across the entire range
187 long step = Long.MAX_VALUE / 100L;
188 testTimeConversions(Long.MIN_VALUE, Long.MAX_VALUE - step, step);
189
190 // Samples through the near future
191 long currentTime = System.currentTimeMillis();
192 testTimeConversions(currentTime, currentTime + 1_000_000, 10_000);
193 }
194
195 static void testTimeConversions(long from, long to, long step) {
196 ZipEntry ze = new ZipEntry("TestExtraTime.java");
197 for (long time = from; time <= to; time += step) {
198 ze.setTime(time);
199 FileTime lastModifiedTime = ze.getLastModifiedTime();
200 if (lastModifiedTime.toMillis() != time) {
201 throw new RuntimeException("setTime should make getLastModifiedTime " +
202 "return the specified instant: " + time +
203 " got: " + lastModifiedTime.toMillis());
204 }
205 if (ze.getTime() != time) {
206 throw new RuntimeException("getTime after setTime, expected: " +
207 time + " got: " + ze.getTime());
208 }
209 }
210 }
shermand940d0f2015-04-07 08:52:44 -0700211
212 static void check(ZipEntry ze, byte[] extra) {
213 if (extra != null) {
214 byte[] extra1 = ze.getExtra();
215 if (extra1 == null || extra1.length < extra.length ||
216 !Arrays.equals(Arrays.copyOfRange(extra1,
217 extra1.length - extra.length,
218 extra1.length),
219 extra)) {
220 throw new RuntimeException("Timestamp: storing extra field failed!");
221 }
222 }
223 }
224
225 static void testTagOnlyHandling() throws Throwable {
226 ByteArrayOutputStream baos = new ByteArrayOutputStream();
227 byte[] extra = new byte[] { 0x0a, 0, 4, 0, 0, 0, 0, 0 };
228 try (ZipOutputStream zos = new ZipOutputStream(baos)) {
229 ZipEntry ze = new ZipEntry("TestExtraTime.java");
230 ze.setExtra(extra);
231 zos.putNextEntry(ze);
232 zos.write(new byte[] { 1,2 ,3, 4});
233 }
234 try (ZipInputStream zis = new ZipInputStream(
235 new ByteArrayInputStream(baos.toByteArray()))) {
236 ZipEntry ze = zis.getNextEntry();
237 check(ze, extra);
238 }
239 Path zpath = Paths.get(System.getProperty("test.dir", "."),
240 "TestExtraTime.zip");
241 Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
242 try (ZipFile zf = new ZipFile(zpath.toFile())) {
243 ZipEntry ze = zf.getEntry("TestExtraTime.java");
244 check(ze, extra);
245 } finally {
246 Files.delete(zpath);
247 }
248 }
sherman21984b02013-05-29 19:50:47 -0700249}