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 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.spi.ToolProvider; 51 import java.util.stream.Stream; 52 import java.util.zip.ZipException; 53 54 import jdk.testlibrary.FileUtils; 55 56 public class InputFilesTest { 57 private static final ToolProvider JAR_TOOL = 58 ToolProvider.findFirst("jar").get(); 59 60 private final String nl = System.lineSeparator(); 61 private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 62 private final PrintStream out = new PrintStream(baos); 63 private Runnable onCompletion; 64 65 @BeforeMethod 66 public void reset() { 67 onCompletion = null; 68 } 69 70 @AfterMethod 71 public void run() { 72 if (onCompletion != null) { 73 onCompletion.run(); 74 } 75 } 76 77 @Test 78 public void test1() throws IOException { 79 mkdir("test1 test2"); 80 touch("test1/testfile1 test2/testfile2"); 81 jar("cf test.jar -C test1 . -C test2 ."); 82 jar("tf test.jar"); 83 println(); 84 String output = "META-INF/" + nl + 85 "META-INF/MANIFEST.MF" + nl + 86 "testfile1" + nl + 87 "testfile2" + nl; 88 rm("test.jar test1 test2"); 89 Assert.assertEquals(baos.toByteArray(), output.getBytes()); 90 } 91 92 @Test 93 public void test2() throws IOException { 94 mkdir("test1 test2 test3 test4"); 95 touch("test1/testfile1 test2/testfile2 test3/testfile3 test4/testfile4"); 96 jar("cf test.jar -C test1 . -C test2 . --release 9 -C test3 . -C test4 ."); 97 jar("tf test.jar"); 98 println(); 99 String output = "META-INF/" + nl + 100 "META-INF/MANIFEST.MF" + nl + 101 "testfile1" + nl + 102 "testfile2" + nl + 103 "META-INF/versions/9/testfile3" + nl + 104 "META-INF/versions/9/testfile4" + nl; 105 rm("test.jar test1 test2 test3 test4"); 106 Assert.assertEquals(baos.toByteArray(), output.getBytes()); 107 } 108 109 @Test 110 public void test3() throws IOException { 111 touch("test"); 112 jar("cf test.jar test test"); 113 jar("tf test.jar"); 114 println(); 115 String output = "META-INF/" + nl + 116 "META-INF/MANIFEST.MF" + nl + 117 "test" + nl; 118 rm("test.jar test"); 119 Assert.assertEquals(baos.toByteArray(), output.getBytes()); 120 } 121 122 @Test 123 public void test4() throws IOException { 124 mkdir("a"); 125 touch("a/test"); 126 jar("cf test.jar -C a test -C a test"); 127 jar("tf test.jar"); 128 println(); 129 String output = "META-INF/" + nl + 130 "META-INF/MANIFEST.MF" + nl + 131 "test" + nl; 132 rm("test.jar a"); 133 Assert.assertEquals(baos.toByteArray(), output.getBytes()); 134 } 135 136 @Test(expectedExceptions = {ZipException.class}) 137 public void test5() throws IOException { 138 mkdir("a"); 139 touch("test a/test"); 140 onCompletion = () -> rm("test a"); 141 jar("cf test.jar -C a test test"); 142 } 143 144 @Test(expectedExceptions = {ZipException.class}) 145 public void test6() throws IOException { 146 mkdir("test1 test2"); 147 touch("test1/a test2/a"); 148 onCompletion = () -> rm("test1 test2"); 149 jar("cf test.jar --release 9 -C test1 a -C test2 a"); 150 } 151 152 private Stream<Path> mkpath(String... args) { 153 return Arrays.stream(args).map(d -> Paths.get(".", d.split("/"))); 154 } 155 156 private void mkdir(String cmdline) { 157 System.out.println("mkdir -p " + cmdline); 158 mkpath(cmdline.split(" +")).forEach(p -> { 159 try { 160 Files.createDirectories(p); 161 } catch (IOException x) { 162 throw new UncheckedIOException(x); 163 } 164 }); 165 } 166 167 private void touch(String cmdline) { 168 System.out.println("touch " + cmdline); 169 mkpath(cmdline.split(" +")).forEach(p -> { 170 try { 171 Files.createFile(p); 172 } catch (IOException x) { 173 throw new UncheckedIOException(x); 174 } 175 }); 176 } 177 178 private void rm(String cmdline) { 179 System.out.println("rm -rf " + cmdline); 180 mkpath(cmdline.split(" +")).forEach(p -> { 181 try { 182 if (Files.isDirectory(p)) { 183 FileUtils.deleteFileTreeWithRetry(p); 184 } else { 185 FileUtils.deleteFileIfExistsWithRetry(p); 186 } 187 } catch (IOException x) { 188 throw new UncheckedIOException(x); 189 } 190 }); 191 } 192 193 private void jar(String cmdline) throws IOException { 194 System.out.println("jar " + cmdline); 195 baos.reset(); 196 197 // the run method catches IOExceptions, we need to expose them 198 ByteArrayOutputStream baes = new ByteArrayOutputStream(); 199 PrintStream err = new PrintStream(baes); 200 PrintStream saveErr = System.err; 201 System.setErr(err); 202 int rc = JAR_TOOL.run(out, err, cmdline.split(" +")); 203 System.setErr(saveErr); 204 if (rc != 0) { 205 String s = baes.toString(); 206 if (s.startsWith("java.util.zip.ZipException: duplicate entry: ")) { 207 throw new ZipException(s); 208 } 209 throw new IOException(s); 210 } 211 } 212 213 private void println() throws IOException { 214 System.out.println(new String(baos.toByteArray())); 215 } 216 }