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 = ToolProvider.findFirst("jar") 58 .orElseThrow(() -> 59 new RuntimeException("jar tool not found") 60 ); 61 62 private final String nl = System.lineSeparator(); 63 private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 64 private final PrintStream out = new PrintStream(baos); 65 private Runnable onCompletion; 66 67 @BeforeMethod 68 public void reset() { 69 onCompletion = null; 70 } 71 72 @AfterMethod 73 public void run() { 74 if (onCompletion != null) { 75 onCompletion.run(); 76 } 77 } 78 79 @Test 80 public void test1() throws IOException { 81 mkdir("test1 test2"); 82 touch("test1/testfile1 test2/testfile2"); 83 jar("cf test.jar -C test1 . -C test2 ."); 84 jar("tf test.jar"); 85 println(); 86 String output = "META-INF/" + nl + 87 "META-INF/MANIFEST.MF" + nl + 88 "testfile1" + nl + 89 "testfile2" + nl; 90 rm("test.jar test1 test2"); 91 Assert.assertEquals(baos.toByteArray(), output.getBytes()); 92 } 93 94 @Test 95 public void test2() throws IOException { 96 mkdir("test1 test2 test3 test4"); 97 touch("test1/testfile1 test2/testfile2 test3/testfile3 test4/testfile4"); 98 jar("cf test.jar -C test1 . -C test2 . --release 9 -C test3 . -C test4 ."); 99 jar("tf test.jar"); 100 println(); 101 String output = "META-INF/" + nl + 102 "META-INF/MANIFEST.MF" + nl + 103 "testfile1" + nl + 104 "testfile2" + 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 }