8166460: jdk/internal/util/jar/TestVersionedStream gets Assertion error

Reviewed-by: psandoz
This commit is contained in:
Steve Drach 2016-10-12 14:31:17 -07:00
parent a19fc7fbdb
commit 71c0fe8710

View File

@ -25,13 +25,14 @@
* @test
* @bug 8163798
* @summary basic tests for multi-release jar versioned streams
* @library /lib/testlibrary
* @modules jdk.jartool/sun.tools.jar java.base/jdk.internal.util.jar
* @build jdk.testlibrary.FileUtils
* @run testng TestVersionedStream
*/
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -40,29 +41,31 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.URI;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipFile;
public class TestVersionedStream {
private String userdir;
import jdk.testlibrary.FileUtils;
@BeforeClass
public void initialize() {
userdir = System.getProperty("user.dir", ".");
public class TestVersionedStream {
private final Path userdir;
private final Set<String> unversionedEntryNames;
public TestVersionedStream() throws IOException {
userdir = Paths.get(System.getProperty("user.dir", "."));
// These are not real class files even though they end with .class.
// They are resource files so jar tool validation won't reject them.
@ -70,91 +73,103 @@ public class TestVersionedStream {
// could be in a concealed package if this was a modular multi-release
// jar.
createFiles(
"base/p/Bar.class",
"base/p/Foo.class",
"base/p/Main.class",
"v9/p/Foo.class",
"v10/p/Foo.class",
"v10/q/Bar.class",
"v11/p/Bar.class",
"v11/p/Foo.class"
);
jar("cf mmr.jar -C base . --release 9 -C v9 . --release 10 -C v10 . --release 11 -C v11 .");
jar("cf mmr.jar -C base . --release 9 -C v9 . " +
"--release 10 -C v10 . --release 11 -C v11 .");
System.out.println("Contents of mmr.jar\n=======");
jar("tf mmr.jar");
try(JarFile jf = new JarFile("mmr.jar")) {
unversionedEntryNames = jf.stream()
.map(je -> je.getName())
.peek(System.out::println)
.map(nm -> nm.startsWith("META-INF/versions/")
? nm.replaceFirst("META-INF/versions/\\d+/", "")
: nm)
.collect(Collectors.toCollection(LinkedHashSet::new));
}
System.out.println("=======");
}
@AfterClass
public void close() throws IOException {
Path root = Paths.get(userdir);
Files.walkFileTree(root, new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
if (!dir.equals(root)) {
Files.delete(dir);
}
return FileVisitResult.CONTINUE;
}
});
Files.walk(userdir, 1)
.filter(p -> !p.equals(userdir))
.forEach(p -> {
try {
if (Files.isDirectory(p)) {
FileUtils.deleteFileTreeWithRetry(p);
} else {
FileUtils.deleteFileIfExistsWithRetry(p);
}
} catch (IOException x) {
throw new UncheckedIOException(x);
}
});
}
@DataProvider
public Object[][] data() {
List<String> p = List.of(
"META-INF/",
"META-INF/MANIFEST.MF",
"p/",
"p/Foo.class",
"p/Main.class"
);
List<String> q = List.of(
"META-INF/",
"META-INF/MANIFEST.MF",
"p/",
"p/Foo.class",
"p/Main.class",
"q/",
"q/Bar.class"
);
Runtime.Version rt = JarFile.runtimeVersion();
return new Object[][] {
{Runtime.Version.parse("8"), p},
{Runtime.Version.parse("9"), p},
{Runtime.Version.parse("10"), q},
{Runtime.Version.parse("11"), q},
{JarFile.baseVersion(), p},
{rt, rt.major() > 9 ? q : p}
{Runtime.Version.parse("8")},
{Runtime.Version.parse("9")},
{Runtime.Version.parse("10")},
{Runtime.Version.parse("11")},
{JarFile.baseVersion()},
{JarFile.runtimeVersion()}
};
}
@Test(dataProvider="data")
public void test(Runtime.Version version, List<String> names) throws Exception {
public void test(Runtime.Version version) throws Exception {
try (JarFile jf = new JarFile(new File("mmr.jar"), false, ZipFile.OPEN_READ, version);
Stream<JarEntry> jes = jdk.internal.util.jar.VersionedStream.stream(jf))
Stream<JarEntry> jes = jdk.internal.util.jar.VersionedStream.stream(jf))
{
Assert.assertNotNull(jes);
List<JarEntry> entries = jes.collect(Collectors.toList());
// put versioned entries in list so we can reuse them
List<JarEntry> versionedEntries = jes.collect(Collectors.toList());
// verify the correct order
List<String> enames = entries.stream()
.map(je -> je.getName())
.collect(Collectors.toList());
Assert.assertEquals(enames, names);
Assert.assertTrue(versionedEntries.size() > 0);
// also keep the names
List<String> versionedNames = new ArrayList<>(versionedEntries.size());
// verify the correct order while building enames
Iterator<String> allIt = unversionedEntryNames.iterator();
Iterator<JarEntry> verIt = versionedEntries.iterator();
boolean match = false;
while (verIt.hasNext()) {
match = false;
if (!allIt.hasNext()) break;
String name = verIt.next().getName();
versionedNames.add(name);
while (allIt.hasNext()) {
if (name.equals(allIt.next())) {
match = true;
break;
}
}
}
if (!match) {
Assert.fail("versioned entries not in same order as unversioned entries");
}
// verify the contents
Map<String,String> contents = new HashMap<>();
contents.put("p/Bar.class", "base/p/Bar.class\n");
contents.put("p/Main.class", "base/p/Main.class\n");
if (version.major() > 9) {
contents.put("q/Bar.class", "v10/q/Bar.class\n");
}
switch (version.major()) {
case 8:
contents.put("p/Foo.class", "base/p/Foo.class\n");
@ -164,9 +179,12 @@ public class TestVersionedStream {
break;
case 10:
contents.put("p/Foo.class", "v10/p/Foo.class\n");
contents.put("q/Bar.class", "v10/q/Bar.class\n");
break;
case 11:
contents.put("p/Bar.class", "v11/p/Bar.class\n");
contents.put("p/Foo.class", "v11/p/Foo.class\n");
contents.put("q/Bar.class", "v10/q/Bar.class\n");
break;
default:
Assert.fail("Test out of date, please add more cases");
@ -174,9 +192,9 @@ public class TestVersionedStream {
contents.entrySet().stream().forEach(e -> {
String name = e.getKey();
int i = enames.indexOf(name);
int i = versionedNames.indexOf(name);
Assert.assertTrue(i != -1, name + " not in enames");
JarEntry je = entries.get(i);
JarEntry je = versionedEntries.get(i);
try (InputStream is = jf.getInputStream(je)) {
String s = new String(is.readAllBytes());
Assert.assertTrue(s.endsWith(e.getValue()), s);
@ -210,5 +228,4 @@ public class TestVersionedStream {
new sun.tools.jar.Main(System.out, System.err, "jar")
.run(args.split(" +"));
}
}