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