diff --git a/tck-dist/src/main/asciidoc/concurrency-tck-reference-guide.adoc b/tck-dist/src/main/asciidoc/concurrency-tck-reference-guide.adoc index ef62a161..2046a55b 100644 --- a/tck-dist/src/main/asciidoc/concurrency-tck-reference-guide.adoc +++ b/tck-dist/src/main/asciidoc/concurrency-tck-reference-guide.adoc @@ -14,8 +14,8 @@ :APIGitSite: https://github.com/jakartaee/concurrency :TCKTestPlatform: Junit5 -:SigPluginVersion: 1.6 -:SigPluginGAV: org.netbeans.tools:sigtest-maven-plugin:{SigPluginVersion} +:SigPluginVersion: 2.3 +:SigPluginGAV: jakarta.tck:sigtest-maven-plugin:{SigPluginVersion} :JavaVersion1: 17 :JavaVersion2: 21 @@ -268,7 +268,7 @@ The TCK uses external libraries that also need to be available on the Applicatio - org.apache.derby:derby - For database testing - org.junit.jupiter:junit-jupiter - For test assertions -- org.netbeans.tools:sigtest-maven-plugin - For signature testing +- jakarta.tck:sigtest-maven-plugin - For signature testing See <> @@ -330,6 +330,21 @@ Example META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension: my.custom.test.package.MyLoadableExtension ---- +=== Test property reference + +In the previous sections, there were sample configurations that contained information about +the different system properties that can be set under the `` of the Surefire plugin. + +This section contains a complete list of the system properties that will be looked up by the TCK +and a short description of what data each represents. + +Use this reference as a quick guide for customizing how this TCK is run for your implementation. + +include::generated/test-properties.adoc[] + +Note: All non-java properties set on the test client will be exported to the test server, so there is no +need to set the same properties on both. + == Running the TCK Once the TCK Runner project is created and configured the {APIShortName} TCK is run as part of the maven test lifecycle. @@ -356,13 +371,10 @@ The signature tests validate the integrity of the `jakarta.enterprise.concurrent The {APIShortName} TCK will run signature tests on the application server itself, and not as part of a separate plugin / execution. This means that the signature tests will run during the maven `test` phase. -You need to configure your application server with a JVM property `-Djimage.dir=`. -This is because, when running the signature tests on JDK 9+ we need to convert the JDK modules back into class files for signature testing. - The signature test plugin we use will also attempt to perform reflective access of classes, methods, and fields. Due to the new module system in JDK 9+ special permissions need to be added in order for these tests to run: -If you are using a Security Manager add the following permissions to the `sigtest-maven-plugin` on your application server: +If you are using a Security Manager add the following permissions to applications running on your application server: [source, txt] ---- @@ -373,7 +385,7 @@ permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.vm.ann By default the java.base module only exposes certain classes for reflective access. Therefore, the {APIShortName} TCK test will need access to the `jdk.internal.vm.annotation` class. -To give the `sigtest-maven-plugin` access to this class set the following JVM properties: +To give the TCK access to this class set the following JVM properties: [source, properties] ---- diff --git a/tck-dist/src/main/java/ee/jakarta/tck/data/metadata/CollectMetaData.java b/tck-dist/src/main/java/ee/jakarta/tck/data/metadata/CollectMetaData.java index 52310ea6..cdb353ee 100644 --- a/tck-dist/src/main/java/ee/jakarta/tck/data/metadata/CollectMetaData.java +++ b/tck-dist/src/main/java/ee/jakarta/tck/data/metadata/CollectMetaData.java @@ -36,6 +36,7 @@ import org.junit.platform.commons.support.AnnotationSupport; import org.junit.platform.commons.support.HierarchyTraversalMode; +import ee.jakarta.tck.concurrent.framework.TestProperty; import ee.jakarta.tck.concurrent.framework.junit.anno.Assertion; import ee.jakarta.tck.concurrent.framework.junit.anno.Challenge; @@ -111,6 +112,7 @@ public static void main(final String[] args) throws Exception { writeSigOutput(new File(adocGeneratedLocation, SIG_OUTPUT_FILE)); writeOutput(testMetaData, new File(adocGeneratedLocation, EXPECTED_OUTPUT_FILE)); writeGitIgnore(new File(adocGeneratedLocation, ".gitignore"), RUNTIME_TESTS_FILE, CHALLENGED_TESTS_FILE, SIG_OUTPUT_FILE, EXPECTED_OUTPUT_FILE, TEST_PROPERTIES_FILE); + writeTestProperties(new File(adocGeneratedLocation, TEST_PROPERTIES_FILE)); for (TestMetaData data: testMetaData) { debug(data.debugString()); @@ -327,6 +329,36 @@ private static Object[] getTestCounts(final List testMetaData) { return results.toArray(); } + /** + * Compiles a list of all system properties used by the TCK output to the generated adoc folder. + * + * @param outputLocation - the output file + * @throws IOException - exception if we cannot write to this location + */ + private static void writeTestProperties(final File outputLocation) throws IOException { + String output = + """ + |=== + |Key |Required |Description + $properties + |===""".replaceAll("\\$properties", getTestProperties()); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputLocation))) { + writer.write(output.trim() + System.lineSeparator()); + } + } + + private static String getTestProperties() { + String output = ""; + for (TestProperty property : TestProperty.values()) { + output += + """ + + |%s |%s |%s + """.formatted(property.getKey(), property.isRequired(), property.getDescription()); + } + return output; + } + /** * Inspects each class for methods and annotations and constructs a metadata object. * Collects all metadata objects and returns them as a list. diff --git a/tck-dist/src/main/starter/pom.xml b/tck-dist/src/main/starter/pom.xml index 49414471..49f26d15 100644 --- a/tck-dist/src/main/starter/pom.xml +++ b/tck-dist/src/main/starter/pom.xml @@ -112,7 +112,7 @@ - org.netbeans.tools + jakarta.tck sigtest-maven-plugin ${sigtest.version} @@ -144,7 +144,7 @@ ${derby.version} - org.netbeans.tools + jakarta.tck sigtest-maven-plugin ${sigtest.version} @@ -171,6 +171,9 @@ ${maven.surefire.plugin.version} + + ${jimage.dir} + [TODO] [TODO] diff --git a/tck/pom.xml b/tck/pom.xml index b8ce3e4a..b257aef1 100644 --- a/tck/pom.xml +++ b/tck/pom.xml @@ -48,7 +48,7 @@ ${project.version} - 1.6 + 2.3 3.3.0 @@ -92,7 +92,7 @@ - org.netbeans.tools + jakarta.tck sigtest-maven-plugin ${sigtest.version} @@ -267,7 +267,7 @@ - org.netbeans.tools + jakarta.tck sigtest-maven-plugin ${sigtest.version} diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/ApiCheckDriver.java b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/ApiCheckDriver.java index 79c8f26b..b2f74b4b 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/ApiCheckDriver.java +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/ApiCheckDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024 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 @@ -27,10 +27,12 @@ import java.lang.reflect.Method; import java.util.LinkedList; import java.util.List; +import java.util.logging.Logger; public final class ApiCheckDriver extends SignatureTestDriver implements Serializable { - private static final long serialVersionUID = 1L; + + private static final Logger log = Logger.getLogger(ApiCheckDriver.class.getCanonicalName()); /* flags for the Diff utility argument list */ private static final String BASE_FLAG = "-base"; @@ -60,22 +62,14 @@ protected String[] createTestArguments(final String packageListFile, final Strin final boolean bStaticMode) throws Exception { Class pkgListClass = Class.forName("javasoft.sqe.apiCheck.PackageList"); - Constructor pkgCtor = pkgListClass.getDeclaredConstructor(new Class[] { - String.class - }); - Object pkgInstance = pkgCtor.newInstance(new Object[] { - packageListFile - }); + Constructor pkgCtor = pkgListClass.getDeclaredConstructor(new Class[] {String.class}); + Object pkgInstance = pkgCtor.newInstance(new Object[] {packageListFile}); - Method pkgMethod = pkgListClass.getDeclaredMethod("getSubPackagesFormatted", new Class[] { - String.class - }); + Method pkgMethod = pkgListClass.getDeclaredMethod("getSubPackagesFormatted", new Class[] {String.class}); - String excludePkgs = (String) pkgMethod.invoke(pkgInstance, new Object[] { - packageOrClassUnderTest - }); + String excludePkgs = (String) pkgMethod.invoke(pkgInstance, new Object[] {packageOrClassUnderTest}); - List sigArgsList = new LinkedList<>(); + List sigArgsList = new LinkedList(); sigArgsList.add(BASE_FLAG); sigArgsList.add(getSigFileInfo(packageOrClassUnderTest, mapFile, signatureRepositoryDir).getFile()); @@ -103,12 +97,8 @@ protected String[] createTestArguments(final String packageListFile, final Strin protected boolean runSignatureTest(final String packageOrClassName, final String[] testArguments) throws Exception { Class diffClass = Class.forName("javasoft.sqe.apiCheck.Diff"); - Method mainMethod = diffClass.getDeclaredMethod("main", new Class[] { - String[].class - }); - mainMethod.invoke(null, new Object[] { - testArguments - }); + Method mainMethod = diffClass.getDeclaredMethod("main", new Class[] {String[].class}); + mainMethod.invoke(null, new Object[] {testArguments}); Method diffMethod = diffClass.getDeclaredMethod("diffsFound", new Class[] {}); return (!((Boolean) diffMethod.invoke(null, new Object[] {})).booleanValue()); @@ -118,7 +108,7 @@ protected boolean runSignatureTest(final String packageOrClassName, final String @Override protected boolean runPackageSearch(final String packageOrClassName, final String[] testArguments) throws Exception { Class sigTestClass = Class.forName("com.sun.tdk.signaturetest.SignatureTest"); - Object sigTestInstance = sigTestClass.getConstructor().newInstance(); + Object sigTestInstance = sigTestClass.getDeclaredConstructor().newInstance(); ByteArrayOutputStream output = new ByteArrayOutputStream(); @@ -130,33 +120,22 @@ protected boolean runPackageSearch(final String packageOrClassName, final String } // dump args for debugging aid - System.out.println("\nCalling: com.sun.tdk.signaturetest.SignatureTest() with following args:"); + log.fine("\nCalling: com.sun.tdk.signaturetest.SignatureTest() with following args:"); for (int ii = 0; ii < testArguments.length; ii++) { - System.out.println("\t testArguments[" + ii + "] = " + testArguments[ii]); + log.fine("\t testArguments[" + ii + "] = " + testArguments[ii]); } Method runMethod = sigTestClass.getDeclaredMethod("run", - new Class[] { - String[].class, PrintWriter.class, PrintWriter.class - }); - runMethod.invoke(sigTestInstance, new Object[] { - testArguments, new PrintWriter(output, true), null - }); + new Class[] {String[].class, PrintWriter.class, PrintWriter.class}); + runMethod.invoke(sigTestInstance, new Object[] {testArguments, new PrintWriter(output, true), null}); String rawMessages = output.toString(); // currently, there is no way to determine if there are error msgs in // the rawmessages, so we will always dump this and call it a status. - System.out.println("********** Status Report '" + packageOrClassName + "' **********\n"); - System.out.println(rawMessages); + log.info("********** Status Report '" + packageOrClassName + "' **********\n"); + log.info(rawMessages); return sigTestInstance.toString().substring(7).startsWith("Passed."); } - @Override - protected boolean verifyJTAJarForNoXA(final String classpath, final String repositoryDir) throws Exception { - // Need to find out whether implementing this method is really required now. - // By default, signature test framework will use sigtest - return true; - } - } // END ApiCheckDriver diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/ConcurrencySignatureTestRunner.java b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/ConcurrencySignatureTestRunner.java index 5347a33a..ce87c3fc 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/ConcurrencySignatureTestRunner.java +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/ConcurrencySignatureTestRunner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -33,22 +33,21 @@ import java.security.CodeSource; import java.util.ArrayList; import java.util.HashSet; -import java.util.Properties; import java.util.Set; +import java.util.logging.Logger; -import ee.jakarta.tck.concurrent.framework.TestLogger; +import ee.jakarta.tck.concurrent.framework.TestProperty; public class ConcurrencySignatureTestRunner extends SigTestEE { + private Logger log = Logger.getLogger(getClass().getCanonicalName()); + + public static final String SIG_RESOURCE_PACKAGE = "ee.jakarta.tck.concurrent.common.signature"; public static final String SIG_FILE_NAME = "jakarta.enterprise.concurrent.sig"; public static final String SIG_MAP_NAME = "sig-test.map"; public static final String SIG_PKG_NAME = "sig-test-pkg-list.txt"; - - public static final String[] SIG_RESOURCES = { - SIG_FILE_NAME, SIG_MAP_NAME, SIG_PKG_NAME - }; - - private static final TestLogger log = TestLogger.get(ConcurrencySignatureTestRunner.class); + + public static final String[] SIG_RESOURCES = {SIG_FILE_NAME, SIG_MAP_NAME, SIG_PKG_NAME}; public ConcurrencySignatureTestRunner() { setup(); @@ -58,25 +57,29 @@ public ConcurrencySignatureTestRunner() { * Returns a list of strings where each string represents a package name. Each * package name will have it's signature tested by the signature test framework. * + * TODO is there a way to construct this list at runtime? + * Unlikely due to lazy classloading Package.getPackages() will not contain anything + * that hasn't been loaded. + * * @return String[] The names of the packages whose signatures should be * verified. */ @Override - protected String[] getPackages(final String vehicleName) { + protected String[] getPackages() { return new String[] { "jakarta.enterprise.concurrent", "jakarta.enterprise.concurrent.spi" }; - } /** * Returns the classpath for the packages we are interested in. */ protected String getClasspath() { - final String defined = System.getProperty("signature.sigTestClasspath"); + final String defined = TestProperty.signatureClasspath.getValue(); if (defined != null && !defined.isBlank()) { return defined; } + // The Jakarta artifacts we want added to our classpath String[] classes = new String[] { "jakarta.enterprise.concurrent.AbortedException", // For jakarta.enterprise.concurrent-api-3.0.0.jar @@ -85,9 +88,7 @@ protected String getClasspath() { }; // The JDK modules we want added to our classpath - String[] jdkModules = new String[] { - "java.base", "java.rmi", "java.sql", "java.naming" - }; + String[] jdkModules = new String[] {"java.base", "java.rmi", "java.sql", "java.naming"}; // Get Jakarta artifacts from application server Set classPaths = new HashSet(); @@ -112,7 +113,7 @@ protected String getClasspath() { // Get JDK modules from jimage // Add JDK classes to classpath - File jimageOutput = new File(SigTestData.getJImageDir()); + File jimageOutput = TestProperty.signatureImageDir.getFile(); for (String module : jdkModules) { Path modulePath = Paths.get(jimageOutput.getAbsolutePath(), module); if (Files.isDirectory(modulePath)) { @@ -152,7 +153,7 @@ protected File writeStreamToTempFile(final InputStream inputStream, final String protected File writeStreamToSigFile(final InputStream inputStream) throws IOException { FileOutputStream outputStream = null; - String tmpdir = System.getProperty("java.io.tmpdir"); + String tmpdir = TestProperty.javaTempDir.getValue(); try { File sigfile = new File(tmpdir + File.separator + SIG_FILE_NAME); if (sigfile.exists()) { @@ -205,30 +206,30 @@ public void signatureTest() throws Fault { try { InputStream inStreamMapfile = ConcurrencySignatureTestRunner.class.getClassLoader() - .getResourceAsStream("ee/jakarta/tck/concurrent/common/signature/" + SIG_MAP_NAME); + .getResourceAsStream(SIG_RESOURCE_PACKAGE.replace(".", "/") + "/" + SIG_MAP_NAME); File mFile = writeStreamToTempFile(inStreamMapfile, "sig-test", ".map"); mapFile = mFile.getCanonicalPath(); log.info("mapFile location is :" + mapFile); InputStream inStreamPackageFile = ConcurrencySignatureTestRunner.class.getClassLoader() - .getResourceAsStream("ee/jakarta/tck/concurrent/common/signature/" + SIG_PKG_NAME); + .getResourceAsStream(SIG_RESOURCE_PACKAGE.replace(".", "/") + "/" + SIG_PKG_NAME); File pFile = writeStreamToTempFile(inStreamPackageFile, "sig-test-pkg-list", ".txt"); packageListFile = pFile.getCanonicalPath(); log.info("packageFile location is :" + packageListFile); InputStream inStreamSigFile = ConcurrencySignatureTestRunner.class.getClassLoader() - .getResourceAsStream("ee/jakarta/tck/concurrent/common/signature/" + SIG_FILE_NAME); + .getResourceAsStream(SIG_RESOURCE_PACKAGE.replace(".", "/") + "/" + SIG_FILE_NAME); File sigFile = writeStreamToSigFile(inStreamSigFile); log.info("signature File location is :" + sigFile.getCanonicalPath()); - signatureRepositoryDir = System.getProperty("java.io.tmpdir"); + signatureRepositoryDir = TestProperty.javaTempDir.getValue(); } catch (IOException ex) { log.info("Exception while creating temp files :" + ex); } - String[] packagesUnderTest = getPackages(SigTestData.getVehicle()); - String[] classesUnderTest = getClasses(SigTestData.getVehicle()); - String optionalPkgToIgnore = SigTestData.getOptionalTechPackagesToIgnore(); + String[] packagesUnderTest = getPackages(); + String[] classesUnderTest = getClasses(); + String optionalPkgToIgnore = ""; // unlisted optional packages are technology packages for those optional // technologies (e.g. jsr-88) that might not have been specified by the @@ -239,14 +240,13 @@ public void signatureTest() throws Fault { // If testing with Java 9+, extract the JDK's modules so they can be used // on the testcase's classpath. - Properties sysProps = System.getProperties(); - String version = (String) sysProps.get("java.version"); + String version = TestProperty.javaVer.getValue(); if (!version.startsWith("1.")) { - String jimageDir = SigTestData.getJImageDir(); + String jimageDir = TestProperty.signatureImageDir.getValue(); File f = new File(jimageDir); f.mkdirs(); - String javaHome = (String) sysProps.get("java.home"); + String javaHome = TestProperty.javaHome.getValue(); log.info("Executing JImage"); try { @@ -308,7 +308,7 @@ public static void assertProjectSetup() { // Ensure that jimage directory is set. // This is where modules will be converted back to .class files for use in // signature testing - assertNotNull(System.getProperty("jimage.dir"), + assertNotNull(TestProperty.signatureImageDir.getValue(), "The system property jimage.dir must be set in order to run the Signature test."); // Ensure user has the correct security/JDK settings to allow the plugin access diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/PackageList.java b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/PackageList.java index bc047874..3fbff049 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/PackageList.java +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/PackageList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024 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 @@ -32,6 +32,7 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; +import java.util.logging.Logger; /** * This class represents a package list file. A package list file is used in @@ -63,6 +64,8 @@ * trailing period character. */ class PackageList { + + private static final Logger log = Logger.getLogger(PackageList.class.getCanonicalName()); // Any line in the packageFile starting with this character is a comment private static final char COMMENT_CHAR = '#'; @@ -206,16 +209,16 @@ private void removeExistingPackage() { List delPkgs = new ArrayList<>(); // iterate over package set and find package names to remove for (Iterator i = packageNames.iterator(); i.hasNext();) { - packageName = i.next(); + packageName = (String) i.next(); if (packageName.startsWith(delPackage)) { delPkgs.add(packageName); } } // actually remove the package names from the set for (int i = 0; i < delPkgs.size(); i++) { - packageName = delPkgs.get(i); + packageName = (String) (delPkgs.get(i)); packageNames.remove(packageName); - System.out.println("PackageList.removeExistingPackage() \"" + packageName + "\""); + log.info("PackageList.removeExistingPackage() \"" + packageName + "\""); } } @@ -338,10 +341,10 @@ private void writePkgFile() throws Exception { out = new BufferedWriter(new FileWriter(packageFile)); writeHeader(out); for (Iterator i = packageNames.iterator(); i.hasNext();) { - String packageName = i.next(); + String packageName = (String) i.next(); out.write(packageName); out.newLine(); - System.out.println("PackageList.writePkgFile() \"" + packageName + "\""); + log.info("PackageList.writePkgFile() \"" + packageName + "\""); } } finally { if (out != null) { @@ -362,7 +365,7 @@ public String[] getSubPackages(final String pkgName) { List result = new ArrayList<>(); String subPackageName = pkgName + "."; for (Iterator i = packageNames.iterator(); i.hasNext();) { - String packageName = i.next(); + String packageName = (String) i.next(); if (packageName.startsWith(subPackageName)) { result.add(packageName); } @@ -396,16 +399,16 @@ public String getSubPackagesFormatted(final String pkgName) { * Test Driver */ public static void main(final String[] args) throws Exception { - System.out.println("\n\n*** Creating package list file ***\n\n"); + log.info("\n\n*** Creating package list file ***\n\n"); PackageList list = new PackageList("jakarta.ejb", "/home/ryano/cts-tools-master/tools/api-check/test/jakarta.ejb.sig_2.1", "/home/ryano/cts-tools-master/tools/api-check/test/pkg-list.txt"); list.writePkgListFile(); - System.out.println("\n\n*** Reading sub-packages from package list file ***\n\n"); + log.info("\n\n*** Reading sub-packages from package list file ***\n\n"); PackageList readList = new PackageList("/home/ryano/cts-tools-master/tools/api-check/test/pkg-list.txt"); - System.out.println(Arrays.asList(readList.getSubPackages("jakarta.ejb"))); - System.out.println(readList.getSubPackagesFormatted("jakarta.ejb")); + log.info(Arrays.asList(readList.getSubPackages("jakarta.ejb")).toString()); + log.info(readList.getSubPackagesFormatted("jakarta.ejb")); } } // end class PackageList diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/README.md b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/README.md index d704a0cf..52d4f63a 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/README.md +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/README.md @@ -4,7 +4,7 @@ This package is inherited from the Platform-TCK (https://github.com/eclipse-ee4j The latest signature files are updated in the concurrency TCK Repository (concurrency-api//tck/src/main/resources/ee/jakarta/tck/spec/signature) -generated using sigtest-maven-plugin.jar(version 1.6). +generated using sigtest-maven-plugin.jar (version 2.3). The signature tests are run using the sigtest-maven-plugin.jar and the framework available in this folder. @@ -19,7 +19,7 @@ The plugin that generates the signature file has been copied below for reference ```xml - org.netbeans.tools + jakarta.tck sigtest-maven-plugin ${sigtest.version} @@ -32,17 +32,18 @@ The plugin that generates the signature file has been copied below for reference ${project.build.directory}/concurrency-api + ${project.build.directory}/jimage/java.base${project.build.directory}/jimage/java.base jakarta.enterprise.concurrent, jakarta.enterprise.concurrent.spi, false - ${project.build.directory}/jakarta.enterprise.concurrent.sig_${version} + ${project.build.directory}/jakarta.enterprise.concurrent.sig_${java.version} ``` -- The `classes` configuration points to a location where an earlier plugin has unpacked the api jar form which we are generating the signature file. +- The `classes` configuration points to a location where an earlier plugin has unpacked the api jar from which we are generating the signature file. - The `packages` configuration specifies the packages we want to generate signatures from. - The `attach` configuration specifies that we do not want the plugin to use its default file extension - The `sigfile` configurations specifies the signature file we want the plugin to generate @@ -76,10 +77,7 @@ The signature file will be automatically copied to the `/src/main/resource/ee/ja Since the Concurrency TCK can only be run against Jakarta EE Servers we have simplified the running of signature tests. -Signature tests will be automatically run as part of the TCK via the `ee.jakarta.tck.concurrent.spec.signature` project. +Signature tests will be automatically run as part of the TCK via the `ee.jakarta.tck.concurrent.spec.signature` package. -This project will deploy a servlet application to the Jakarta EE Server. -The servlet runs the signature test using the signaturetest framework from the Platform TCK. - -TCK Users will only need to set a single JVM property `-Djimage.dir=`. -This directory will be populated with class files extracted from the JDK modules. \ No newline at end of file +This package will deploy an application to the Jakarta EE Server. +The application runs the signature test using the signaturetest framework from the Platform TCK. diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTest.java b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTest.java index 191aca8f..61bac8ba 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTest.java +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023 Oracle and/or its affiliates and others. + * Copyright (c) 2022, 2024 Oracle and/or its affiliates and others. * All rights reserved. * * This program and the accompanying materials are made available under the @@ -21,9 +21,11 @@ package ee.jakarta.tck.concurrent.common.signature; -import java.io.PrintStream; import java.io.PrintWriter; +import java.io.PrintStream; + import java.util.ArrayList; +import java.util.logging.Logger; /** * This class should be extended by TCK developers that wish to create a set of @@ -32,6 +34,8 @@ * by the signature test framework. */ public abstract class SigTest { + + private static final Logger log = Logger.getLogger(SigTest.class.getCanonicalName()); private SignatureTestDriver driver; @@ -46,6 +50,8 @@ public abstract class SigTest { * {@link SignatureTestDriver} that will use API Check. TCK developers can * override this to return the desired {@link SignatureTestDriver} for their * TCK. + * + * @return Object instance of SignatureTestDriver */ protected SignatureTestDriver getSigTestDriver() { @@ -68,7 +74,7 @@ protected SignatureTestDriver getSigTestDriver() { * @return String The path and name of the package list file. */ protected String getPackageFile() { - return getSigTestDriver().getPackageFileImpl(SigTestData.getBinDir()); + return getSigTestDriver().getPackageFileImpl(); } /** @@ -85,7 +91,7 @@ protected String getPackageFile() { * @return String The path and name of the signature map file. */ protected String getMapFile() { - return getSigTestDriver().getMapFileImpl(SigTestData.getBinDir()); + return getSigTestDriver().getMapFileImpl(); } /** @@ -98,10 +104,11 @@ protected String getMapFile() { * @return String The signature repository directory. */ protected String getRepositoryDir() { - return getSigTestDriver().getRepositoryDirImpl(SigTestData.getTSHome()); + return getSigTestDriver().getRepositoryDirImpl(); } /** + *

