1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * 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 26 * @bug 8165944 27 * @summary test several jar tool input file scenarios with variations on -C 28 * options with/without a --release option. Some input files are 29 * duplicates that sometimes cause exceptions and other times do not, 30 * demonstrating identical behavior to JDK 8 jar tool. 31 * @library /lib/testlibrary 32 * @modules jdk.jartool/sun.tools.jar 33 * @build jdk.testlibrary.FileUtils 34 * @run testng InputFilesTest 35 */ 36 37 import org.testng.Assert; 38 import org.testng.annotations.AfterMethod; 39 import org.testng.annotations.BeforeMethod; 40 import org.testng.annotations.Test; 41 42 import java.io.ByteArrayOutputStream; 43 import java.io.IOException; 44 import java.io.PrintStream; 45 import java.io.UncheckedIOException; 46 import java.nio.file.Files; 47 import java.nio.file.Path; 48 import java.nio.file.Paths; 49 import java.util.Arrays; 50 import java.util.stream.Stream; 51 import java.util.zip.ZipException; 52 53 import jdk.testlibrary.FileUtils; 54 55 public class InputFilesTest { 56 private final String nl = System.lineSeparator(); 57 private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 58 private final PrintStream out = new PrintStream(baos); 59 private Runnable onCompletion; 60 61 @BeforeMethod 62 public void reset() { 63 onCompletion = null; 64 } 65 66 @AfterMethod 67 public void run() { 68 if (onCompletion != null) { 69 onCompletion.run(); 70 } 71 } 72 73 @Test 74 public void test1() throws IOException { 75 mkdir("test1 test2"); 76 touch("test1/testfile1 test2/testfile2"); 77 jar("cf test.jar -C test1 . -C test2 ."); 78 jar("tf test.jar"); 79 println(); 80 String output = "META-INF/" + nl + 81 "META-INF/MANIFEST.MF" + nl + 82 "testfile1" + nl + 83 "testfile2" + nl; 84 rm("test.jar test1 test2"); 85 Assert.assertEquals(baos.toByteArray(), output.getBytes()); 86 } 87 88 @Test 89 public void test2() throws IOException { 90 mkdir("test1 test2 test3 test4"); 91 touch("test1/testfile1 test2/testfile2 test3/testfile3 test4/testfile4"); 92 jar("cf test.jar -C test1 . -C test2 . --release 9 -C test3 . -C test4 ."); 93 jar("tf test.jar"); 94 println(); 95 String output = "META-INF/" + nl + 96 "META-INF/MANIFEST.MF" + nl + 97 "testfile1" + nl + 98 "testfile2" + nl + 99 "META-INF/versions/9/testfile3" + nl + 100 "META-INF/versions/9/testfile4" + nl; 101 rm("test.jar test1 test2 test3 test4"); 102 Assert.assertEquals(baos.toByteArray(), output.getBytes()); 103 } 104 105 @Test 106 public void test3() throws IOException { 107 touch("test"); 108 jar("cf test.jar test test"); 109 jar("tf test.jar"); 110 println(); 111 String output = "META-INF/" + nl + 112 "META-INF/MANIFEST.MF" + nl + 113 "test" + nl; 114 rm("test.jar test"); 115 Assert.assertEquals(baos.toByteArray(), output.getBytes()); 116 } 117 118 @Test 119 public void test4() throws IOException { 120 mkdir("a"); 121 touch("a/test"); 122 jar("cf test.jar -C a test -C a test"); 123 jar("tf test.jar"); 124 println(); 125 String output = "META-INF/" + nl + 126 "META-INF/MANIFEST.MF" + nl + 127 "test" + nl; 128 rm("test.jar a"); 129 Assert.assertEquals(baos.toByteArray(), output.getBytes()); 130 } 131 132 @Test(expectedExceptions = {ZipException.class}) 133 public void test5() throws IOException { 134 mkdir("a"); 135 touch("test a/test"); 136 onCompletion = () -> rm("test a"); 137 jar("cf test.jar -C a test test"); 138 } 139 140 @Test(expectedExceptions = {ZipException.class}) 141 public void test6() throws IOException { 142 mkdir("test1 test2"); 143 touch("test1/a test2/a"); 144 onCompletion = () -> rm("test1 test2"); 145 jar("cf test.jar --release 9 -C test1 a -C test2 a"); 146 } 147 148 private Stream<Path> mkpath(String... args) { 149 return Arrays.stream(args).map(d -> Paths.get(".", d.split("/"))); 150 } 151 152 private void mkdir(String cmdline) { 153 System.out.println("mkdir -p " + cmdline); 154 mkpath(cmdline.split(" +")).forEach(p -> { 155 try { 156 Files.createDirectories(p); 157 } catch (IOException x) { 158 throw new UncheckedIOException(x); 159 } 160 }); 161 } 162 163 private void touch(String cmdline) { 164 System.out.println("touch " + cmdline); 165 mkpath(cmdline.split(" +")).forEach(p -> { 166 try { 167 Files.createFile(p); 168 } catch (IOException x) { 169 throw new UncheckedIOException(x); 170 } 171 }); 172 } 173 174 private void rm(String cmdline) { 175 System.out.println("rm -rf " + cmdline); 176 mkpath(cmdline.split(" +")).forEach(p -> { 177 try { 178 if (Files.isDirectory(p)) { 179 FileUtils.deleteFileTreeWithRetry(p); 180 } else { 181 FileUtils.deleteFileIfExistsWithRetry(p); 182 } 183 } catch (IOException x) { 184 throw new UncheckedIOException(x); 185 } 186 }); 187 } 188 189 private void jar(String cmdline) throws IOException { 190 System.out.println("jar " + cmdline); 191 baos.reset(); 192 193 // the run method catches IOExceptions, we need to expose them 194 ByteArrayOutputStream baes = new ByteArrayOutputStream(); 195 PrintStream err = new PrintStream(baes); 196 PrintStream saveErr = System.err; 197 System.setErr(err); 198 boolean ok = new sun.tools.jar.Main(out, err, "jar").run(cmdline.split(" +")); 199 System.setErr(saveErr); 200 if (!ok) { 201 String s = baes.toString(); 202 if (s.startsWith("java.util.zip.ZipException: duplicate entry: ")) { 203 throw new ZipException(s); 204 } 205 throw new IOException(s); 206 } 207 } 208 209 private void println() throws IOException { 210 System.out.println(new String(baos.toByteArray())); 211 } 212 }