diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index f59edc7..bd16536 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -14,6 +14,15 @@ updates:
- dependency-name: '*:*'
update-types: ['version-update:semver-major', 'version-update:semver-minor']
open-pull-requests-limit: 10
+ # WildFly Jakarta Servlet TCK Runner
+ - package-ecosystem: "maven"
+ directory: "/servlet-tck"
+ schedule:
+ interval: "daily"
+ ignore:
+ - dependency-name: '*:*'
+ update-types: ['version-update:semver-major', 'version-update:semver-minor']
+ open-pull-requests-limit: 10
- package-ecosystem: "github-actions"
# Workflow files stored in the
# default location of `.github/workflows`
diff --git a/.github/workflows/servlet-tck.yml b/.github/workflows/servlet-tck.yml
new file mode 100644
index 0000000..fa3ed45
--- /dev/null
+++ b/.github/workflows/servlet-tck.yml
@@ -0,0 +1,61 @@
+# This is a basic workflow that is manually triggered
+
+name: Jakarta Servlet TCK on WildFly
+
+# Controls when the action will run. Workflow runs when manually triggered using the UI
+# or API.
+on:
+ push:
+ branches:
+ - 'main'
+ paths:
+ - '.github/workflows/servlet-tck.yml'
+ - 'servlet-tck/**'
+ pull_request:
+ branches:
+ - 'main'
+ paths:
+ - '.github/workflows/servlet-tck.yml'
+ - 'servlet-tck/**'
+ # Currently disabled as we're not yet passing, and we don't need to add extra noise
+ #schedule:
+ # - cron: '0 0 * * *' # Every day at 00:00 UTC
+ workflow_dispatch:
+
+# Only run the latest job
+concurrency:
+ group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
+ cancel-in-progress: true
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+ jakarta-servlet-tck:
+ # The type of runner that the job will run on
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ java: ['17', '21']
+
+ # Runner steps
+ steps:
+ - uses: actions/checkout@v4
+ - name: Setup Java JDK
+ uses: actions/setup-java@v4
+ with:
+ java-version: ${{ matrix.java }}
+ distribution: 'temurin'
+ cache: 'maven'
+ - name: Jakarta Servlet TCK on WildFly with Java ${{ matrix.java }}
+ run: |
+ cd servlet-tck
+ mvn -B clean verify -fae
+ - uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: test-reports-${{ matrix.java }}
+ path: |
+ '**/surefire-reports/'
+ '**/failsafe-reports/'
+ '**/server.log'
+
diff --git a/servlet-tck/README.adoc b/servlet-tck/README.adoc
new file mode 100644
index 0000000..d7f4826
--- /dev/null
+++ b/servlet-tck/README.adoc
@@ -0,0 +1,60 @@
+= WildFly Jakarta Servlet TCK Runner
+
+This project allows WildFly to run the https://jakarta.ee/specifications/servlet/[Jakarta Servlet TCK].
+
+== Requirements
+
+You must have at least Java SE 17 and Maven installed.
+
+== Running the TCK
+
+The simplest way to run the TCK is to run:
+
+[source,bash]
+----
+mvn clean verify
+----
+
+What this will do is download the Jakarta Servlet TCK, unzip it and install the artifacts from the ZIP to your local
+Maven Repository.
+
+=== Running Against a Specific Build of WildFly
+
+IMPORTANT: The build must container JAR's for modules. These are used for client side testing.
+
+To run against a specific build of WildFly you must set the `JBOSS_HOME` environment variable to the path of the server.
+
+[source,bash]
+----
+JBOSS_HOME=/path/to/wildfly mvn clean verify
+----
+
+This will run the TCK against that build of WildFly and will not provision a WildFly server.
+
+=== Running a Single Test
+
+Running a single test is fairly easy. You simply need to run:
+
+[source,bash]
+----
+mvn clean verify -Dtest=SomeTests
+----
+
+This is the same as any other
+
+=== Debug Logging
+
+You can output debug logging be passing the `-Dtest.log.level=DEBUG` via the command line.
+
+=== Debugging Tests
+
+You can debug a test by using the WildFly Arquillian debug properties.
+
+* `wildfly.debug`: enables debugging
+* `wildfly.debug.port`: The port to listen on, defaults to 8787
+* `wildfly.debug.suspend`: Waits for you to attach the debugger before the startup of WildFly continues
+
+[source,bash]
+----
+mvn clean verify -Dtest=SomeTests -Dwildfly.debug -Dwildfly.debug.port=5005 -Dwildfly.debug.suspend
+----
\ No newline at end of file
diff --git a/servlet-tck/pom.xml b/servlet-tck/pom.xml
new file mode 100644
index 0000000..6c597d1
--- /dev/null
+++ b/servlet-tck/pom.xml
@@ -0,0 +1,133 @@
+
+
+
+
+ 4.0.0
+
+
+ org.jboss
+ jboss-parent
+ 41
+
+
+ org.wildfly.tck.servlet
+ servlet-tck-parent
+ 1.0.0.Final-SNAPSHOT
+ pom
+
+ WildFly: Jakarta Servlet TCK Parent
+ A TCK runner for the Jakarta Servlet TCK
+ https://github.com/wildfly/wildfly-tck-runner
+ 2024
+
+ Red Hat, Inc.
+ https://wildfly.org
+
+
+
+
+ Apache License, Version 2.0
+ https://www.apache.org/licenses/LICENSE-2.0
+
+
+
+
+
+ James R. Perkins
+ jperkins@redhat.com
+ Red Hat Inc.
+
+
+
+
+
+
+
+ tck-setup
+ tck-runner
+
+
+
+ scm:git:git@github.com:wildfly/wildfly-tck-runners.git
+ scm:git:git@github.com:wildfly/wildfly-tck-runner.git
+ github.com/wildfly/wildfly-tck-runners
+ HEAD
+
+
+
+ GitHub
+ https://github.com/wildfly/wildfly-tck-runner/issues
+
+
+
+
+
+
+ 17
+
+ ${maven.compiler.release}
+ ${maven.compiler.release}
+
+ ${maven.compiler.release}
+ ${settings.localRepository}
+
+
+ 6.1.0
+ ${version.jakarta.servlet-api}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ staging
+
+ https://jakarta.oss.sonatype.org
+ ${sonatypeOssDistMgmtNexusUrl}/content/repositories/staging/
+
+
+
+ sonatype-nexus-staging
+ Sonatype Nexus Staging
+ ${sonatypeOssDistMgmtStagingUrl}
+
+ true
+
+
+ false
+
+
+
+
+
+ sonatype-nexus-staging
+ Sonatype Nexus Staging
+ ${sonatypeOssDistMgmtStagingUrl}
+
+ true
+
+
+ false
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/servlet-tck/tck-runner/pom.xml b/servlet-tck/tck-runner/pom.xml
new file mode 100644
index 0000000..240abf9
--- /dev/null
+++ b/servlet-tck/tck-runner/pom.xml
@@ -0,0 +1,369 @@
+
+
+
+
+ 4.0.0
+
+ org.wildfly.tck.servlet
+ servlet-tck-parent
+ 1.0.0.Final-SNAPSHOT
+
+
+ tck-runner
+ WildFly: Jakarta Servlet TCK Runner
+
+
+
+ 1.9.1.Final
+ 10.0.0.Final
+ 1.2.6
+ 2.0.0
+ 5.11.1
+ 2.2
+
+ 3.0.6.Final
+ 1.2.1.Final
+ 2.0.1.Final
+
+ 5.1.0.Beta6
+ 5.0.1.Final
+
+
+
+
+ standalone.xml
+
+
+ org.wildfly
+ wildfly-preview-feature-pack
+
+ org.wildfly.channels
+ wildfly-preview
+
+ true
+ true
+ false
+ false
+
+
+
+
+
+ org.junit
+ junit-bom
+ ${version.org.junit}
+ pom
+ import
+
+
+ org.jboss.arquillian
+ arquillian-bom
+ ${version.org.jboss.arquillian}
+ pom
+ import
+
+
+ org.jboss.shrinkwrap
+ shrinkwrap-bom
+ ${version.org.jboss.shrinkwrap}
+ import
+ pom
+
+
+ org.wildfly.arquillian
+ wildfly-arquillian-bom
+ ${version.org.wildfly.arquillian}
+ pom
+ import
+
+
+
+
+
+
+ jakarta.tck
+ servlet-tck-runtime
+ ${version.jakarta.servlet-tck}
+ test
+
+
+ jakarta.annotation
+ jakarta.annotation-api
+
+
+ org.jboss.arquillian.junit
+ arquillian-junit-core
+
+
+
+
+ jakarta.tck
+ sigtest-maven-plugin
+ ${version.jakartaee.tck.sigtest}
+ test
+
+
+ org.jboss.arquillian.test
+ arquillian-test-spi
+ test
+
+
+
+ org.jboss.arquillian.test
+ arquillian-test-impl-base
+ test
+
+
+ org.jboss.arquillian.junit5
+ arquillian-junit5-container
+ test
+
+
+ org.jboss.shrinkwrap
+ shrinkwrap-api
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.jboss.logmanager
+ jboss-logmanager
+ ${version.org.jboss.logging.jboss-logmanager}
+ test
+
+
+
+ org.jboss.slf4j
+ slf4j-jboss-logmanager
+ ${version.org.jboss.slf4j.slf4j-jboss-logmanager}
+ test
+
+
+ org.wildfly.arquillian
+ wildfly-arquillian-container-managed
+
+
+ org.jboss.logmanager
+ jboss-logmanager
+
+
+ jakarta.annotation
+ jakarta.annotation-api
+
+
+ test
+
+
+
+
+
+
+
+ src/test/resources
+ true
+
+ arquillian.xml
+
+
+
+ src/test/resources
+
+ arquillian.xml
+
+
+
+
+
+ maven-antrun-plugin
+
+
+ process-test-classes
+
+ run
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ echo
+ process-test-classes
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+ maven-surefire-plugin
+
+
+
+ default-test
+
+ true
+
+
+
+ servlet-tck
+ test
+
+ test
+
+
+
+ jakarta.tck:servlet-tck-runtime
+
+
+
+ ${jakarta.api.libs}
+
+
+
+ ${project.build.directory}/java-bundle
+ ${sigTestClasspath}:${project.build.directory}/java-bundle/java.base
+
+
+ org.jboss.logmanager.LogManager
+
+ true
+
+ true
+
+ org.jboss.slf4j:slf4j-jboss-logmanager
+
+
+
+
+
+
+
+
+
+
+ set-jboss-home
+
+
+ env.JBOSS_HOME
+
+
+
+ ${env.JBOSS_HOME}
+
+
+
+ provision-container
+
+
+ !env.JBOSS_HOME
+
+
+
+ ${project.build.directory}${file.separator}wildfly
+
+
+
+
+ org.wildfly.plugins
+ wildfly-maven-plugin
+ ${version.wildfly-maven-plugin}
+
+ ${provisioning.skip}
+ ${jboss.home}
+ ${galleon.offline}
+
+ ${galleon.fork.embedded}
+
+
+
+ ${wildfly.feature.pack.groupId}
+ ${wildfly.feature.pack.artifactId}
+ ${version.org.wildfly}
+
+
+
+
+
+
+ ${wildfly.channel.manifest.groupId}
+ ${wildfly.channel.manifest.artifactId}
+ ${version.org.wildfly}
+
+
+
+
+ core-server
+ servlet
+ undertow-https
+
+
+
+
+ server-provisioning
+ generate-test-resources
+
+ provision
+
+
+
+ configure-server
+ process-test-resources
+
+ execute-commands
+
+
+ ${jboss.home}
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/servlet-tck/tck-runner/src/test/java/org/wildfly/tck/servlet/arquillian/WildFlyArquillianExtension.java b/servlet-tck/tck-runner/src/test/java/org/wildfly/tck/servlet/arquillian/WildFlyArquillianExtension.java
new file mode 100644
index 0000000..2bdcfb6
--- /dev/null
+++ b/servlet-tck/tck-runner/src/test/java/org/wildfly/tck/servlet/arquillian/WildFlyArquillianExtension.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright The WildFly Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.wildfly.tck.servlet.arquillian;
+
+import java.util.List;
+
+import org.jboss.arquillian.container.spi.client.deployment.DeploymentDescription;
+import org.jboss.arquillian.container.test.impl.client.deployment.AnnotationDeploymentScenarioGenerator;
+import org.jboss.arquillian.container.test.spi.client.deployment.DeploymentScenarioGenerator;
+import org.jboss.arquillian.core.spi.LoadableExtension;
+import org.jboss.arquillian.test.spi.TestClass;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+
+/**
+ * @author James R. Perkins
+ */
+public class WildFlyArquillianExtension implements LoadableExtension {
+ @Override
+ public void register(final ExtensionBuilder builder) {
+ builder.override(DeploymentScenarioGenerator.class, AnnotationDeploymentScenarioGenerator.class, ScenarioBasedUpdater.class);
+ }
+
+ /**
+ * Hacks the {@link AnnotationDeploymentScenarioGenerator} to add missing resources in deployments.
+ */
+ public static class ScenarioBasedUpdater extends AnnotationDeploymentScenarioGenerator {
+
+ @Override
+ public List generate(TestClass testClass) {
+ final List descriptions = super.generate(testClass);
+
+ for (DeploymentDescription description : descriptions) {
+ final Archive> applicationArchive = description.getArchive();
+
+ // This works around a future TCK challenge and can be removed when it's resolved
+ if (testClass.getName()
+ .equals("servlet.tck.pluggability.api.jakarta_servlet.registration.RegistrationTests") &&
+ applicationArchive instanceof WebArchive webArchive) {
+ webArchive.addClass(servlet.tck.api.jakarta_servlet.servletcontext30.AddFilterString.class);
+ }
+
+ // This works around a TCK challenge and can be removed once a release including
+ // https://github.com/jakartaee/servlet/issues/691 is out.
+ if (testClass.getName()
+ .equals("servlet.tck.spec.defaultmapping.DefaultMappingTests") &&
+ applicationArchive instanceof WebArchive webArchive) {
+ webArchive.addClasses(
+ servlet.tck.spec.requestmap.TestServlet1.class,
+ servlet.tck.spec.requestmap.TestServlet2.class,
+ servlet.tck.spec.requestmap.TestServlet3.class,
+ servlet.tck.spec.requestmap.TestServlet4.class,
+ servlet.tck.spec.requestmap.TestServlet5.class
+ );
+ }
+ }
+
+ return descriptions;
+ }
+
+ }
+}
diff --git a/servlet-tck/tck-runner/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/servlet-tck/tck-runner/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
new file mode 100644
index 0000000..656ea13
--- /dev/null
+++ b/servlet-tck/tck-runner/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -0,0 +1 @@
+org.wildfly.tck.servlet.arquillian.WildFlyArquillianExtension
\ No newline at end of file
diff --git a/servlet-tck/tck-runner/src/test/resources/arquillian.xml b/servlet-tck/tck-runner/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..a394c28
--- /dev/null
+++ b/servlet-tck/tck-runner/src/test/resources/arquillian.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ ${jboss.home}
+
+
+
+
+ true
+ https
+
+
+
+
diff --git a/servlet-tck/tck-runner/src/test/resources/configure-server.cli b/servlet-tck/tck-runner/src/test/resources/configure-server.cli
new file mode 100644
index 0000000..b577d24
--- /dev/null
+++ b/servlet-tck/tck-runner/src/test/resources/configure-server.cli
@@ -0,0 +1,39 @@
+embed-server --admin-only=true
+
+# Turn on trace logging
+/subsystem=logging/console-handler=CONSOLE:undefine-attribute(name=level)
+if (outcome != success) of /subsystem=logging/logger=servlet.tck:read-resource
+ /subsystem=logging/logger=servlet.tck:add(level=TRACE)
+else
+ /subsystem=logging/logger=servlet.tck:write-attribute(name=level, value=TRACE)
+end-if
+
+# Configure a filesystem-realm with the required user
+if (outcome != success) of /subsystem=elytron/filesystem-realm=tck-realm:read-resource
+ /subsystem=elytron/filesystem-realm=tck-realm:add(path=tck-users, relative-to=jboss.server.config.dir)
+ /subsystem=elytron/filesystem-realm=tck-realm:add-identity(identity=javajoe)
+ /subsystem=elytron/filesystem-realm=tck-realm:set-password(identity=javajoe, clear={password="javajoe"})
+ /subsystem=elytron/filesystem-realm=tck-realm:add-identity-attribute(identity=javajoe, name=Roles, value=["Manager", "Employee"])
+ /subsystem=elytron/filesystem-realm=tck-realm:add-identity(identity=j2ee)
+ /subsystem=elytron/filesystem-realm=tck-realm:set-password(identity=j2ee, clear={password="j2ee"})
+ /subsystem=elytron/filesystem-realm=tck-realm:add-identity-attribute(identity=j2ee, name=Roles, value=["Administrator", "Employee"])
+end-if
+
+# Configure a security domain that makes use of our security realm
+if (outcome != success) of /subsystem=elytron/security-domain=tck-security-domain:read-resource
+ /subsystem=elytron/security-domain=tck-security-domain:add(realms=[{realm=tck-realm}], default-realm=tck-realm, permission-mapper=default-permission-mapper)
+end-if
+
+# Set the EJB security domain, if EJB is present
+if (outcome == success) of /subsystem=ejb3:read-resource
+ /subsystem=ejb3/application-security-domain=other:write-attribute(name=security-domain, value=tck-security-domain)
+ /subsystem=undertow/application-security-domain=other:write-attribute(name=security-domain, value=tck-security-domain)
+end-if
+
+# Update Undertow configuration to make use of our security domain
+if (outcome != success) of /subsystem=undertow/application-security-domain=tck-security-domain:read-resource
+ /subsystem=undertow/application-security-domain=tck-security-domain:add(security-domain=tck-security-domain, enable-jacc=false)
+ /subsystem=undertow:write-attribute(name=default-security-domain, value=tck-security-domain)
+end-if
+
+stop-embedded-server
\ No newline at end of file
diff --git a/servlet-tck/tck-runner/src/test/resources/logging.properties b/servlet-tck/tck-runner/src/test/resources/logging.properties
new file mode 100644
index 0000000..9da7218
--- /dev/null
+++ b/servlet-tck/tck-runner/src/test/resources/logging.properties
@@ -0,0 +1,21 @@
+#
+# Copyright The WildFly Authors
+# SPDX-License-Identifier: Apache-2.0
+#
+
+loggers=servlet.tck
+
+logger.level=INFO
+logger.handlers=CONSOLE
+
+logger.servlet.tck.level=${test.log.level:INFO}
+
+handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
+handler.CONSOLE.formatter=COLOR-PATTERN
+handler.CONSOLE.properties=autoFlush,target
+handler.CONSOLE.autoFlush=true
+handler.CONSOLE.target=SYSTEM_OUT
+
+formatter.COLOR-PATTERN=org.jboss.logmanager.formatters.ColorPatternFormatter
+formatter.COLOR-PATTERN.properties=pattern
+formatter.COLOR-PATTERN.pattern=[client] %d{HH\:mm\:ss,SSS} %-5p [%c] (%t) %s%e%n
\ No newline at end of file
diff --git a/servlet-tck/tck-setup/pom.xml b/servlet-tck/tck-setup/pom.xml
new file mode 100644
index 0000000..1524193
--- /dev/null
+++ b/servlet-tck/tck-setup/pom.xml
@@ -0,0 +1,106 @@
+
+
+
+
+ 4.0.0
+
+ org.wildfly.tck.servlet
+ servlet-tck-parent
+ 1.0.0.Final-SNAPSHOT
+
+
+ tck-setup
+ WildFly: Jakarta Servlet TCK Setup
+
+
+ ${project.build.directory}/tck
+ false
+
+ https://download.eclipse.org/jakartaee/servlet/6.1/jakarta-servlet-tck-${version.jakarta.servlet-tck}.zip
+ 1170697a87622a920bd50f0a68ed594c6efc5e17dd370566312194c4e12bec29
+ jakarta-servlet-tck-${version.jakarta.servlet-tck}
+ ${project.build.directory}/jakarta-servlet-tck
+ ${project.build.directory}/jakarta-servlet-tck/servlet-tck/artifacts
+
+
+
+
+ com.googlecode.maven-download-plugin
+ download-maven-plugin
+ 1.9.0
+
+
+ download-tck
+ test-compile
+
+ wget
+
+
+
+
+ ${tck.url}
+ true
+ ${tck.download.directory}
+ jakarta-servlet-tck-${version.jakarta.servlet-tck}.zip
+ ${tck.sha256}
+
+
+
+ maven-install-plugin
+
+
+ install-servlet-tck-pom
+ test-compile
+
+ install-file
+
+
+ jakarta.tck
+ servlet-tck
+ ${version.jakarta.servlet-tck}
+ pom
+ ${tck.artifact.directory}/servlet-tck-${version.jakarta.servlet-tck}.pom
+ ${maven.repo.local}
+
+
+
+ install-servlet-tck-runtime
+ test-compile
+
+ install-file
+
+
+ jakarta.tck
+ servlet-tck-runtime
+ ${version.jakarta.servlet-tck}
+ jar
+ ${tck.artifact.directory}/servlet-tck-runtime-${version.jakarta.servlet-tck}.jar
+ ${maven.repo.local}
+
+
+
+ install-servlet-tck-util
+ test-compile
+
+ install-file
+
+
+ jakarta.tck
+ servlet-tck-util
+ ${version.jakarta.servlet-tck}
+ jar
+ ${tck.artifact.directory}/servlet-tck-util-${version.jakarta.servlet-tck}.jar
+ ${maven.repo.local}
+
+
+
+
+
+
+
+
\ No newline at end of file