* Returns the list of Optional Packages which are not accounted for. By * 'unlisted optional' we mean the packages which are Optional to the technology * under test that the user did NOT specifically list for testing. For example, @@ -110,21 +117,28 @@ protected String getRepositoryDir() { * list this optional technology for testing (via ts.jte javaee.level prop) then * this method will return the packages for JSR-88 technology with this method * call. - *

+ *

+ * + *

* This is useful for checking for a scenarios when a user may have forgotten to * identify a whole or partial technology implementation and in such cases, Java * EE platform still requires testing it. - *

+ *

+ * + *

* Any partial or complete impl of an unlistedOptionalPackage sends up a red * flag indicating that the user must also pass tests for this optional * technology area. - *

+ *

+ * + *

* Sub-classes are free to override this method if they use a different * signature repository directory. Most users should be able to use this default * implementation - which means that there was NO optional technology packages * that need to be tested. + *

* - * @return ArrayList + * @return List of unlisted packages */ protected ArrayList getUnlistedOptionalPackages() { return null; @@ -159,16 +173,13 @@ protected String[] getClasses() { * Called by the test framework to initialize this test. The method simply * retrieves some state information that is necessary to run the test when when * the test framework invokes the run method (actually the test1 method). - * - * @throws Fault When an error occurs reading or saving the state information - * processed by this method. */ public void setup() { try { - System.out.println("$$$ SigTest.setup() called"); - System.out.println("$$$ SigTest.setup() complete"); + log.info("$$$ SigTest.setup() called"); + log.info("$$$ SigTest.setup() complete"); } catch (Exception e) { - System.out.println("Unexpected exception " + e.getMessage()); + log.info("Unexpected exception " + e.getMessage()); // throw new Fault("setup failed!", e); } } @@ -181,10 +192,10 @@ public void setup() { * @throws Fault When an error occurs cleaning up the state of this test. */ public void cleanup() throws Fault { - System.out.println("$$$ SigTest.cleanup() called"); + log.info("$$$ SigTest.cleanup() called"); try { getSigTestDriver().cleanupImpl(); - System.out.println("$$$ SigTest.cleanup() returning"); + log.info("$$$ SigTest.cleanup() returning"); } catch (Exception e) { throw new Fault("Cleanup failed!", e); } @@ -197,10 +208,11 @@ public static class Fault extends Exception { /** * creates a Fault with a message + * @param msg - Error message */ public Fault(final String msg) { super(msg); - System.out.println(msg); + log.info(msg); } /** @@ -212,7 +224,7 @@ public Fault(final String msg) { public Fault(final String msg, final Throwable t) { super(msg); this.t = t; - // System.out.println(msg, t); + // log.info(msg, t); } /** @@ -227,7 +239,6 @@ public Fault(final Throwable t) { /** * Prints this Throwable and its backtrace to the standard error stream. - * */ public void printStackTrace() { if (this.t != null) { @@ -293,6 +304,7 @@ public static class SetupException extends Exception { /** * creates a Fault with a message + * @param msg - The error message */ public SetupException(final String msg) { super(msg); diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestData.java b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestData.java deleted file mode 100644 index f386aa3b..00000000 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestData.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 - */ - -/* - * $Id$ - */ - -package ee.jakarta.tck.concurrent.common.signature; - -import java.util.Properties; - -/** - * This class holds the data passed to a signature test invocation during the - * setup phase. This allows us to keep the passed data separate and reuse the - * data between the signature test framework base classes. - */ -public final class SigTestData { - - private SigTestData() { - // Helper class - } - - private static Properties props = System.getProperties(); - - public static String getVehicle() { - return props.getProperty("vehicle", ""); - } - - public static String getBinDir() { - return props.getProperty("bin.dir", ""); - } - - public static String getTSHome() { - return props.getProperty("ts_home", ""); - } - - public static String getTestClasspath() { - return props.getProperty("sigTestClasspath", ""); - } - - public static String getJavaeeLevel() { - return props.getProperty("javaee.level", ""); - } - - public static String getCurrentKeywords() { - return props.getProperty("current.keywords", ""); - } - - public static String getProperty(final String prop) { - return props.getProperty(prop); - } - - public static String getOptionalTechPackagesToIgnore() { - return props.getProperty("optional.tech.packages.to.ignore", ""); - } - - public static String getJtaJarClasspath() { - return props.getProperty("jtaJarClasspath", ""); - } - - public static String getJImageDir() { - return props.getProperty("jimage.dir", ""); - } -} // end class SigTestData diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestDriver.java b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestDriver.java index 2ba84537..3a72b1c4 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestDriver.java +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024 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 @@ -22,6 +22,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.logging.Logger; /** *

@@ -29,6 +30,8 @@ *

*/ public class SigTestDriver extends SignatureTestDriver { + + private static final Logger log = Logger.getLogger(SigTestDriver.class.getCanonicalName()); private static final String CLASSPATH_FLAG = "-Classpath"; @@ -58,14 +61,6 @@ public class SigTestDriver extends SignatureTestDriver { private static final String EXCLUDE_JDK_CLASS_FLAG = "-IgnoreJDKClass"; - private static String[] excludeJdkClasses = { - "java.util.Map", "java.lang.Object", "java.io.ByteArrayInputStream", - "java.io.InputStream", "java.lang.Deprecated", "java.io.Writer", "java.io.OutputStream", "java.util.List", - "java.util.Collection", "java.lang.instrument.IllegalClassFormatException", - "javax.transaction.xa.XAException", "java.lang.annotation.Repeatable", "java.lang.InterruptedException", - "java.lang.CloneNotSupportedException", "java.lang.Throwable", "java.lang.Thread", "java.lang.Enum" - }; - // ---------------------------------------- Methods from SignatureTestDriver @Override @@ -94,7 +89,7 @@ protected String[] createTestArguments(final String packageListFile, final Strin if (bStaticMode) { // static mode allows finer level of constants checking // -CheckValue says to check the actual const values - System.out.println("Setting static mode flag to allow constant checking."); + log.info("Setting static mode flag to allow constant checking."); command.add(STATIC_FLAG); command.add(CHECKVALUE_FLAG); @@ -104,8 +99,9 @@ protected String[] createTestArguments(final String packageListFile, final Strin command.add(SMODE_FLAG); // command.add("bin"); command.add("src"); + command.add("-BootCp"); } else { - System.out.println("Not Setting static mode flag to allow constant checking."); + log.info("Not Setting static mode flag to allow constant checking."); } command.add("-Verbose"); @@ -123,11 +119,8 @@ protected String[] createTestArguments(final String packageListFile, final Strin command.add(EXCLUDE_FLAG); command.add(subPackages[i]); } - - for (String jdkClassName : excludeJdkClasses) { - command.add(EXCLUDE_JDK_CLASS_FLAG); - command.add(jdkClassName); - } + + command.add(EXCLUDE_JDK_CLASS_FLAG); command.add(API_VERSION_FLAG); command.add(info.getVersion()); @@ -145,25 +138,21 @@ protected boolean runSignatureTest(final String packageOrClassName, final String ByteArrayOutputStream output = new ByteArrayOutputStream(); // do some logging to help with troubleshooting - System.out.println("\nCalling: com.sun.tdk.signaturetest.SignatureTest() with following args:"); + log.fine("\nCalling: com.sun.tdk.signaturetest.SignatureTest() with following args:"); for (int ii = 0; ii < testArguments.length; ii++) { - System.out.println(" testArguments[" + ii + "] = " + testArguments[ii]); + log.fine(" testArguments[" + ii + "] = " + testArguments[ii]); } Method runMethod = sigTestClass.getDeclaredMethod("run", - new Class[] { - String[].class, PrintWriter.class, PrintWriter.class - }); - runMethod.invoke(sigTestInstance, new Object[] { - testArguments, new PrintWriter(output, true), null - }); + new Class[] {String[].class, PrintWriter.class, PrintWriter.class}); + runMethod.invoke(sigTestInstance, new Object[] {testArguments, new PrintWriter(output, true), null}); String rawMessages = output.toString(); // currently, there is no way to determine if there are error msgs in // the rawmessages, so we will always dump this and call it a status. - System.out.println("********** Status Report '" + packageOrClassName + "' **********\n"); - System.out.println(rawMessages); + log.info("********** Status Report '" + packageOrClassName + "' **********\n"); + log.info(rawMessages); return sigTestInstance.toString().substring(7).startsWith("Passed."); } // END runSignatureTest @@ -176,7 +165,7 @@ testArguments, new PrintWriter(output, true), null protected boolean runPackageSearch(final String packageOrClassName, final String[] testArguments) throws Exception { Class sigTestClass = Class.forName("com.sun.tdk.signaturetest.SignatureTest"); - Object sigTestInstance = sigTestClass.getConstructor().newInstance(); + Object sigTestInstance = sigTestClass.getDeclaredConstructor().newInstance(); ByteArrayOutputStream output = new ByteArrayOutputStream(); @@ -188,72 +177,22 @@ protected boolean runPackageSearch(final String packageOrClassName, final String } // dump args for debugging aid - System.out.println("\nCalling: com.sun.tdk.signaturetest.SignatureTest() with following args:"); + log.fine("\nCalling: com.sun.tdk.signaturetest.SignatureTest() with following args:"); for (int ii = 0; ii < testArguments.length; ii++) { - System.out.println("\t testArguments[" + ii + "] = " + testArguments[ii]); + log.fine("\t testArguments[" + ii + "] = " + testArguments[ii]); } Method runMethod = sigTestClass.getDeclaredMethod("run", - new Class[] { - String[].class, PrintWriter.class, PrintWriter.class - }); - runMethod.invoke(sigTestInstance, new Object[] { - testArguments, new PrintWriter(output, true), null - }); + new Class[] {String[].class, PrintWriter.class, PrintWriter.class}); + runMethod.invoke(sigTestInstance, new Object[] {testArguments, new PrintWriter(output, true), null}); String rawMessages = output.toString(); // currently, there is no way to determine if there are error msgs in // the rawmessages, so we will always dump this and call it a status. - System.out.println("********** Status Report '" + packageOrClassName + "' **********\n"); - System.out.println(rawMessages); - - return sigTestInstance.toString().substring(7).startsWith("Passed."); - } - - /* - * @return This returns true if javax.transaction.xa is not found in the JTA API - * jar - */ - protected boolean verifyJTAJarForNoXA(final String classpath, final String repositoryDir) throws Exception { - - System.out.println("SigTestDriver#verifyJTAJarForNoXA - Starting:"); - List command = new ArrayList<>(); + log.info("********** Status Report '" + packageOrClassName + "' **********\n"); + log.info(rawMessages); - // Build Commandline for com.sun.tdk.signaturetest.SignatureTest - command.add(STATIC_FLAG); - command.add(FILENAME_FLAG); - command.add(repositoryDir + "empty.sig"); - command.add(PACKAGE_FLAG); - command.add("javax.transaction.xa"); - command.add(CLASSPATH_FLAG); - command.add(classpath); - - String[] testArguments = (String[]) command.toArray(new String[command.size()]); - - // do some logging to help with troubleshooting - System.out.println("\nCalling: com.sun.tdk.signaturetest.SignatureTest() with following args:"); - for (int ii = 0; ii < testArguments.length; ii++) { - System.out.println(" testArguments[" + ii + "] = " + testArguments[ii]); - } - - Class sigTestClass = Class.forName("com.sun.tdk.signaturetest.SignatureTest"); - Object sigTestInstance = sigTestClass.getConstructor().newInstance(); - ByteArrayOutputStream output = new ByteArrayOutputStream(); - - Method runMethod = sigTestClass.getDeclaredMethod("run", - new Class[] { - String[].class, PrintWriter.class, PrintWriter.class - }); - runMethod.invoke(sigTestInstance, new Object[] { - testArguments, new PrintWriter(output, true), null - }); - String rawMessages = output.toString(); - - // currently, there is no way to determine if there are error msgs in - // the rawmessages, so we will always dump this and call it a status. - System.out.println("********** Status Report JTA JAR validation **********\n"); - System.out.println(rawMessages); return sigTestInstance.toString().substring(7).startsWith("Passed."); } } diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestEE.java b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestEE.java index bc01aee9..7a4a0386 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestEE.java +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestEE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024 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 @@ -13,16 +13,18 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 */ - package ee.jakarta.tck.concurrent.common.signature; import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; -import java.io.PrintStream; import java.io.PrintWriter; +import java.io.PrintStream; + import java.util.ArrayList; -import java.util.Properties; +import java.util.logging.Logger; + +import ee.jakarta.tck.concurrent.framework.TestProperty; /** * This class should be extended by TCK developers that wish to create a set of @@ -31,6 +33,8 @@ * by the signature test framework within which container. */ public abstract class SigTestEE { + + private static final Logger log = Logger.getLogger(SigTestEE.class.getCanonicalName()); private SignatureTestDriver driver; @@ -45,6 +49,8 @@ public abstract class SigTestEE { * {@link SignatureTestDriver} that will use API Check. TCK developers can * override this to return the desired {@link SignatureTestDriver} for their * TCK. + * + * @return Instance of SignatureTestDriver */ protected SignatureTestDriver getSigTestDriver() { @@ -57,9 +63,11 @@ protected SignatureTestDriver getSigTestDriver() { } // END getSigTestDriver /** + *

* Returns the location of the package list file. This file denotes the valid * sub-packages of any package being verified in the signature tests. - *

+ *

+ * * Sub-classes are free to override this method if they use a different path or * filename for their package list file. Most users should be able to use this * default implementation. @@ -67,16 +75,18 @@ protected SignatureTestDriver getSigTestDriver() { * @return String The path and name of the package list file. */ protected String getPackageFile() { - return getSigTestDriver().getPackageFileImpl(SigTestData.getBinDir()); + return getSigTestDriver().getPackageFileImpl(); } /** + *

* Returns the path and name of the signature map file that this TCK uses when * conducting signature tests. The signature map file tells the signature test * framework which API versions of tested packages to use. To keep this code * platform independent, be sure to use the File.separator string (or the * File.separatorChar) to denote path separators. - *

+ *

+ * * Sub-classes are free to override this method if they use a different path or * filename for their signature map file. Most users should be able to use this * default implementation. @@ -84,12 +94,14 @@ protected String getPackageFile() { * @return String The path and name of the signature map file. */ protected String getMapFile() { - return getSigTestDriver().getMapFileImpl(SigTestData.getBinDir()); + return getSigTestDriver().getMapFileImpl(); } /** + *

* Returns the directory that contains the signature files. - *

+ *

+ * * Sub-classes are free to override this method if they use a different * signature repository directory. Most users should be able to use this default * implementation. @@ -97,10 +109,11 @@ protected String getMapFile() { * @return String The signature repository directory. */ protected String getRepositoryDir() { - return getSigTestDriver().getRepositoryDirImpl(SigTestData.getTSHome()); + return getSigTestDriver().getRepositoryDirImpl(); } /** + *

* Returns the list of Optional Packages which are not accounted for. By * 'unlisted optional' we mean the packages which are Optional to the technology * under test that the user did NOT specifically list for testing. For example, @@ -109,21 +122,26 @@ protected String getRepositoryDir() { * list this optional technology for testing (via ts.jte javaee.level prop) then * this method will return the packages for JSR-88 technology with this method * call. - *

+ *

+ * + *

* This is useful for checking for a scenarios when a user may have forgotten to * identify a whole or partial technology implementation and in such cases, Java * EE platform still requires testing it. - *

+ *

+ * + *

* Any partial or complete impl of an unlistedOptionalPackage sends up a red * flag indicating that the user must also pass tests for this optional * technology area. - *

+ *

+ * * Sub-classes are free to override this method if they use a different * signature repository directory. Most users should be able to use this default * implementation - which means that there was NO optional technology packages * that need to be tested. * - * @return ArrayList + * @return List of unlisted packages */ protected ArrayList getUnlistedOptionalPackages() { return null; @@ -134,10 +152,6 @@ protected ArrayList getUnlistedOptionalPackages() { * framework. TCK developers must implement this method in their signature test * sub-class. * - * @param vehicleName The name of the vehicle the signature tests should be - * conducted in. Valid values for this property are ejb, - * servlet, ejb and appclient. - * * @return String[] A list of packages that the developer wishes to test using * the signature test framework. If the developer does not wish to test * any package signatures in the specified vehicle this method should @@ -152,7 +166,7 @@ protected ArrayList getUnlistedOptionalPackages() { * the specified vehicle has no package signatures to be verified within * it. */ - protected abstract String[] getPackages(final String vehicleName); + protected abstract String[] getPackages(); /** *

@@ -167,19 +181,13 @@ protected ArrayList getUnlistedOptionalPackages() { * vehicle, the implementation of this method must return a zero-length array. *

* - * @param vehicleName The name of the vehicle the signature tests should be - * conducted in. Valid values for this property are ejb, - * servlet, ejb and appclient. - * * @return an Array of Strings containing the individual classes the framework * should test based on the specifed vehicle. The default implementation * of this method returns a zero-length array no matter the vehicle * specified. */ - protected String[] getClasses(final String vehicleName) { - + protected String[] getClasses() { return new String[] {}; - } // END getClasses /** @@ -189,10 +197,10 @@ protected String[] getClasses(final String vehicleName) { */ public void setup() { try { - System.out.println("$$$ SigTestEE.setup() called"); - System.out.println("$$$ SigTestEE.setup() complete"); + log.info("$$$ SigTestEE.setup() called"); + log.info("$$$ SigTestEE.setup() complete"); } catch (Exception e) { - System.out.println("Unexpected exception " + e.getMessage()); + log.info("Unexpected exception " + e.getMessage()); } } @@ -205,15 +213,15 @@ public void setup() { * @throws Fault When an error occurs executing the signature tests. */ public void signatureTest() throws Fault { - System.out.println("$$$ SigTestEE.signatureTest() called"); + log.info("$$$ SigTestEE.signatureTest() called"); SigTestResult results = null; String mapFile = getMapFile(); String repositoryDir = getRepositoryDir(); - String[] packages = getPackages(SigTestData.getVehicle()); - String[] classes = getClasses(SigTestData.getVehicle()); + String[] packages = getPackages(); + String[] classes = getClasses(); String packageFile = getPackageFile(); - String testClasspath = SigTestData.getTestClasspath(); - String optionalPkgToIgnore = SigTestData.getOptionalTechPackagesToIgnore(); + String testClasspath = TestProperty.signatureClasspath.getValue(); + String optionalPkgToIgnore = ""; // unlisted optional packages are technology packages for those optional // technologies (e.g. jsr-88) that might not have been specified by the @@ -224,15 +232,14 @@ public void signatureTest() throws Fault { // If testing with Java 9+, extract the JDK's modules so they can be used // on the testcase's classpath. - Properties sysProps = System.getProperties(); - String version = (String) sysProps.get("java.version"); + String version = TestProperty.javaVer.getValue(); if (!version.startsWith("1.")) { - String jimageDir = SigTestData.getJImageDir(); + String jimageDir = TestProperty.signatureImageDir.getValue(); File f = new File(jimageDir); f.mkdirs(); - String javaHome = (String) sysProps.get("java.home"); - System.out.println("Executing JImage"); + String javaHome = TestProperty.javaHome.getValue(); + log.info("Executing JImage"); try { ProcessBuilder pb = new ProcessBuilder(javaHome + "/bin/jimage", "extract", "--dir=" + jimageDir, @@ -244,14 +251,14 @@ public void signatureTest() throws Fault { BufferedReader out = new BufferedReader(new InputStreamReader(proc.getInputStream())); String line = null; while ((line = out.readLine()) != null) { - System.out.println(line); + log.info(line); } int rc = proc.waitFor(); - System.out.println("JImage RC = " + rc); + log.info("JImage RC = " + rc); out.close(); } catch (Exception e) { - System.out.println("Exception while executing JImage! Some tests may fail."); + log.info("Exception while executing JImage! Some tests may fail."); e.printStackTrace(); } } @@ -259,18 +266,18 @@ public void signatureTest() throws Fault { try { results = getSigTestDriver().executeSigTest(packageFile, mapFile, repositoryDir, packages, classes, testClasspath, unlistedTechnologyPkgs, optionalPkgToIgnore); - System.out.println(results.toString()); + log.info(results.toString()); if (!results.passed()) { - System.out.println("results.passed() returned false"); + log.info("results.passed() returned false"); throw new Exception(); } - System.out.println("$$$ SigTestEE.signatureTest() returning"); + log.info("$$$ SigTestEE.signatureTest() returning"); } catch (Exception e) { if (results != null && !results.passed()) { throw new Fault("SigTestEE.signatureTest() failed!, diffs found"); } else { - System.out.println("Unexpected exception " + e.getMessage()); + log.info("Unexpected exception " + e.getMessage()); throw new Fault("signatureTest failed with an unexpected exception", e); } } @@ -284,10 +291,10 @@ public void signatureTest() throws Fault { * @throws Fault When an error occurs cleaning up the state of this test. */ public void cleanup() throws Fault { - System.out.println("$$$ SigTestEE.cleanup() called"); + log.info("$$$ SigTestEE.cleanup() called"); try { getSigTestDriver().cleanupImpl(); - System.out.println("$$$ SigTestEE.cleanup() returning"); + log.info("$$$ SigTestEE.cleanup() returning"); } catch (Exception e) { throw new Fault("Cleanup failed!", e); } @@ -300,10 +307,11 @@ public static class Fault extends Exception { /** * creates a Fault with a message + * @param msg - error message */ public Fault(final String msg) { super(msg); - System.out.println(msg); + log.info(msg); } /** @@ -315,7 +323,7 @@ public Fault(final String msg) { public Fault(final String msg, final Throwable t) { super(msg); this.t = t; - System.out.println(msg); + log.info(msg); t.printStackTrace(); } diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestResult.java b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestResult.java index 0de4d418..0ef6e50d 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestResult.java +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SigTestResult.java @@ -112,7 +112,7 @@ private synchronized void formatList(final List list, final StringBuffer synchronized (this) { for (int i = 0; i < list.size(); i++) { - String pkg = list.get(i); + String pkg = (String) (list.get(i)); buf.append("\t\t").append(pkg).append(NL); } } diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SignatureTestDriver.java b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SignatureTestDriver.java index 1474fb8c..42e1c4d2 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SignatureTestDriver.java +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/common/signature/SignatureTestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates and others. + * Copyright (c) 2022, 2024 Oracle and/or its affiliates and others. * All rights reserved. * * This program and the accompanying materials are made available under the @@ -24,12 +24,17 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.Properties; +import java.util.logging.Logger; + +import ee.jakarta.tck.concurrent.framework.TestProperty; /** * Allows the sigtest framework to be extended using different signature test * implementations (e.g. ApiCheck, or SigTest) */ public abstract class SignatureTestDriver { + + private static final Logger log = Logger.getLogger(SignatureTestDriver.class.getCanonicalName()); private static final String SIG_FILE_EXT = ".sig"; @@ -38,26 +43,28 @@ public abstract class SignatureTestDriver { /** * Implementation of the getPackageFile method defined in both the SigTest and * SigTestEE class. + * + * @return - Return the signature package file location */ - public String getPackageFileImpl(final String binDir) { + public String getPackageFileImpl() { String thePkgListFile = "sig-test-pkg-list.txt"; - System.out.println("Using the following as the SigTest Package file: " + thePkgListFile); + log.info("Using the following as the SigTest Package file: " + thePkgListFile); - String theFile = binDir + File.separator + thePkgListFile; + String theFile = thePkgListFile; File ff = new File(theFile); if (!ff.exists()) { // we could not find the map file that coresponded to our SE version so // lets // try to default to use the sig-test-pkg-list.txt - System.out.println("The SigTest Package file does not exist: " + thePkgListFile); - theFile = binDir + File.separator + "sig-test-pkg-list.txt"; + log.info("The SigTest Package file does not exist: " + thePkgListFile); + theFile = "sig-test-pkg-list.txt"; File ff2 = new File(theFile); if (!ff2.exists()) { - System.out.println("The Default SigTest Package file does not exist either: " + theFile); + log.info("The Default SigTest Package file does not exist either: " + theFile); } else { - System.out.println("Defaulting to using SigTest Package file: " + theFile); + log.info("Defaulting to using SigTest Package file: " + theFile); } } @@ -68,26 +75,28 @@ public String getPackageFileImpl(final String binDir) { /** * Implementation of the getMapFile method defined in both the SigTest and * SigTestEE class. + * + * @return - Return the signature map file location */ - public String getMapFileImpl(final String binDir) { + public String getMapFileImpl() { String theMapFile = "sig-test.map"; - System.out.println("Using the following as the sig-Test map file: " + theMapFile); + log.info("Using the following as the sig-Test map file: " + theMapFile); - String theFile = binDir + File.separator + theMapFile; + String theFile = theMapFile; File ff = new File(theFile); if (!ff.exists()) { // we could not find the map file that coresponded to our SE version so // lets // try to default to use the sig-test.map - System.out.println("The SigTest Map file does not exist: " + theMapFile); - theFile = binDir + File.separator + "sig-test.map"; + log.info("The SigTest Map file does not exist: " + theMapFile); + theFile = "sig-test.map"; File ff2 = new File(theFile); if (!ff2.exists()) { - System.out.println("The SigTest Map file does not exist either: " + theFile); + log.info("The SigTest Map file does not exist either: " + theFile); } else { - System.out.println("Defaulting to using SigTest Map file: " + theFile); + log.info("Defaulting to using SigTest Map file: " + theFile); } } @@ -96,22 +105,25 @@ public String getMapFileImpl(final String binDir) { } // END getMapFileImpl /** - * Returns true if the passed in version matches the current Java version being - * used. + * Check java SE version * + * @param ver - The Java SE version + * @return - true if the passed in version matches the current Java version being used, false otherwise. */ public Boolean isJavaSEVersion(final String ver) { - String strOSVersion = System.getProperty("java.version"); + String strOSVersion = TestProperty.javaVer.getValue(); return strOSVersion.startsWith(ver); } /** * Implementation of the getRepositoryDir method defined in both the SigTest and * SigTestEE class. + * + * @return - Return the signature repo location */ - public String getRepositoryDirImpl(final String tsHome) { + public String getRepositoryDirImpl() { - return (tsHome + File.separator + "src" + File.separator + "com" + File.separator + "sun" + File.separator + return ("src" + File.separator + "com" + File.separator + "sun" + File.separator + "ts" + File.separator + "tests" + File.separator + "signaturetest" + File.separator + "signature-repository" + File.separator); @@ -120,13 +132,15 @@ public String getRepositoryDirImpl(final String tsHome) { /** * Implementation of the cleanup method defined in both the SigTest and * SigTestEE class. + * + * @throws Exception - If we are unable to cleanup */ public void cleanupImpl() throws Exception { try { - System.out.println("cleanup"); + log.info("cleanup"); } catch (Exception e) { - System.out.println("Exception in cleanup method" + e); + log.info("Exception in cleanup method" + e); throw e; } @@ -158,8 +172,11 @@ public void cleanupImpl() throws Exception { * since they were not explicitly declared as * being under test. Their existence requires * explicit testing. + * @param optionalPkgToIgnore Optional list of packages to ignore * * @return a {@link SigTestResult} containing the result of the test execution + * @throws Exception if execution fails + * */ public SigTestResult executeSigTest(final String packageListFile, final String mapFile, final String signatureRepositoryDir, final String[] packagesUnderTest, final String[] classesUnderTest, @@ -168,38 +185,38 @@ public SigTestResult executeSigTest(final String packageListFile, final String m SigTestResult result = new SigTestResult(); - System.out.println("optionalPkgToIgnore = " + optionalPkgToIgnore); + log.info("optionalPkgToIgnore = " + optionalPkgToIgnore); String[] arrayOptionalPkgsToIgnore = null; if (optionalPkgToIgnore != null) { arrayOptionalPkgsToIgnore = optionalPkgToIgnore.split(","); } if (packagesUnderTest != null && packagesUnderTest.length > 0) { - System.out.println("********** BEGIN PACKAGE LEVEL SIGNATURE " + "VALIDATION **********\n\n"); + log.info("********** BEGIN PACKAGE LEVEL SIGNATURE " + "VALIDATION **********\n\n"); for (int i = 0; i < packagesUnderTest.length; i++) { String packageName = packagesUnderTest[i]; - System.out.println("********** BEGIN VALIDATE PACKAGE '" + packagesUnderTest[i] + "' **********\n"); + log.info("********** BEGIN VALIDATE PACKAGE '" + packagesUnderTest[i] + "' **********\n"); - System.out.println("********** VALIDATE IN STATIC MODE - TO CHECK CONSANT VALUES ****"); - System.out.println("Static mode supports checks of static constants values "); + log.info("********** VALIDATE IN STATIC MODE - TO CHECK CONSANT VALUES ****"); + log.info("Static mode supports checks of static constants values "); String[] args = createTestArguments(packageListFile, mapFile, signatureRepositoryDir, packageName, classpath, true); dumpTestArguments(args); if (runSignatureTest(packageName, args)) { - System.out.println("********** Package '" + packageName + "' - PASSED (STATIC MODE) **********"); + log.info("********** Package '" + packageName + "' - PASSED (STATIC MODE) **********"); result.addPassedPkg(packageName + "(static mode)"); } else { result.addFailedPkg(packageName + "(static mode)"); - System.out.println("********** Package '" + packageName + "' - FAILED (STATIC MODE) **********"); + log.info("********** Package '" + packageName + "' - FAILED (STATIC MODE) **********"); } - System.out.println("\n\n"); - System.out.println("********** VALIDATE IN REFLECTIVE MODE ****"); - System.out.println("Reflective mode supports verification within containers (ie ejb, servlet, etc)"); + log.info("\n\n"); + log.info("********** VALIDATE IN REFLECTIVE MODE ****"); + log.info("Reflective mode supports verification within containers (ie ejb, servlet, etc)"); String[] args2 = createTestArguments(packageListFile, mapFile, signatureRepositoryDir, packageName, classpath, false); @@ -215,59 +232,51 @@ public SigTestResult executeSigTest(final String packageListFile, final String m .println("********** Package '" + packageName + "' - FAILED (REFLECTION MODE) **********"); } - System.out.println("********** END VALIDATE PACKAGE '" + packagesUnderTest[i] + "' **********\n"); - - System.out.println("\n"); - System.out.println("\n"); - + log.info("********** END VALIDATE PACKAGE '" + packagesUnderTest[i] + "' **********\n"); } } if (classesUnderTest != null && classesUnderTest.length > 0) { - System.out.println("********** BEGIN CLASS LEVEL SIGNATURE " + "VALIDATION **********\n\n"); + log.info("********** BEGIN CLASS LEVEL SIGNATURE " + "VALIDATION **********\n\n"); for (int i = 0; i < classesUnderTest.length; i++) { String className = classesUnderTest[i]; - System.out.println("********** BEGIN VALIDATE CLASS '" + classesUnderTest[i] + "' **********\n"); + log.info("********** BEGIN VALIDATE CLASS '" + classesUnderTest[i] + "' **********\n"); - System.out.println("********** VALIDATE IN STATIC MODE - TO CHECK CONSANT VALUES ****"); - System.out.println("Static mode supports checks of static constants values "); + log.info("********** VALIDATE IN STATIC MODE - TO CHECK CONSANT VALUES ****"); + log.info("Static mode supports checks of static constants values "); String[] args = createTestArguments(packageListFile, mapFile, signatureRepositoryDir, className, classpath, true); dumpTestArguments(args); if (runSignatureTest(className, args)) { - System.out.println("********** Class '" + className + "' - PASSED (STATIC MODE) **********"); + log.info("********** Class '" + className + "' - PASSED (STATIC MODE) **********"); result.addPassedClass(className + "(static mode)"); } else { - System.out.println("********** Class '" + className + "' - FAILED (STATIC MODE) **********"); + log.info("********** Class '" + className + "' - FAILED (STATIC MODE) **********"); result.addFailedClass(className + "(static mode)"); } - System.out.println("\n\n"); - System.out.println("********** VALIDATE IN REFLECTIVE MODE ****"); - System.out.println("Reflective mode supports verification within containers (ie ejb, servlet, etc)"); + log.info("\n\n"); + log.info("********** VALIDATE IN REFLECTIVE MODE ****"); + log.info("Reflective mode supports verification within containers (ie ejb, servlet, etc)"); String[] args2 = createTestArguments(packageListFile, mapFile, signatureRepositoryDir, className, classpath, false); dumpTestArguments(args2); if (runSignatureTest(className, args2)) { - System.out.println("********** Class '" + className + "' - PASSED (REFLECTION MODE) **********"); + log.info("********** Class '" + className + "' - PASSED (REFLECTION MODE) **********"); result.addPassedClass(className + "(reflection mode)"); } else { - System.out.println("********** Class '" + className + "' - FAILED (REFLECTION MODE) **********"); + log.info("********** Class '" + className + "' - FAILED (REFLECTION MODE) **********"); result.addFailedClass(className + "(reflection mode)"); } - System.out.println("********** END VALIDATE CLASS '" + classesUnderTest[i] + "' **********\n"); - - System.out.println("\n"); - System.out.println("\n"); - + log.info("********** END VALIDATE CLASS '" + classesUnderTest[i] + "' **********\n"); } } @@ -296,13 +305,13 @@ public SigTestResult executeSigTest(final String packageListFile, final String m // requires us to add special handling to avoid testing 'certain' pkgs // within an optional technology. if (isIgnorePackageUnderTest(packageName, arrayOptionalPkgsToIgnore)) { - System.out.println("Ignoring special optional technology package: " + packageName); + log.info("Ignoring special optional technology package: " + packageName); continue; } - System.out.println("\n\n"); - System.out.println("********** CHECK IF OPTIONAL TECHNOLOGIES EXIST IN REFLECTIVE MODE ****"); - System.out.println("Reflective mode supports verification within containers (ie ejb, servlet, etc)"); + log.info("\n\n"); + log.info("********** CHECK IF OPTIONAL TECHNOLOGIES EXIST IN REFLECTIVE MODE ****"); + log.info("Reflective mode supports verification within containers (ie ejb, servlet, etc)"); String[] args3 = createTestArguments(packageListFile, mapFile, signatureRepositoryDir, packageName, classpath, false); @@ -322,7 +331,7 @@ public SigTestResult executeSigTest(final String packageListFile, final String m if (runPackageSearch(packageName, args3)) { // if this passed we have an issue because it should not exist - thus // should NOT pass. - System.out.println("********** Package '" + packageName + log.info("********** Package '" + packageName + "' - WAS FOUND BUT SHOULD NOT BE (REFLECTION MODE) **********"); String err = "ERROR: An area of concern has been identified. "; err += "You must run sigtests with (ts.jte) javaee.level set to "; @@ -332,11 +341,11 @@ public SigTestResult executeSigTest(final String packageListFile, final String m err += "all related TCK tests. To properly pass the "; err += "signature tests - you must identify all Optional Technology "; err += "areas (via javaee.level) that you wish to pass signature tests for."; - System.out.println(err); + log.info(err); result.addFailedPkg( packageName + " (Undeclared Optional Technology package found in reflection mode)"); } else { - System.out.println("********** Undeclared Optional Technology package '" + packageName + log.info("********** Undeclared Optional Technology package '" + packageName + "' - PASSED (REFLECTION MODE) **********"); } } @@ -363,6 +372,9 @@ public SigTestResult executeSigTest(final String packageListFile, final String m * null. In some rare cases the tested API may * not be part of the test environment and will * have to specified using this parameter. + * @param bStaticMode Boolean if we shold run in static mode or not + * @return A string array of test arguments + * @throws Exception if we are unable to create test arguments */ protected abstract String[] createTestArguments(final String packageListFile, final String mapFile, final String signatureRepositoryDir, final String packageOrClassUnderTest, final String classpath, @@ -376,7 +388,9 @@ protected abstract String[] createTestArguments(final String packageListFile, fi * @param testArguments the arguments necessary to invoke the signature * test framework * - * @return true if the test passed, otherwise false + * @return {@code true} if the test passed, otherwise {@code false} + * + * @throws Exception if we fail to run signature tests */ protected abstract boolean runSignatureTest(final String packageOrClassName, final String[] testArguments) throws Exception; @@ -385,24 +399,13 @@ protected abstract boolean runSignatureTest(final String packageOrClassName, fin * This checks if a class exists or not within the impl. * * @param packageOrClassName the package or class to be validated + * @param testArguments array of test arguments * - * @return true if the package was found to exist, otherwise - * false + * @return {@code true} if the package was found to exist, otherwise + * {@code false} + * @throws Exception - If we cannot find packages */ - protected abstract boolean runPackageSearch(final String packageOrClassName, final String[] testArguments) - throws Exception; - - /** - * This method checks whether JTA API jar contains classes from - * javax.transaction.xa package - * - * @param classpath the classpath, pointing JTA API jar - * @param repositoryDir the directory containing an empty signature file - * - * @return true if the package javax.transaction.xa is not found in - * the JTA API jar, otherwise false - */ - protected abstract boolean verifyJTAJarForNoXA(final String classpath, final String repositoryDir) throws Exception; + protected abstract boolean runPackageSearch(final String packageOrClassName, final String[] testArguments) throws Exception; /** * Loads the specified file into a Properties object provided the specified file @@ -418,6 +421,7 @@ protected abstract boolean runPackageSearch(final String packageOrClassName, fin * not a regular file, can also be thrown if there * is an error creating an input stream from the * specified file. + * @throws FileNotFoundException If the specified map file does not exist. */ public Properties loadMapFile(final String mapFile) throws IOException, FileNotFoundException { @@ -442,8 +446,8 @@ public Properties loadMapFile(final String mapFile) throws IOException, FileNotF /** * This method will attempt to build a fully-qualified filename in the format of - * respositoryDir + baseName + .sig_ + - * version. + * {@code respositoryDir} + {@code baseName} + {@code .sig_} + + * {@code version}. * * @param baseName the base portion of the signature filename * @param repositoryDir the directory in which the signatures are stored @@ -498,10 +502,10 @@ protected String getSigFileName(final String baseName, final String repositoryDi * @throws Exception if the determined signature file is not a regular file or * does not exist */ - protected SignatureFileInfo getSigFileInfo(final String originalPackage, final String mapFile, - final String repositoryDir) throws Exception { + protected SignatureFileInfo getSigFileInfo(final String packageName, final String mapFile, final String repositoryDir) + throws Exception { - String packageName = originalPackage; + String packageNameCopy = packageName; String name = null; String version = null; Properties props = loadMapFile(mapFile); @@ -510,7 +514,7 @@ protected SignatureFileInfo getSigFileInfo(final String originalPackage, final S boolean packageFound = false; for (Enumeration e = props.propertyNames(); e.hasMoreElements();) { name = (String) (e.nextElement()); - if (name.equals(packageName)) { + if (name.equals(packageNameCopy)) { version = props.getProperty(name); packageFound = true; break; @@ -528,12 +532,12 @@ protected SignatureFileInfo getSigFileInfo(final String originalPackage, final S * We do this by removing the specified packages last package name section. So * jakarta.ejb.spi would become jakarta.ejb */ - int index = packageName.lastIndexOf("."); + int index = packageNameCopy.lastIndexOf("."); if (index <= 0) { throw new Exception( - "Package \"" + originalPackage + "\" not specified in mapping file \"" + mapFile + "\"."); + "Package \"" + packageName + "\" not specified in mapping file \"" + mapFile + "\"."); } - packageName = packageName.substring(0, index); + packageNameCopy = packageNameCopy.substring(0, index); } // end while /* Return the expected name of the signature file */ @@ -579,11 +583,11 @@ private static boolean isIgnorePackageUnderTest(final String packageName, private static void dumpTestArguments(final String[] params) { if (params != null && params.length > 0) { - System.out.println("----------------- BEGIN SIG PARAM DUMP -----------------"); + log.fine("----------------- BEGIN SIG PARAM DUMP -----------------"); for (int i = 0; i < params.length; i++) { - System.out.println(" Param[" + i + "]: " + params[i]); + log.fine(" Param[" + i + "]: " + params[i]); } - System.out.println("------------------ END SIG PARAM DUMP ------------------"); + log.fine("------------------ END SIG PARAM DUMP ------------------"); } } // END dumpTestArguments @@ -602,6 +606,10 @@ protected static class SignatureFileInfo { // -------------------------------------------------------- Constructors + /** + * @param file - The signature test file + * @param version - The Java version used to generate the signature test file + */ public SignatureFileInfo(final String file, final String version) { if (file == null) { @@ -619,12 +627,18 @@ public SignatureFileInfo(final String file, final String version) { // ------------------------------------------------------ Public Methods + /** + * @return File name as string + */ public String getFile() { return file; } // END getFileIncludingPath + /** + * @return Java version used to generate signatures + */ public String getVersion() { return version; diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/framework/TestProperty.java b/tck/src/main/java/ee/jakarta/tck/concurrent/framework/TestProperty.java new file mode 100644 index 00000000..425a1c46 --- /dev/null +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/framework/TestProperty.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * 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 + */ +package ee.jakarta.tck.concurrent.framework; + +import java.io.File; +import java.util.logging.Logger; + +/** + *

This enum represents the different test properties used within this TCK. + * Each one is given a description and documentation will automatically be created in the TCK distribution.

+ * + *

When a test property is requested from the client, we expect these properties to be available from the system.

+ * + *

When a test property is requested from the container, we will attempt to load the property from a known property file. + * {@link TCKFrameworkAppender} + *

+ */ +public enum TestProperty { + //Java properties that should always be set by the JVM + javaHome(true, "java.home", "Path to the java executable used to create the current JVM"), + javaSpecVer(true, "java.specification.version", "Specification version of the java executable"), + javaTempDir(true, "java.io.tmpdir", "The path to a temporary directory where a copy of the signature file will be created"), + javaVer(true, "java.version", "Full version of the java executable"), + + //TODO - add properties to allow users to configure wait times + + //Signature testing properties + signatureClasspath(false, "signature.sigTestClasspath", "The path to the Jakarta Concurrency API JAR used by your implementation.", ""), + signatureImageDir(true, "jimage.dir", "The path to a directory that is readable and writable that " + + "the signature test will cache Java SE modules as classes"); + + + private static final Logger log = Logger.getLogger(TestProperty.class.getCanonicalName()); + + private boolean required; + private String key; + private String description; + private String defaultValue; + + // CONSTRUCTORS + private TestProperty(final boolean required, final String key, final String description) { + this(required, key, description, null); + } + + private TestProperty(final boolean required, final String key, final String description, final String defaultValue) { + this.required = required; + this.key = key; + this.description = description; + this.defaultValue = defaultValue; + } + + // GETTERS + public boolean isRequired() { + return required; + } + + public String getKey() { + return key; + } + + public String getDescription() { + return description; + } + + // COMPARISONS + public boolean equals(final String expectedValue) { + return getValue().equalsIgnoreCase(expectedValue); + } + + public boolean isSet() { + String value = getValue(false); + if (value == null) + return false; + if (value.isBlank() || value.isEmpty()) { + return false; + } + return true; + } + + // CONVERTERS + public long getLong() throws IllegalStateException, NumberFormatException { + return Long.parseLong(getValue()); + } + + public int getInt() throws IllegalStateException, NumberFormatException { + return Integer.parseInt(getValue()); + } + + public File getFile() { + return new File(getValue()); + } + + /** + * Get the test property value. + * + * @return the property value + * @throws IllegalStateException if required and no property was found + */ + public String getValue() throws IllegalStateException { + return getValue(required); + } + + private String getValue(final boolean verify) throws IllegalStateException { + String value = null; + log.fine("Searching for property: " + key); + + // Client: get property from system + if (value == null) { + value = System.getProperty(key); + log.fine("Value from system: " + value); + } + + //Container: get property from properties file + if (value == null) { + value = TestPropertyHandler.loadProperties().getProperty(key); + log.fine("Value from resource file: " + value); + } + + //Default: get default property + if (value == null) { + value = defaultValue; + log.fine("Defaulting to value: " + value); + } + + if (verify && value == null) + throw new IllegalStateException("Could not obtain a value for system property: " + key); + + return value; + } +} diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/framework/TestPropertyHandler.java b/tck/src/main/java/ee/jakarta/tck/concurrent/framework/TestPropertyHandler.java new file mode 100644 index 00000000..b4226ad0 --- /dev/null +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/framework/TestPropertyHandler.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * 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 + */ +package ee.jakarta.tck.concurrent.framework; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.Properties; +import java.util.logging.Logger; + +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.container.ResourceContainer; + +/** + * This uitlity class handles the caching and loading of test properties between the + * client and container when tests are run inside an Arquillian container. + */ +public final class TestPropertyHandler { + + private static final Logger log = Logger.getLogger(TestPropertyHandler.class.getCanonicalName()); + + private static final String PROP_FILE = "tck.properties"; + private static Properties foundProperties; + + private TestPropertyHandler() { + //UTILITY CLASS + } + + /** + * Container: Load properties from the TestProperty cache file, and return a properties object. + * If any error occurs in finding the cache file, or loading the properties, + * then an empty properties object is returned. + * + * @return - the cached properties, or an empty properties object. + */ + static Properties loadProperties() { + if (foundProperties != null) { + return foundProperties; + } + + //Try to load property file + foundProperties = new Properties(); + InputStream propsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(PROP_FILE); + if (propsStream != null) { + try { + foundProperties.load(propsStream); + } catch (Exception e) { + log.info("Attempted to load properties from resource " + PROP_FILE + " but failed. Because: " + e.getLocalizedMessage()); + } + } + + return foundProperties; + } + + /** + * Client: Store system properties from the client to a properties file + * as a resource on the archive sent to the container. + * + * @param archive - The archive going to the container + * @return the archive with a resource file attached + */ + public static Archive storeProperties(final Archive archive) { + if (!(archive instanceof ResourceContainer)) { + throw new RuntimeException("Could not store properties to archive, because it was not a ResourceConatiner. " + + "Please raise an issue with the maintainers of the Jakarta Concurrency TCK."); + } + + Properties filteredProps = new Properties(); + for (TestProperty prop : TestProperty.values()) { + if (prop.getKey().startsWith("java.")) { + continue; + } + filteredProps.put(prop.getKey(), prop.getValue()); + } + + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + filteredProps.store(out, "System properties shared with Arquillian container"); + ((ResourceContainer) archive).addAsResource(new StringAsset(out.toString()), PROP_FILE); + } catch (Exception e) { + throw new RuntimeException("Could not store properties file to archive", e); + } + + return archive; + } +} diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/framework/arquillian/extensions/TCKArchiveProcessor.java b/tck/src/main/java/ee/jakarta/tck/concurrent/framework/arquillian/extensions/TCKArchiveProcessor.java index 6d07f614..181ddfd7 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/framework/arquillian/extensions/TCKArchiveProcessor.java +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/framework/arquillian/extensions/TCKArchiveProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -35,6 +35,7 @@ import org.jboss.shrinkwrap.resolver.api.maven.Maven; import ee.jakarta.tck.concurrent.common.signature.ConcurrencySignatureTestRunner; +import ee.jakarta.tck.concurrent.framework.TestProperty; import ee.jakarta.tck.concurrent.framework.junit.anno.Common; import ee.jakarta.tck.concurrent.framework.junit.anno.Signature; @@ -84,7 +85,7 @@ private static void appendSignaturePackages(final Archive applicationArchive, if (!testClass.isAnnotationPresent(Signature.class)) { return; //Nothing to append } - final String jdkVersion = System.getProperty("java.specification.version"); + final String jdkVersion = TestProperty.javaSpecVer.getValue(); final Package signaturePackage = ConcurrencySignatureTestRunner.class.getPackage(); final String signatureFileName = ConcurrencySignatureTestRunner.SIG_FILE_NAME + "_" + jdkVersion; @@ -100,7 +101,7 @@ private static void appendSignaturePackages(final Archive applicationArchive, ((ClassContainer) applicationArchive).addPackage(signaturePackage); // Add the sigtest plugin library - File sigTestDep = Maven.resolver().resolve("org.netbeans.tools:sigtest-maven-plugin:1.6").withoutTransitivity().asSingleFile(); + File sigTestDep = Maven.resolver().resolve("jakarta.tck:sigtest-maven-plugin:2.3").withoutTransitivity().asSingleFile(); log.info("Application Archive [" + applicationName + "] is being appended with library " + sigTestDep.getName()); ((LibraryContainer) applicationArchive).addAsLibrary(sigTestDep); diff --git a/tck/src/main/java/ee/jakarta/tck/concurrent/framework/arquillian/extensions/TCKFrameworkAppender.java b/tck/src/main/java/ee/jakarta/tck/concurrent/framework/arquillian/extensions/TCKFrameworkAppender.java index 34827a76..a7d76743 100644 --- a/tck/src/main/java/ee/jakarta/tck/concurrent/framework/arquillian/extensions/TCKFrameworkAppender.java +++ b/tck/src/main/java/ee/jakarta/tck/concurrent/framework/arquillian/extensions/TCKFrameworkAppender.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -22,6 +22,7 @@ import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; +import ee.jakarta.tck.concurrent.framework.TestPropertyHandler; import ee.jakarta.tck.concurrent.framework.TestServlet; import ee.jakarta.tck.concurrent.framework.junit.anno.Common; import ee.jakarta.tck.concurrent.framework.junit.extensions.AssertionExtension; @@ -57,7 +58,7 @@ public Archive createAuxiliaryArchive() { framework = ShrinkWrap.create(JavaArchive.class, archiveName); framework.addPackages(false, utilPackage, annoPackage, extePackage); - return framework; + return TestPropertyHandler.storeProperties(framework); } }