diff --git a/tests/release-test/README.MD b/tests/release-test/README.MD new file mode 100644 index 0000000000..395ec2af10 --- /dev/null +++ b/tests/release-test/README.MD @@ -0,0 +1,20 @@ +[//]: # " Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. " +[//]: # " " +[//]: # " This program and the accompanying materials are made available under the " +[//]: # " terms of the Eclipse Public License v. 2.0, which is available at " +[//]: # " http://www.eclipse.org/legal/epl-2.0. " +[//]: # " " +[//]: # " This Source Code may also be made available under the following Secondary " +[//]: # " Licenses when the conditions for such availability set forth in the " +[//]: # " Eclipse Public License v. 2.0 are satisfied: GNU General Public License, " +[//]: # " version 2 with the GNU Classpath Exception, which is available at " +[//]: # " https://www.gnu.org/software/classpath/license.html. " +[//]: # " " +[//]: # " SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 " + +This module is to check the built artifacts before release. + +The module can check Jersey 2.x, 3.0.x, and 3.1.x versions. + +Usage: + * mvn test -Djersey.version= [-Pstaging] diff --git a/tests/release-test/pom.xml b/tests/release-test/pom.xml new file mode 100644 index 0000000000..7199c0bf26 --- /dev/null +++ b/tests/release-test/pom.xml @@ -0,0 +1,122 @@ + + + + + 4.0.0 + + + org.eclipse.ee4j + project + 1.0.7 + ../../../pom.xml + + + org.glassfish.jersey.tests + release-test + 2.37-SNAPSHOT + jar + jersey-release-test + + Jersey post-release validation tests + + + ${jersey.version} + 11 + 11 + 3.8.6 + 1.7.3 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M7 + + 1 + false + false + + **/DownloadBomPomDependencies.java + **/*Test.class + + + + + + + + + + org.glassfish.jersey + jersey-bom + ${jersey.version} + import + pom + + + + + + + junit + junit + 4.13.2 + test + + + + + org.apache.maven + maven-core + ${maven.version} + provided + + + org.apache.maven + maven-model + ${maven.version} + provided + + + org.apache.maven + maven-compat + ${maven.version} + provided + + + + org.apache.maven.plugin-testing + maven-plugin-testing-harness + 3.3.0 + test + + + org.apache.maven.resolver + maven-resolver-connector-basic + ${maven.resolver.version} + + + org.apache.maven.resolver + maven-resolver-transport-http + ${maven.resolver.version} + + + diff --git a/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/ClassVersionChecker.java b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/ClassVersionChecker.java new file mode 100644 index 0000000000..43e5327356 --- /dev/null +++ b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/ClassVersionChecker.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +package org.glassfish.jersey.test.artifacts; + +import java.io.DataInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +class ClassVersionChecker { + static TestResult checkClassVersion(JarFile jar, JarEntry entry, Properties properties) throws IOException { + final String jerseyVersion = MavenUtil.getJerseyVersion(properties); + final int minVersion = jerseyVersion.startsWith("3.1") ? 11 : 8; + return checkClassVersion(jar.getInputStream(entry), jar.getName() + File.separator + entry.getName(), minVersion); + } + + private static TestResult checkClassVersion(InputStream inputStream, String filename, int version) throws IOException { + TestResult result = new TestResult(); + DataInputStream in = new DataInputStream(inputStream); + + int magic = in.readInt(); + if (magic != -889275714) { + result.exception().append(filename).println(" is not a valid class!"); + } + + int minor = in.readUnsignedShort(); + int major = in.readUnsignedShort(); + int classVersion = convertMajorMinorToSE(major, minor); + TestResult.MessageBuilder builder = classVersion <= version ? result.ok() : result.exception(); + builder.append(filename).append(": ").append(major).append(".").append(minor).append(" = JDK ") + .println(String.valueOf(classVersion)); + in.close(); + return result; + } + + private static int convertMajorMinorToSE(int major, int minor) { + int comp = (major - 44 + minor); + return comp; + } +} diff --git a/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyPair.java b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyPair.java new file mode 100644 index 0000000000..dd31588bc8 --- /dev/null +++ b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyPair.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +package org.glassfish.jersey.test.artifacts; + +import java.util.Arrays; + +class DependencyPair { + private final String groupId; + private final String artifactId; + + DependencyPair(String groupId, String artifactId) { + this.groupId = groupId; + this.artifactId = artifactId; + } + + String artifactId() { + return artifactId; + } + + String groupId() { + return groupId; + } + + static DependencyPair[] concat(DependencyPair[] first, DependencyPair[] second) { + DependencyPair[] result = Arrays.copyOf(first, first.length + second.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + @Override + public String toString() { + return groupId + ':' + artifactId; + } +} diff --git a/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyResolver.java b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyResolver.java new file mode 100644 index 0000000000..5df3bc1e53 --- /dev/null +++ b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyResolver.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +package org.glassfish.jersey.test.artifacts; + +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; + +import java.util.List; + +/** + * + * @author lukas + */ +final class DependencyResolver { + static Artifact resolveArtifact(org.apache.maven.model.Dependency d, List remoteRepos, + RepositorySystem repoSystem, RepositorySystemSession repoSession) + throws ArtifactResolutionException { + DefaultArtifact artifact = new DefaultArtifact( + d.getGroupId(), d.getArtifactId(), d.getClassifier(), d.getType(), d.getVersion() + ); + ArtifactRequest request = new ArtifactRequest(); + request.setArtifact(artifact); + request.setRepositories(remoteRepos); + return repoSystem.resolveArtifact(repoSession, request).getArtifact(); + } +} \ No newline at end of file diff --git a/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/MavenUtil.java b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/MavenUtil.java new file mode 100644 index 0000000000..2c5b3a2869 --- /dev/null +++ b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/MavenUtil.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +package org.glassfish.jersey.test.artifacts; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Model; +import org.apache.maven.model.Profile; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Properties; +import java.util.stream.Stream; + +public final class MavenUtil { + + static final String JERSEY_VERSION = "jersey.version"; + private static final String PROJECT_VERSION = "project.version"; + + static File getArtifactJar(File repositoryRoot, Dependency dependency, Properties properties) { + return getArtifactFile(repositoryRoot, dependency, properties, "jar"); + } + + private static File getArtifactFile(File repositoryRoot, Dependency dependency, Properties properties, String extension) { + StringBuilder fileSuffix = new StringBuilder(); + String groupIdParts[] = dependency.getGroupId().split("\\."); + for (String groupIdPart : groupIdParts) { + fileSuffix.append(groupIdPart).append(File.separator); + } + String artifactIdParts[] = dependency.getArtifactId().split("\\."); + for (String artifactIdPart : artifactIdParts) { + fileSuffix.append(artifactIdPart).append(File.separator); + } + String version = MavenUtil.getDependencyVersion(dependency, properties); + fileSuffix.append(version).append(File.separator); + fileSuffix.append(dependency.getArtifactId()).append('-').append(version).append(".").append(extension); + return new File(repositoryRoot, fileSuffix.toString()); + } + + static String getDependencyVersion(Dependency dependency, Properties properties) { + String version = dependency.getVersion(); + if (version.startsWith("${") && version.endsWith("}")) { + String property = version.substring(2, version.length() - 1); + final String value; + switch (property) { + case JERSEY_VERSION: // in pom.xml + case PROJECT_VERSION: // in bom.pom + value = getJerseyVersion(properties); + break; + default: + value = properties.getProperty(property); + break; + } + version = value == null ? version : value; + } + return version; + } + + static File getLocalMavenRepository() { + String folder = System.getProperty("localRepository"); + return new File(folder); + } + + static Properties getMavenProperties() { + try { + Model model = getModelFromFile("pom.xml"); + return model.getProperties(); + } catch (XmlPullParserException | IOException e) { + throw new RuntimeException(e); + } + } + + static Stream keepJerseyJars(Stream stream, DependencyPair... keep) { + return stream.filter(dependency -> { + for (DependencyPair pair : keep) { + if (dependency.getGroupId().equals(pair.groupId()) && dependency.getArtifactId().equals(pair.artifactId())) { + return true; + } + } + return false; + }); + } + + static Stream streamJerseyJars() throws IOException, XmlPullParserException { + Model model = getModelFromFile("pom.xml"); + List deps = getBomPomDependencies(model); + + return deps.stream() + .filter(dep -> dep.getGroupId().startsWith("org.glassfish.jersey")) + .filter(dep -> dep.getType().equals("jar")); + } + + private static Model getModelFromFile(String fileName) throws IOException, XmlPullParserException { + File pomFile = new File(fileName); + return getModelFromFile(pomFile); + } + + private static Model getModelFromFile(File file) throws IOException, XmlPullParserException { + MavenXpp3Reader mavenReader = new MavenXpp3Reader(); + try (FileReader fileReader = new FileReader(file)) { + Model model = mavenReader.read(fileReader); + return model; + } + } + + private static List getBomPomDependencies(Model model) throws IOException, XmlPullParserException { + Dependency bomPom = null; + List dependencies = model.getDependencyManagement().getDependencies(); + for (Dependency dependency : dependencies) { + if (dependency.getGroupId().equals("org.glassfish.jersey") && dependency.getArtifactId().equals("jersey-bom")) { + bomPom = dependency; + break; + } + } + if (bomPom == null) { + throw new IllegalStateException("Bom pom not found"); + } + File pom = getArtifactFile(getLocalMavenRepository(), bomPom, model.getProperties(), "pom"); + Model bomPomModel = getModelFromFile(pom); + return bomPomModel.getDependencyManagement().getDependencies(); + } + + static String getJerseyVersion(Properties properties) { + String property = properties.getProperty(JERSEY_VERSION); // when it is in the pom.file + if (property == null || property.startsWith("${")) { + property = System.getProperty(JERSEY_VERSION); // not in pom, but -Djersey.version + } + if (property == null || property.startsWith("${")) { + throw new IllegalStateException("Property " + JERSEY_VERSION + " not set (-Djersey.version=)"); + } + return property; + } + + /* Unused at the moment, but could be useful in the future in the case of profiles are needed */ + private static List getProfileDependency(Model model) { + List profileDependencies = Collections.EMPTY_LIST; + List profiles = model.getProfiles(); + String activeProfile = getActiveProfile(); + for (Profile profile : profiles) { + if (activeProfile.equals(profile.getId())) { + profileDependencies = profile.getDependencies(); + break; + } + } + return profileDependencies; + } + + private static String getActiveProfile() { + String profileId = System.getProperty("profileId"); // set this to the surefire plugin + return profileId; + } +} diff --git a/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/TestResult.java b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/TestResult.java new file mode 100644 index 0000000000..172c5967b5 --- /dev/null +++ b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/TestResult.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +package org.glassfish.jersey.test.artifacts; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +class TestResult { + private List oks = new LinkedList<>(); + private List exceptions = new LinkedList<>(); + + MessageBuilder ok() { + return new MessageBuilder(oks); + } + + MessageBuilder exception() { + return new MessageBuilder(exceptions); + } + boolean result() { + for (String ok : oks) { + System.out.append("(pass) ").print(ok); + } + + for (String exception : exceptions) { + System.out.append("\u001b[31;1m(FAIL) ").append(exception).print("\u001b[0m"); + } + + return exceptions.isEmpty(); + } + + public TestResult append(TestResult result) throws IOException { + oks.addAll(result.oks); + exceptions.addAll(result.exceptions); + return this; + } + + class MessageBuilder implements Appendable { + final List list; + final StringBuilder builder = new StringBuilder(); + + MessageBuilder(List list) { + this.list = list; + } + + @Override + public MessageBuilder append(CharSequence csq) throws IOException { + builder.append(csq); + return this; + } + + public MessageBuilder append(int i) throws IOException { + builder.append(i); + return this; + } + + @Override + public MessageBuilder append(CharSequence csq, int start, int end) throws IOException { + builder.append(csq, start, end); + return this; + } + + @Override + public MessageBuilder append(char c) throws IOException { + builder.append(c); + return this; + } + + public TestResult println(String message) { + builder.append(message).append('\n'); + list.add(builder.toString()); + return TestResult.this; + } + } +} diff --git a/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/DownloadBomPomDependencies.java b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/DownloadBomPomDependencies.java new file mode 100644 index 0000000000..ef31d4edf7 --- /dev/null +++ b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/DownloadBomPomDependencies.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +package org.glassfish.jersey.test.artifacts; + +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.impl.DefaultServiceLocator; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; +import org.eclipse.aether.spi.connector.transport.TransporterFactory; +import org.eclipse.aether.transport.http.HttpTransporterFactory; + +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.model.Dependency; +import org.apache.maven.plugin.testing.AbstractMojoTestCase; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.apache.maven.project.ProjectBuildingRequest; +import org.apache.maven.project.ProjectBuildingResult; +import org.apache.maven.repository.internal.MavenRepositorySystemUtils; + +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; +import org.junit.Test; + +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.List; +import java.util.Properties; +import java.util.stream.Collectors; + +public class DownloadBomPomDependencies extends AbstractMojoTestCase { + + @Test + public void testDownloadBomPomDependencies() throws Exception { +// RepositorySystem repositorySystem = (RepositorySystem) lookup(RepositorySystem.class.getName()); + DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); + locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); + locator.addService(TransporterFactory.class, HttpTransporterFactory.class); + RepositorySystem repositorySystem = locator.getService(RepositorySystem.class); + + RepositorySystemSession repoSession = getRepoSession(repositorySystem); + List remoteRepos = getRemoteRepositories(repoSession); + + Properties properties = MavenUtil.getMavenProperties(); + String jerseyVersion = MavenUtil.getJerseyVersion(properties); + List memberDeps = MavenUtil.streamJerseyJars().collect(Collectors.toList()); + for (Dependency member : memberDeps) { + member.setVersion(jerseyVersion); + Artifact m = DependencyResolver.resolveArtifact(member, remoteRepos, repositorySystem, repoSession); + System.out.append("Resolved ").append(member.getGroupId()).append(":").append(member.getArtifactId()).append(":") + .append(member.getVersion()).append(" to ").println(m.getFile().getName()); + } + } + + private List getRemoteRepositories(RepositorySystemSession session) throws Exception { + File pom = lookupResourcesPom("/release-test-pom.xml"); + MavenExecutionRequest request = new DefaultMavenExecutionRequest(); + request.setPom(pom); + request.addActiveProfile("staging"); + ProjectBuildingRequest buildingRequest = request + .getProjectBuildingRequest() + .setRepositorySession(session) + .setResolveDependencies(true); + + ProjectBuilder projectBuilder = lookup(ProjectBuilder.class); + ProjectBuildingResult projectBuildingResult = projectBuilder.build(pom, buildingRequest); + MavenProject project = projectBuildingResult.getProject(); + + List remoteArtifactRepositories = project.getRemoteProjectRepositories(); + return remoteArtifactRepositories; + } + + private static RepositorySystemSession getRepoSession(RepositorySystem repositorySystem) { + DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); + LocalRepository localRepo = new LocalRepository(MavenUtil.getLocalMavenRepository().getAbsolutePath()); + session.setLocalRepositoryManager(repositorySystem.newLocalRepositoryManager(session, localRepo)); + return session; + } + + private static File lookupResourcesPom(String pomFile) throws URISyntaxException { + URL resource = DownloadBomPomDependencies.class.getResource(pomFile); + if (resource == null) { + throw new IllegalStateException("Pom file " + pomFile + " was not located on classpath!"); + } + File file = new File(resource.toURI()); + if (!file.exists()) { + throw new IllegalStateException("Cannot locate test pom xml file!"); + } + return file; + } +} diff --git a/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/ManifestTest.java b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/ManifestTest.java new file mode 100644 index 0000000000..8da0835edb --- /dev/null +++ b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/ManifestTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +package org.glassfish.jersey.test.artifacts; + +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Properties; +import java.util.jar.JarFile; +import java.util.stream.Collectors; + +public class ManifestTest { + private static final File localRepository = MavenUtil.getLocalMavenRepository(); + private static final Properties properties = MavenUtil.getMavenProperties(); + + private static final String BUNDLE_NAME_ATTRIBUTE = "Bundle-Name"; + private static final String BUNDLE_VERSION_ATTRIBUTE = "Bundle-Version"; + private static final String [] EXCLUDED_JARS = {"test", "rx-client", "oauth", "weld2-se", "spring", + "servlet-portability", /* obsolete */ + "helidon-connector", /* Helidon does not contain OSGi headers */ + "grizzly-connector", /* Limited maintenance */ + }; + + @Test + public void testHasOsgiManifest() throws IOException, XmlPullParserException { + TestResult testResult = new TestResult(); + List jars = MavenUtil.streamJerseyJars() + .filter(dependency -> { + for (String excluded : EXCLUDED_JARS) { + if (dependency.getArtifactId().contains(excluded)) { + return false; + } + } + return true; + }) + .map(dependency -> MavenUtil.getArtifactJar(localRepository, dependency, properties)) + .collect(Collectors.toList()); + + for (String ATTRIBUTE : new String[]{BUNDLE_NAME_ATTRIBUTE, BUNDLE_VERSION_ATTRIBUTE}) { + for (File jar : jars) { + JarFile jarFile = new JarFile(jar); + String value = jarFile.getManifest().getMainAttributes().getValue(ATTRIBUTE); + TestResult.MessageBuilder builder = value != null ? testResult.ok() : testResult.exception(); + builder.append(jar.getName()).append(value == null ? " DOES NOT CONTAIN " : " CONTAINS ") + .append(ATTRIBUTE).println(" attribute"); + } + } + + //Assertions.assertTrue(testResult.result(), "Some error occurred, see previous messages"); + Assert.assertTrue("Some error occurred, see previous messages", testResult.result()); + } + +} diff --git a/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/MultiReleaseTest.java b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/MultiReleaseTest.java new file mode 100644 index 0000000000..deef29ac70 --- /dev/null +++ b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/MultiReleaseTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +package org.glassfish.jersey.test.artifacts; + +import org.apache.maven.model.Dependency; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.Properties; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; + +public class MultiReleaseTest { + private static final String s = ""; + private static final File localRepository = MavenUtil.getLocalMavenRepository(); + private static final Properties properties = MavenUtil.getMavenProperties(); + + private static final DependencyPair[] jdk11multiRelease = jdk11multiRelease(properties); + private static final DependencyPair[] jdk12multiRelease = jdk12multiRelease(properties); + private static final DependencyPair[] jdk17multiRelease = jdk17multiRelease(properties); + + @Test + public void testIsJdkMultiRelease() throws IOException, XmlPullParserException { + TestResult result = testJdkVersions("11", jdk11multiRelease); + result.append(testJdkVersions("12", jdk12multiRelease)); + result.append(testJdkVersions("17", jdk17multiRelease)); + //Assertions.assertTrue(result.result(), "Some error occurred, see previous messages"); + Assert.assertTrue("Some error occurred, see previous messages", result.result()); + } + + private static TestResult testJdkVersions(String version, DependencyPair... dependencies) + throws XmlPullParserException, IOException { + final TestResult result = new TestResult(); + if (dependencies == null || dependencies.length == 0) { + return result; + } + + Stream deps = MavenUtil.streamJerseyJars(); + List files = MavenUtil.keepJerseyJars(deps, dependencies) + .map(dependency -> MavenUtil.getArtifactJar(localRepository, dependency, properties)) + .collect(Collectors.toList()); + + //Assertions.assertEquals(dependencies.length, files.size(), "Some jdk " + version + " dependencies not found"); + if (dependencies.length != files.size()) { + System.out.println("Expected:"); + for (DependencyPair pair : dependencies) { + System.out.println(pair); + } + System.out.println("Resolved:"); + for (File file : files) { + System.out.println(file.getName()); + } + Assert.assertEquals("Some jdk " + version + " dependencies not found", dependencies.length, files.size()); + } + + for (File jar : files) { + JarFile jarFile = new JarFile(jar); + if (!jarFile.isMultiRelease()) { + result.exception().append("Not a multirelease jar ").append(jar.getName()).println("!"); + } + ZipEntry versions = jarFile.getEntry("META-INF/versions/" + version); + if (versions == null) { + result.exception().append("No classes for JDK ").append(version).append(" for ").println(jar.getName()); + } + result.ok().append("Classes for JDK ").append(version).append(" found for ").println(jar.getName()); + + Optional file = jarFile.stream() + .filter(entry -> !entry.isDirectory()) + .filter(entry -> !entry.getName().contains("versions")) + .filter(entry -> entry.getName().endsWith(".class")) + .findAny(); + JarEntry jarEntry = file.get(); + result.append(ClassVersionChecker.checkClassVersion(jarFile, jarEntry, properties)); + } + + return result; + } + + private static DependencyPair[] jdk11multiRelease(Properties properties) { + String jerseyVersion = MavenUtil.getJerseyVersion(properties); + if (jerseyVersion.startsWith("3.0")) { + return jdk11multiRelease30(); + } else if (jerseyVersion.startsWith("3")) { + return jdk11multiRelease31(); + } + return jdk11multiRelease2(); + } + + private static DependencyPair[] jdk11multiRelease2() { + return new DependencyPair[] { + new DependencyPair("org.glassfish.jersey.bundles", "jaxrs-ri"), + new DependencyPair("org.glassfish.jersey.core", "jersey-common") + }; + } + + private static DependencyPair[] jdk11multiRelease30() { + DependencyPair[] pairs30 = { + new DependencyPair("org.glassfish.jersey.containers", "jersey-container-jetty-http"), + new DependencyPair("org.glassfish.jersey.containers", "jersey-container-jetty-servlet"), + new DependencyPair("org.glassfish.jersey.test-framework.providers", "jersey-test-framework-provider-jetty") + }; + return DependencyPair.concat(jdk11multiRelease2(), pairs30); + } + + private static DependencyPair[] jdk11multiRelease31() { + return new DependencyPair[]{}; + } + + private static DependencyPair[] jdk12multiRelease(Properties properties) { + return new DependencyPair[]{ + new DependencyPair("org.glassfish.jersey.ext", "jersey-wadl-doclet") + }; + } + + private static DependencyPair[] jdk17multiRelease(Properties properties) { + String jerseyVersion = MavenUtil.getJerseyVersion(properties); + if (jerseyVersion.startsWith("3")) { + return new DependencyPair[] { + new DependencyPair("org.glassfish.jersey.connectors", "jersey-helidon-connector"), + new DependencyPair("org.glassfish.jersey.ext", "jersey-spring6") + }; + } + return new DependencyPair[]{}; + } +} diff --git a/tests/release-test/src/test/resources/release-test-pom.xml b/tests/release-test/src/test/resources/release-test-pom.xml new file mode 100644 index 0000000000..d8aa48608e --- /dev/null +++ b/tests/release-test/src/test/resources/release-test-pom.xml @@ -0,0 +1,34 @@ + + + + + 4.0.0 + + + org.eclipse.ee4j + project + 1.0.7 + + + org.glassfish.jersey.tests + release-test-test + 0.0.1-SNAPSHOT + + \ No newline at end of file