Path: blob/master/test/jdk/tools/jar/JarEntryTime.java
41144 views
/*1* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 4225317 696965126* @modules jdk.jartool27* @summary Check extracted files have date as per those in the .jar file28*/2930import java.io.File;31import java.io.PrintWriter;32import java.nio.file.attribute.FileTime;33import java.util.Date;34import java.util.TimeZone;35import java.util.spi.ToolProvider;3637public class JarEntryTime {38static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")39.orElseThrow(() ->40new RuntimeException("jar tool not found")41);424344// ZipEntry's mod date has 2 seconds precision: give extra time to45// allow for e.g. rounding/truncation and networked/samba drives.46static final long PRECISION = 10000L;4748static final TimeZone TZ = TimeZone.getDefault();49static final boolean DST = TZ.inDaylightTime(new Date());5051static boolean cleanup(File dir) throws Throwable {52boolean rc = true;53File[] x = dir.listFiles();54if (x != null) {55for (int i = 0; i < x.length; i++) {56rc &= x[i].delete();57}58}59return rc & dir.delete();60}6162static void extractJar(File jarFile, boolean useExtractionTime) throws Throwable {63String javahome = System.getProperty("java.home");64String jarcmd = javahome + File.separator + "bin" + File.separator + "jar";65String[] args;66if (useExtractionTime) {67args = new String[] {68jarcmd,69"-J-Dsun.tools.jar.useExtractionTime=true",70"xf",71jarFile.getName() };72} else {73args = new String[] {74jarcmd,75"xf",76jarFile.getName() };77}78Process p = Runtime.getRuntime().exec(args);79check(p != null && (p.waitFor() == 0));80}8182public static void realMain(String[] args) throws Throwable {8384File dirOuter = new File("outer");85File dirInner = new File(dirOuter, "inner");86File jarFile = new File("JarEntryTime.jar");87File testFile = new File("JarEntryTimeTest.txt");8889// Remove any leftovers from prior run90cleanup(dirInner);91cleanup(dirOuter);92jarFile.delete();93testFile.delete();9495/* Create a directory structure96* outer/97* inner/98* foo.txt99* Set the lastModified dates so that outer is created now, inner100* yesterday, and foo.txt created "earlier".101*/102check(dirOuter.mkdir());103check(dirInner.mkdir());104File fileInner = new File(dirInner, "foo.txt");105try (PrintWriter pw = new PrintWriter(fileInner)) {106pw.println("hello, world");107}108109// Get the "now" from the "last-modified-time" of the last file we110// just created, instead of the "System.currentTimeMillis()", to111// workaround the possible "time difference" due to nfs.112final long now = fileInner.lastModified();113final long earlier = now - (60L * 60L * 6L * 1000L);114final long yesterday = now - (60L * 60L * 24L * 1000L);115116check(dirOuter.setLastModified(now));117check(dirInner.setLastModified(yesterday));118check(fileInner.setLastModified(earlier));119120// Make a jar file from that directory structure121check(JAR_TOOL.run(System.out, System.err,122"cf", jarFile.getName(), dirOuter.getName()) == 0);123check(jarFile.exists());124125check(cleanup(dirInner));126check(cleanup(dirOuter));127128// Extract and check that the last modified values are those specified129// in the archive130extractJar(jarFile, false);131check(dirOuter.exists());132check(dirInner.exists());133check(fileInner.exists());134checkFileTime(dirOuter.lastModified(), now);135checkFileTime(dirInner.lastModified(), yesterday);136checkFileTime(fileInner.lastModified(), earlier);137138check(cleanup(dirInner));139check(cleanup(dirOuter));140141try (PrintWriter pw = new PrintWriter(testFile)) {142pw.println("hello, world");143}144final long start = testFile.lastModified();145146// Extract and check the last modified values are the current times.147extractJar(jarFile, true);148149try (PrintWriter pw = new PrintWriter(testFile)) {150pw.println("hello, world");151}152final long end = testFile.lastModified();153154check(dirOuter.exists());155check(dirInner.exists());156check(fileInner.exists());157checkFileTime(start, dirOuter.lastModified(), end);158checkFileTime(start, dirInner.lastModified(), end);159checkFileTime(start, fileInner.lastModified(), end);160161check(cleanup(dirInner));162check(cleanup(dirOuter));163164check(jarFile.delete());165check(testFile.delete());166}167168static void checkFileTime(long now, long original) {169if (isTimeSettingChanged()) {170return;171}172173if (Math.abs(now - original) > PRECISION) {174System.out.format("Extracted to %s, expected to be close to %s%n",175FileTime.fromMillis(now), FileTime.fromMillis(original));176fail();177}178}179180static void checkFileTime(long start, long now, long end) {181if (isTimeSettingChanged()) {182return;183}184185if (now < start || now > end) {186System.out.format("Extracted to %s, "187+ "expected to be after %s and before %s%n",188FileTime.fromMillis(now),189FileTime.fromMillis(start),190FileTime.fromMillis(end));191fail();192}193}194195private static boolean isTimeSettingChanged() {196TimeZone currentTZ = TimeZone.getDefault();197boolean currentDST = currentTZ.inDaylightTime(new Date());198return (!currentTZ.equals(TZ) || currentDST != DST);199}200201//--------------------- Infrastructure ---------------------------202static volatile int passed = 0, failed = 0;203static void pass() {passed++;}204static void fail() {failed++; Thread.dumpStack();}205static void fail(String msg) {System.out.println(msg); fail();}206static void unexpected(Throwable t) {failed++; t.printStackTrace();}207static void check(boolean cond) {if (cond) pass(); else fail();}208static void equal(Object x, Object y) {209if (x == null ? y == null : x.equals(y)) pass();210else fail(x + " not equal to " + y);}211public static void main(String[] args) throws Throwable {212try {realMain(args);} catch (Throwable t) {unexpected(t);}213System.out.println("\nPassed = " + passed + " failed = " + failed);214if (failed > 0) throw new AssertionError("Some tests failed");}215}216217218