(geronimo-mail) 04/04: Add geronimo-mail_2.1_tck module running the Jakarta Mail TCK 2.1.1
[email protected] Sat, 18 Jul 2026 08:28:02 +0000
| Newsgroups | gmane.comp.java.geronimo.cvs |
|---|---|
| Message-ID | <[email protected]> |
This is an automated email from the ASF dual-hosted git repository. rzo1 pushed a commit to branch mail-tck in repository https://gitbox.apache.org/repos/asf/geronimo-mail.git commit 9d4601cab6ebc09a94a65ed4fc9425594dd319f8 Author: Richard Zowalla <[email protected]> AuthorDate: Sat Jul 18 10:27:41 2026 +0200 Add geronimo-mail_2.1_tck module running the Jakarta Mail TCK 2.1.1 mvn verify -Ptck -pl geronimo-mail_2.1_tck downloads the TCK from download.eclipse.org (sha256-verified), boots an embedded Apache James 3.9 (SMTP 1025 / IMAP 1143, [email protected]), populates the test1 mailbox with the TCK's fpopulate, executes the JavaTest harness through the embedded Ant runtime (no system Ant needed, JavaTest concurrency pinned to 1) and gates the build on the report at verify. Known failures are excluded via src/tck/geronimo.jtx so the gate is green (currently 191 passed / 0 failed) and defects can be fixed one by one by removing their exclude entries. Signature tests are excluded separately as they need a dedicated sigtest setup. The IMAP APPEND continuation deadlock documented in tck.adoc is the reason mailbox population uses the Angus RI as fixture client. Requires a JDK 21 (JavaTest still installs a SecurityManager, gone in JDK 24+). Without -Ptck the module is a no-op and nothing is ever published from it. --- geronimo-mail_2.1_impl/tck.adoc | 15 + geronimo-mail_2.1_tck/pom.xml | 460 +++++++++++++++++++++ .../apache/geronimo/mail/tck/JamesTckServer.java | 380 +++++++++++++++++ geronimo-mail_2.1_tck/src/tck/geronimo.jtx | 167 ++++++++ pom.xml | 1 + 5 files changed, 1023 insertions(+) diff --git a/geronimo-mail_2.1_impl/tck.adoc b/geronimo-mail_2.1_impl/tck.adoc index 3fa5340..974a748 100644 --- a/geronimo-mail_2.1_impl/tck.adoc +++ b/geronimo-mail_2.1_impl/tck.adoc @@ -1,3 +1,18 @@ +NOTE: The TCK run described below is automated by the `geronimo-mail_2.1_tck` +module at the repository root: `mvn verify -Ptck -pl geronimo-mail_2.1_tck` +downloads the Jakarta Mail TCK +2.1.1, boots an embedded Apache James server (SMTP 1025 / IMAP 1143, user +`[email protected]`/`1234`), populates the `test1` mailbox and executes the +JavaTest harness. Pass `-Dtck.failIgnore=false` to make TCK failures fail the +build. The manual setup below remains as reference for interactive/GUI runs and +for debugging individual tests. + +KNOWN ISSUE: populating the mailbox through the geronimo IMAP client deadlocks +in `IMAPConnection.appendMessage` (the client blocks waiting for the server's +literal continuation that never arrives - reproducible against Apache James 3.9). +The tck module therefore runs `fpopulate` with the Angus RI client (fixture +setup only). The same defect likely affects the TCK's own APPEND-related tests. + # Docker CTS Mailserver setup Create a docker-compose.yml file: diff --git a/geronimo-mail_2.1_tck/pom.xml b/geronimo-mail_2.1_tck/pom.xml new file mode 100644 index 0000000..2e796d0 --- /dev/null +++ b/geronimo-mail_2.1_tck/pom.xml @@ -0,0 +1,460 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.geronimo</groupId> + <artifactId>geronimo-mail_2.1_parent</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <groupId>org.apache.geronimo.mail</groupId> + <artifactId>geronimo-mail_2.1_tck</artifactId> + <name>Apache Geronimo Jakarta Mail 2.1 :: TCK</name> + + <description> + Runs the Jakarta Mail 2.1 TCK against the geronimo-mail implementation. + Activate with -Ptck (downloads the TCK from download.eclipse.org, boots an + embedded Apache James server and executes the JavaTest harness). Without + the profile this module is a no-op. Nothing from the TCK distribution is + ever committed to the repository. + </description> + + <properties> + <james.version>3.9.0</james.version> + <mail-tck.version>2.1.1</mail-tck.version> + <mail-tck.url>https://download.eclipse.org/jakartaee/mail/2.1/jakarta-mail-tck-${mail-tck.version}.zip</mail-tck.url> + <mail-tck.sha256>c749d4245acc51a53c8c3058782f3da6dfd87384a4485ce3fee3c8d36bd0df1b</mail-tck.sha256> + <tck.home>${project.build.directory}/mail-tck</tck.home> + <tck.smtp.port>1025</tck.smtp.port> + <tck.imap.port>1143</tck.imap.port> + <tck.control.port>11300</tck.control.port> + <tck.user>[email protected]</tck.user> + <tck.password>1234</tck.password> + <!-- known failures are excluded via src/tck/geronimo.jtx, so any new + failure is a regression and fails the build; set to true to switch + back to report-only mode --> + <tck.failIgnore>false</tck.failIgnore> + <!-- JavaTest per-test timeout multiplier (base 10 minutes); kept low so + tests hitting client-side hangs fail fast instead of stalling the run --> + <tck.timeout.factor>0.1</tck.timeout.factor> + <!-- this module is a test rig, never publish it --> + <maven.deploy.skip>true</maven.deploy.skip> + <maven.javadoc.skip>true</maven.javadoc.skip> + <maven.source.skip>true</maven.source.skip> + </properties> + + <dependencies> + <!-- the artifact under test; also enforces reactor build order --> + <dependency> + <groupId>org.apache.geronimo.mail</groupId> + <artifactId>geronimo-mail_2.1_mail</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + + <!-- embedded Apache James used as the TCK mail server (SMTP + IMAP). + jakarta.mail-api / Angus are excluded so no foreign Jakarta Mail + implementation is around; the James server JVM is independent of + the TCK test JVMs anyway. --> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-protocols-smtp</artifactId> + <version>${james.version}</version> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-protocols-imap4</artifactId> + <version>${james.version}</version> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-protocols-library</artifactId> + <version>${james.version}</version> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-protocols-library</artifactId> + <version>${james.version}</version> + <type>test-jar</type> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>apache-james-mailbox-memory</artifactId> + <version>${james.version}</version> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>apache-james-mailbox-memory</artifactId> + <version>${james.version}</version> + <type>test-jar</type> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>apache-james-mailbox-api</artifactId> + <version>${james.version}</version> + <type>test-jar</type> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>apache-james-mailbox-store</artifactId> + <version>${james.version}</version> + <type>test-jar</type> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-data-memory</artifactId> + <version>${james.version}</version> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-mailrepository-memory</artifactId> + <version>${james.version}</version> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-queue-memory</artifactId> + <version>${james.version}</version> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-core</artifactId> + <version>${james.version}</version> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-testing</artifactId> + <version>${james.version}</version> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>event-bus-api</artifactId> + <version>${james.version}</version> + <type>test-jar</type> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>metrics-tests</artifactId> + <version>${james.version}</version> + </dependency> + <!-- James' MockProtocolHandlerLoader (protocols-library test-jar) wires the + SMTP handler chain via Guice; test-jars do not pull their dependencies + transitively, so it is declared explicitly. Only used inside the embedded + James server JVM - the TCK tests themselves run against JARPATH, which + contains nothing but the geronimo-mail and activation jars. --> + <dependency> + <groupId>com.google.inject</groupId> + <artifactId>guice</artifactId> + <version>6.0.0</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + <version>2.0.13</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <release>11</release> + </configuration> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>tck</id> + <build> + <plugins> + <!-- lay out the jars the TCK runs against (JARPATH) and the + fixture client used to populate the test mailbox --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-jarpath</id> + <phase>generate-test-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>org.apache.geronimo.mail</groupId> + <artifactId>geronimo-mail_2.1_mail</artifactId> + <version>${project.version}</version> + <destFileName>geronimo-mail_2.1_mail.jar</destFileName> + </artifactItem> + <artifactItem> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-activation_2.0_spec</artifactId> + <version>1.0.0</version> + <destFileName>geronimo-activation_2.0_spec.jar</destFileName> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.directory}/jarpath</outputDirectory> + </configuration> + </execution> + <!-- fixture client used only to populate the test1 mailbox: + population through the geronimo IMAP client currently hangs + in APPEND (continuation deadlock, known issue - see tck.adoc), + and mailbox population is test setup, not the system under test --> + <execution> + <id>copy-fixture</id> + <phase>generate-test-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>jakarta.mail</groupId> + <artifactId>jakarta.mail-api</artifactId> + <version>2.1.3</version> + </artifactItem> + <artifactItem> + <groupId>jakarta.activation</groupId> + <artifactId>jakarta.activation-api</artifactId> + <version>2.1.3</version> + </artifactItem> + <artifactItem> + <groupId>org.eclipse.angus</groupId> + <artifactId>angus-mail</artifactId> + <version>2.0.3</version> + </artifactItem> + <artifactItem> + <groupId>org.eclipse.angus</groupId> + <artifactId>angus-activation</artifactId> + <version>2.0.2</version> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.directory}/fixture</outputDirectory> + <stripVersion>true</stripVersion> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <version>3.1.0</version> + <executions> + <!-- download, verify and unpack the TCK; patch ts.jte --> + <execution> + <id>prepare-tck</id> + <phase>process-test-resources</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <target> + <get src="${mail-tck.url}" dest="${project.build.directory}/jakarta-mail-tck-${mail-tck.version}.zip" skipexisting="true"/> + <checksum file="${project.build.directory}/jakarta-mail-tck-${mail-tck.version}.zip" algorithm="SHA-256" property="${mail-tck.sha256}" verifyProperty="tck.checksum.ok"/> + <fail message="jakarta-mail-tck-${mail-tck.version}.zip checksum mismatch"> + <condition> + <isfalse value="${tck.checksum.ok}"/> + </condition> + </fail> + <unzip src="${project.build.directory}/jakarta-mail-tck-${mail-tck.version}.zip" dest="${project.build.directory}"/> + + <!-- point the TCK at this environment; @{...} regex escapes are literal $ --> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^TS_HOME=.*" replace="TS_HOME=${tck.home}" byline="true"/> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^JAVA_HOME=.*" replace="JAVA_HOME=${java.home}" byline="true"/> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^JARPATH=.*" replace="JARPATH=${project.build.directory}/jarpath" byline="true"/> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^API_JAR=.*" replace="API_JAR=${project.build.directory}/jarpath/geronimo-mail_2.1_mail.jar:${project.build.directory}/jarpath/geronimo-activation_2.0_spec.jar" byline="true"/> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^CI_JAR=.*" replace="CI_JAR=" byline="true"/> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^JAVAMAIL_SERVER=$" replace="JAVAMAIL_SERVER=localhost -pn ${tck.imap.port}" byline="true"/> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^JAVAMAIL_USERNAME=$" replace="JAVAMAIL_USERNAME=${tck.user}" byline="true"/> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^JAVAMAIL_PASSWORD=$" replace="JAVAMAIL_PASSWORD=${tck.password}" byline="true"/> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^JAVAMAIL_TRANSPORT_SERVER=.*" replace="JAVAMAIL_TRANSPORT_SERVER=localhost -tpn ${tck.smtp.port}" byline="true"/> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^SMTP_USERNAME=.*" replace="SMTP_USERNAME=user01" byline="true"/> + <replaceregexp file="${tck.home}/lib/ts.jte" match="^SMTP_DOMAIN=.*" replace="SMTP_DOMAIN=james.local" byline="true"/> + + <!-- append the project-owned exclude list of known failures + (src/tck/geronimo.jtx) to the TCK's shipped excludes --> + <concat destfile="${tck.home}/lib/ts.jtx" append="true"> + <fileset file="${project.basedir}/src/tck/geronimo.jtx"/> + </concat> + + <!-- the JavaTest harness installs a SecurityManager, which JDK 17+ + only permits with this flag (and JDK 24+ not at all - run the + tck profile with a JDK 21) --> + <replace file="${tck.home}/build.xml" token="<sysproperty key="testDebug"" value="<jvmarg value="-Djava.security.manager=allow"/><sysproperty key="testDebug""/> + <replace file="${tck.home}/build.xml" token=" -timeoutFactor 1" value=" -timeoutFactor ${tck.timeout.factor}"/> + </target> + </configuration> + </execution> + + <!-- boot embedded James, wait for it, populate mailbox test1 --> + <execution> + <id>start-james-and-populate</id> + <phase>pre-integration-test</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <target> + <java classname="org.apache.geronimo.mail.tck.JamesTckServer" fork="true" spawn="true"> + <classpath refid="maven.compile.classpath"/> + <sysproperty key="tck.smtp.port" value="${tck.smtp.port}"/> + <sysproperty key="tck.imap.port" value="${tck.imap.port}"/> + <sysproperty key="tck.control.port" value="${tck.control.port}"/> + </java> + <waitfor maxwait="120" maxwaitunit="second" checkevery="500" timeoutproperty="tck.james.timeout"> + <and> + <socket server="127.0.0.1" port="${tck.imap.port}"/> + <socket server="127.0.0.1" port="${tck.smtp.port}"/> + </and> + </waitfor> + <fail message="embedded James did not open ports ${tck.smtp.port}/${tck.imap.port} in time" if="tck.james.timeout"/> + + <!-- fixture setup: fill mailbox 'test1' with the TCK's own data --> + <java classname="fpopulate" fork="true" dir="${tck.home}/tests/mailboxes" failonerror="true" timeout="120000"> + <classpath> + <pathelement location="${tck.home}/tests/mailboxes"/> + <fileset dir="${project.build.directory}/fixture"> + <include name="*.jar"/> + </fileset> + </classpath> + <arg value="-s"/> + <arg value="test1"/> + <arg value="-d"/> + <arg value="imap://user01%40james.local:${tck.password}@localhost:${tck.imap.port}/test1"/> + </java> + </target> + </configuration> + </execution> + + <!-- compile and execute the TCK via the embedded Ant runtime --> + <execution> + <id>run-tck</id> + <phase>integration-test</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <target> + <!-- the TCK distribution ships pre-compiled test classes, + so the 'build' target is not needed (and its sources + are not fully included anyway) --> + <ant antfile="${tck.home}/build.xml" target="run" useNativeBasedir="true" inheritall="false"> + <property name="failOnError" value="false"/> + <!-- pin JavaTest batch concurrency so at most one forked + test JVM runs at a time; the presetdef splices + ${tests.arg} right before -runtests --> + <property name="tests.arg" value="-concurrency 1"/> + </ant> + </target> + </configuration> + </execution> + + <!-- always stop James, even after TCK failures --> + <execution> + <id>stop-james</id> + <phase>post-integration-test</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <target> + <java classname="org.apache.geronimo.mail.tck.JamesTckServer" fork="true" failonerror="false"> + <classpath refid="maven.compile.classpath"/> + <sysproperty key="tck.control.port" value="${tck.control.port}"/> + <arg value="--stop"/> + </java> + </target> + </configuration> + </execution> + + <!-- gate: parse the JavaTest summary --> + <execution> + <id>verify-tck</id> + <phase>verify</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <target> + <available file="${tck.home}/JTreport/text/summary.txt" property="tck.summary.present"/> + <fail message="TCK produced no report at ${tck.home}/JTreport" unless="tck.summary.present"/> + <loadfile property="tck.summary" srcFile="${tck.home}/JTreport/text/summary.txt"/> + <resourcecount property="tck.passed.count"> + <tokens> + <concat> + <filterchain> + <linecontainsregexp> + <regexp pattern="Passed\."/> + </linecontainsregexp> + </filterchain> + <file file="${tck.home}/JTreport/text/summary.txt"/> + </concat> + </tokens> + </resourcecount> + <condition property="tck.has.failures"> + <or> + <matches string="${tck.summary}" pattern="Failed\."/> + <matches string="${tck.summary}" pattern="Error\."/> + </or> + </condition> + <condition property="tck.ignore.failures"> + <istrue value="${tck.failIgnore}"/> + </condition> + <echo message="Jakarta Mail TCK: ${tck.passed.count} tests passed; report: ${tck.home}/JTreport"/> + <fail message="Jakarta Mail TCK reported failures/errors, see ${tck.home}/JTreport"> + <condition> + <and> + <isset property="tck.has.failures"/> + <not> + <isset property="tck.ignore.failures"/> + </not> + </and> + </condition> + </fail> + <fail message="Jakarta Mail TCK passed zero tests - setup is broken"> + <condition> + <equals arg1="${tck.passed.count}" arg2="0"/> + </condition> + </fail> + </target> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --git a/geronimo-mail_2.1_tck/src/main/java/org/apache/geronimo/mail/tck/JamesTckServer.java b/geronimo-mail_2.1_tck/src/main/java/org/apache/geronimo/mail/tck/JamesTckServer.java new file mode 100644 index 0000000..d44c4a6 --- /dev/null +++ b/geronimo-mail_2.1_tck/src/main/java/org/apache/geronimo/mail/tck/JamesTckServer.java @@ -0,0 +1,380 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.mail.tck; + +import java.io.ByteArrayOutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.time.Clock; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import jakarta.mail.internet.MimeMessage; + +import org.apache.commons.configuration2.BaseHierarchicalConfiguration; +import org.apache.james.UserEntityValidator; +import org.apache.james.core.Domain; +import org.apache.james.core.MailAddress; +import org.apache.james.core.Username; +import org.apache.james.dnsservice.api.DNSService; +import org.apache.james.domainlist.api.DomainList; +import org.apache.james.domainlist.lib.DomainListConfiguration; +import org.apache.james.domainlist.memory.MemoryDomainList; +import org.apache.james.filesystem.api.FileSystem; +import org.apache.james.imap.encode.main.DefaultImapEncoderFactory; +import org.apache.james.imap.main.DefaultImapDecoderFactory; +import org.apache.james.imap.processor.fetch.FetchProcessor; +import org.apache.james.imap.processor.main.DefaultImapProcessorFactory; +import org.apache.james.imapserver.netty.IMAPServer; +import org.apache.james.imapserver.netty.ImapMetrics; +import org.apache.james.lifecycle.api.LifecycleUtil; +import org.apache.james.mailbox.Authorizator; +import org.apache.james.mailbox.MailboxManager; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageManager; +import org.apache.james.mailbox.inmemory.InMemoryMailboxManager; +import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.store.StoreSubscriptionManager; +import org.apache.james.mailrepository.api.MailRepositoryStore; +import org.apache.james.mailrepository.api.Protocol; +import org.apache.james.mailrepository.memory.MailRepositoryStoreConfiguration; +import org.apache.james.mailrepository.memory.MemoryMailRepository; +import org.apache.james.mailrepository.memory.MemoryMailRepositoryStore; +import org.apache.james.mailrepository.memory.MemoryMailRepositoryUrlStore; +import org.apache.james.mailrepository.memory.SimpleMailRepositoryLoader; +import org.apache.james.metrics.api.MetricFactory; +import org.apache.james.metrics.api.NoopGaugeRegistry; +import org.apache.james.metrics.tests.RecordingMetricFactory; +import org.apache.james.protocols.lib.mock.MockProtocolHandlerLoader; +import org.apache.james.queue.api.MailQueue; +import org.apache.james.queue.api.MailQueueFactory; +import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory; +import org.apache.james.queue.memory.MemoryMailQueueFactory; +import org.apache.james.rrt.api.AliasReverseResolver; +import org.apache.james.rrt.api.CanSendFrom; +import org.apache.james.rrt.api.RecipientRewriteTable; +import org.apache.james.rrt.api.RecipientRewriteTableConfiguration; +import org.apache.james.rrt.lib.AliasReverseResolverImpl; +import org.apache.james.rrt.lib.CanSendFromImpl; +import org.apache.james.rrt.memory.MemoryRecipientRewriteTable; +import org.apache.james.server.core.filesystem.FileSystemImpl; +import org.apache.james.smtpserver.netty.SMTPServer; +import org.apache.james.smtpserver.netty.SmtpMetricsImpl; +import org.apache.james.user.api.UsersRepository; +import org.apache.james.user.api.UsersRepositoryException; +import org.apache.james.user.memory.MemoryUsersRepository; +import org.apache.mailet.Mail; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.inject.TypeLiteral; +import com.google.inject.name.Names; + +import reactor.core.Disposable; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + +/** + * Standalone embedded Apache James server used as the mail server for the + * Jakarta Mail TCK: SMTP + IMAP, domain james.local, user [email protected]. + * Started by the mail-tck module at pre-integration-test and stopped through a + * loopback control socket at post-integration-test ("--stop"). + */ +public final class JamesTckServer { + + public static final String DOMAIN = "james.local"; + public static final String USER = "user01@" + DOMAIN; + public static final String PASSWORD = "1234"; + + private final int smtpPort; + private final int imapPort; + + private SMTPServer smtpServer; + private IMAPServer imapServer; + private MemoryDomainList domainList; + private MemoryUsersRepository usersRepository; + private FileSystemImpl fileSystem; + private MockProtocolHandlerLoader protocolHandlerChain; + private InMemoryIntegrationResources memoryIntegrationResources; + private InMemoryMailboxManager mailboxManager; + private MemoryMailQueueFactory queueFactory; + private MemoryMailQueueFactory.MemoryCacheableMailQueue queue; + private Disposable fetcher; + + public JamesTckServer(final int smtpPort, final int imapPort) { + this.smtpPort = smtpPort; + this.imapPort = imapPort; + } + + public static void main(final String[] args) throws Exception { + final int controlPort = Integer.getInteger("tck.control.port", 11300); + + if (args.length > 0 && "--stop".equals(args[0])) { + try (Socket socket = new Socket(InetAddress.getLoopbackAddress(), controlPort)) { + socket.getOutputStream().write('q'); + socket.getOutputStream().flush(); + } + return; + } + + final JamesTckServer server = new JamesTckServer( + Integer.getInteger("tck.smtp.port", 1025), + Integer.getInteger("tck.imap.port", 1143)); + server.start(); + System.out.println("TCK James server ready (SMTP=" + server.smtpPort + ", IMAP=" + server.imapPort + + ", user=" + USER + ")"); + + // block until a stop request arrives on the control port + try (ServerSocket control = new ServerSocket(controlPort, 1, InetAddress.getLoopbackAddress())) { + try (Socket accepted = control.accept()) { + accepted.getInputStream().read(); + } + } + server.stop(); + } + + public void start() throws Exception { + final AlterableDNSServer dnsServer = new AlterableDNSServer(); + + domainList = new MemoryDomainList(dnsServer); + domainList.configure(DomainListConfiguration.DEFAULT); + if (!domainList.containsDomain(Domain.of(DOMAIN))) { + domainList.addDomain(Domain.of(DOMAIN)); + } + + usersRepository = MemoryUsersRepository.withVirtualHosting(domainList); + usersRepository.addUser(Username.of(USER), PASSWORD); + + memoryIntegrationResources = InMemoryIntegrationResources.builder() + .authenticator((userid, passwd) -> { + try { + return usersRepository.test(userid, passwd.toString()); + } catch (final UsersRepositoryException e) { + e.printStackTrace(); + return Optional.empty(); + } + }) + .fakeAuthorizator() + .inVmEventBus() + .defaultAnnotationLimits() + .defaultMessageParser() + .scanningSearchIndex() + .noPreDeletionHooks() + .storeQuotaManager() + .build(); + mailboxManager = memoryIntegrationResources.getMailboxManager(); + + fileSystem = FileSystemImpl.forTestingWithConfigurationFromClasspath(); + + final MemoryMailRepositoryUrlStore urlStore = new MemoryMailRepositoryUrlStore(); + final MailRepositoryStoreConfiguration storeConfiguration = MailRepositoryStoreConfiguration.forItems( + new MailRepositoryStoreConfiguration.Item( + ImmutableList.of(new Protocol("memory")), + MemoryMailRepository.class.getName(), + new BaseHierarchicalConfiguration())); + final MemoryMailRepositoryStore mailRepositoryStore = + new MemoryMailRepositoryStore(urlStore, new SimpleMailRepositoryLoader(), storeConfiguration); + mailRepositoryStore.init(); + + final MemoryRecipientRewriteTable rewriteTable = new MemoryRecipientRewriteTable(); + rewriteTable.setConfiguration(RecipientRewriteTableConfiguration.DEFAULT_ENABLED); + final AliasReverseResolver aliasReverseResolver = new AliasReverseResolverImpl(rewriteTable); + final CanSendFrom canSendFrom = new CanSendFromImpl(aliasReverseResolver); + + queueFactory = new MemoryMailQueueFactory(new RawMailQueueItemDecoratorFactory(), Clock.systemUTC()); + queue = queueFactory.createQueue(MailQueueFactory.SPOOL); + + protocolHandlerChain = MockProtocolHandlerLoader.builder() + .put(binder -> binder.bind(DomainList.class).toInstance(domainList)) + .put(binder -> binder.bind(Clock.class).toInstance(Clock.systemUTC())) + .put(binder -> binder.bind(new TypeLiteral<MailQueueFactory<?>>() {}).toInstance(queueFactory)) + .put(binder -> binder.bind(RecipientRewriteTable.class).toInstance(rewriteTable)) + .put(binder -> binder.bind(CanSendFrom.class).toInstance(canSendFrom)) + .put(binder -> binder.bind(FileSystem.class).toInstance(fileSystem)) + .put(binder -> binder.bind(MailRepositoryStore.class).toInstance(mailRepositoryStore)) + .put(binder -> binder.bind(DNSService.class).toInstance(dnsServer)) + .put(binder -> binder.bind(UsersRepository.class).toInstance(usersRepository)) + .put(binder -> binder.bind(MailboxManager.class).annotatedWith(Names.named("mailboxmanager")).toInstance(mailboxManager)) + .put(binder -> binder.bind(MetricFactory.class).toInstance(new RecordingMetricFactory())) + .put(binder -> binder.bind(UserEntityValidator.class).toInstance(UserEntityValidator.NOOP)) + .put(binder -> binder.bind(Authorizator.class).toInstance((userId, otherUserId) -> Authorizator.AuthorizationState.ALLOWED)) + .build(); + + final RecordingMetricFactory metricFactory = new RecordingMetricFactory(); + + smtpServer = new SMTPServer(new SmtpMetricsImpl(metricFactory)); + smtpServer.setDnsService(dnsServer); + smtpServer.setFileSystem(fileSystem); + smtpServer.setProtocolHandlerLoader(protocolHandlerChain); + + imapServer = new IMAPServer( + new DefaultImapDecoderFactory().buildImapDecoder(), + new DefaultImapEncoderFactory().buildImapEncoder(), + DefaultImapProcessorFactory.createXListSupportingProcessor( + mailboxManager, + memoryIntegrationResources.getEventBus(), + new StoreSubscriptionManager(mailboxManager.getMapperFactory(), + mailboxManager.getMapperFactory(), + mailboxManager.getEventBus()), + null, + memoryIntegrationResources.getQuotaManager(), + memoryIntegrationResources.getQuotaRootResolver(), + metricFactory, + FetchProcessor.LocalCacheConfiguration.DEFAULT), + new ImapMetrics(metricFactory), + new NoopGaugeRegistry(), + ImmutableSet.of()); + imapServer.setFileSystem(fileSystem); + + // make sure the INBOX exists before any SMTP delivery + final MailboxSession session = mailboxManager.createSystemSession(Username.of(USER)); + final MailboxPath inbox = MailboxPath.inbox(session); + if (!Mono.from(mailboxManager.mailboxExists(inbox, session)).block()) { + mailboxManager.createMailbox(inbox, session); + } + + fetcher = Flux.from(queue.deQueue()) + .publishOn(Schedulers.boundedElastic()) + .subscribe(this::deliver); + + final BaseHierarchicalConfiguration smtpConfig = serverConfig(smtpPort); + smtpConfig.addProperty("authorizedAddresses", "127.0.0.0/8"); + smtpConfig.addProperty("auth.requireSSL", false); + smtpConfig.addProperty("verifyIdentity", false); + smtpConfig.addProperty("handlerchain.[@coreHandlersPackage]", org.apache.james.smtpserver.CoreCmdHandlerLoader.class.getName()); + + final BaseHierarchicalConfiguration imapConfig = serverConfig(imapPort); + imapConfig.addProperty("plainAuthDisallowed", false); + + smtpServer.configure(smtpConfig); + imapServer.configure(imapConfig); + + smtpServer.init(); + imapServer.init(); + } + + private static BaseHierarchicalConfiguration serverConfig(final int port) { + final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration(); + config.addProperty("[@enabled]", true); + config.addProperty("bind", "0.0.0.0:" + port); + config.addProperty("connectiontimeout", "360000"); + config.addProperty("helloName", DOMAIN); + config.addProperty("helloName.[@autodetect]", false); + config.addProperty("gracefulShutdown", false); + return config; + } + + /** + * Local delivery: append the dequeued mail to the INBOX of every local + * recipient. The dequeued mail is a queue-side copy owned by the consumer + * and must be disposed (see the MailQueue contract / JamesMailSpooler). + */ + private void deliver(final MailQueue.MailQueueItem item) { + final Mail mail = item.getMail(); + try { + final MimeMessage msg = mail.getMessage(); + final ByteArrayOutputStream bout = new ByteArrayOutputStream(); + msg.writeTo(bout); + final byte[] content = bout.toByteArray(); + + for (final MailAddress recipient : mail.getRecipients()) { + final Username username = Username.of(recipient.asString()); + final MailboxSession session = mailboxManager.createSystemSession(username); + final MailboxPath inbox = MailboxPath.inbox(session); + if (!Mono.from(mailboxManager.mailboxExists(inbox, session)).block()) { + mailboxManager.createMailbox(inbox, session); + } + final MessageManager mailbox = mailboxManager.getMailbox(inbox, session); + mailbox.appendMessage(MessageManager.AppendCommand.builder().recent().build(content), session); + } + item.done(MailQueue.MailQueueItem.CompletionStatus.SUCCESS); + } catch (final Exception e) { + e.printStackTrace(); + try { + item.done(MailQueue.MailQueueItem.CompletionStatus.REJECT); + } catch (final Exception ignored) { + // nothing left to do + } + } finally { + LifecycleUtil.dispose(mail); + } + } + + public void stop() throws Exception { + if (fetcher != null) { + fetcher.dispose(); + } + if (queue != null) { + queue.close(); + } + if (protocolHandlerChain != null) { + protocolHandlerChain.dispose(); + } + if (imapServer != null) { + imapServer.destroy(); + } + if (smtpServer != null) { + smtpServer.destroy(); + } + } + + /** + * Minimal DNS mock: everything the TCK talks to is local. + */ + private static final class AlterableDNSServer implements DNSService { + + @Override + public Collection<String> findMXRecords(final String hostname) { + return new ArrayList<>(); + } + + @Override + public Collection<InetAddress> getAllByName(final String host) throws UnknownHostException { + return ImmutableList.of(getByName(host)); + } + + @Override + public InetAddress getByName(final String host) throws UnknownHostException { + if (DOMAIN.equals(host) || "localhost".equals(host) || "127.0.0.1".equals(host) || "0.0.0.0".equals(host)) { + return InetAddress.getByName("127.0.0.1"); + } + return InetAddress.getByName(host); + } + + @Override + public Collection<String> findTXTRecords(final String hostname) { + return new ArrayList<>(); + } + + @Override + public String getHostName(final InetAddress addr) { + return addr.getHostName(); + } + + @Override + public InetAddress getLocalHost() throws UnknownHostException { + return InetAddress.getLocalHost(); + } + } + +} diff --git a/geronimo-mail_2.1_tck/src/tck/geronimo.jtx b/geronimo-mail_2.1_tck/src/tck/geronimo.jtx new file mode 100644 index 0000000..2186494 --- /dev/null +++ b/geronimo-mail_2.1_tck/src/tck/geronimo.jtx @@ -0,0 +1,167 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Jakarta Mail TCK 2.1.1 tests that currently FAIL against geronimo-mail. +# This list is appended to the TCK's shipped lib/ts.jtx by the tck profile, +# so the gate stays green while the underlying defects are fixed one by one: +# fix the defect, delete its lines here, run `mvn verify -Ptck` to confirm. +# +# Baseline recorded 2026-07-18 against Jakarta Mail TCK 2.1.1 / James 3.9.0. +# + +# IMAP APPEND continuation deadlock: the client blocks forever waiting for the +# server's literal continuation (see tck.adoc "KNOWN ISSUE"). Every test below +# invokes Folder.appendMessages through the geronimo IMAP client. +javasoft/sqe/tests/jakarta/mail/event/FolderEvent/testlist.html#addMsgCntList_Test +javasoft/sqe/tests/jakarta/mail/exception/testlist.html#illegalWriteException_Test +javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#appendMessages_Test +javasoft/sqe/tests/jakarta/mail/UIDFolder/testlist.html#getUID_Test +javasoft/sqe/tests/jakarta/mail/UIDFolder/testlist.html#getUIDNext_Test + +# API signature verification: needs a dedicated sigtest setup (signature +# records, sigtest.jar invocation) and is out of scope for the functional +# gate; currently reports 18 signature mismatches in the spec classes that +# should be reviewed separately. +SignatureTest.html + +# Remaining baseline failures from the first full run (191 passed / 125 failed). +# Large blocks share single root causes: +# - Message/Multipart/Folder blocks: IMAPFolder.open (SELECT) rejected by +# James 3.9 (CommandFailedException), plus folder create/rename defects +javasoft/sqe/tests/jakarta/mail/event/FolderEvent/testlist.html#addFolderListener_Test +javasoft/sqe/tests/jakarta/mail/event/FolderEvent/testlist.html#addMsgChangeList_Test +javasoft/sqe/tests/jakarta/mail/exception/testlist.html#folderNotFoundExp_Test +javasoft/sqe/tests/jakarta/mail/exception/testlist.html#msgRemoveExp_Test +javasoft/sqe/tests/jakarta/mail/FetchProfile/testlist.html#add_Test +javasoft/sqe/tests/jakarta/mail/FetchProfile/testlist.html#contains_Test +javasoft/sqe/tests/jakarta/mail/Flags/testlist.html#retainAll_Test +javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#create_Test +javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#delete_Test +javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#fetch_Test +javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#getPermanentFlags_Test +javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#getType_Test +javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#list_Test +javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#listSubscribed_Test +javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#renameTo_Test +javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#search_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetAddress/testlist.html#getType_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetAddress/testlist.html#internetAddress_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetAddress/testlist.html#setAddress_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetAddress/testlist.html#unicode_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getAllHeaderLines_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getAllHeaders_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getMatchHeadLines_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getMatchingHeaders_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getNonMatchHead_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getNonMatchHeadLines_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#InternetHeaders_Test +javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#load_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#attachFile_saveFile_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getAllHeaderLines_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getAllHeaders_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getContent_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getContentID_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getContentLanguage_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getContentMD5_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getContentType_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getDataHandler_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getDescription_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getDisposition_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getEncoding_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getFileName_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getHeader_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getLineCount_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getMatchHeadLines_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getMatchingHeaders_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getNonMatchHead_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getNonMatchHeadLines_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getSize_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#isMimeType_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#mimeBodyPart_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#setContentLanguage_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#setFileNameEncoded_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#writeTo_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#addRecipients_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getAllHeaderLines_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getContentID_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getContentLanguage_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getContentMD5_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getEncoding_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getHeader_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getInputStream_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getMatchHeadLines_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getNonMatchHeadLines_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getSentDate_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#MimeMessage_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#setDataHandler_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#setFileNameEncoded_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#setSentDate_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#unicode_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#updateHeaders_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#writeTo_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMultipart/testlist.html#getBodyPart_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMultipart/testlist.html#getCount_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMultipart/testlist.html#getsetPreamble_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeMultipart/testlist.html#writeTo_Test +javasoft/sqe/tests/jakarta/mail/internet/MimePartDataSource/testlist.html#getContentType_Test +javasoft/sqe/tests/jakarta/mail/internet/MimePartDataSource/testlist.html#getInputStream_Test +javasoft/sqe/tests/jakarta/mail/internet/MimePartDataSource/testlist.html#getName_Test +javasoft/sqe/tests/jakarta/mail/internet/MimePartDataSource/testlist.html#getOutputStream_Test +javasoft/sqe/tests/jakarta/mail/internet/MimePartDataSource/testlist.html#mimePartDataSource_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeUtility/testlist.html#decodeText_Test +javasoft/sqe/tests/jakarta/mail/internet/MimeUtility/testlist.html#foldUnfold_Test +javasoft/sqe/tests/jakarta/mail/internet/ParameterList/testlist.html#set_withDecodeStrict_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getAllHeaders_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getContent_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getContentType_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getDataHandler_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getDescription_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getDisposition_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getFileName_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getFlags_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getFolder_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getFrom_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getHeader_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getInputStream_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getMatchingHeaders_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getMessageNumber_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getNonMatchingHeaders_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getReceivedDate_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getReplyTo_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getSize_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getSubject_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#isExpunged_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#isSet_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#match_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#setFileName_Test +javasoft/sqe/tests/jakarta/mail/Message/testlist.html#setFileNameTest_encodeFalse_decodeTrue +javasoft/sqe/tests/jakarta/mail/Multipart/testlist.html#getBodyPart_Test +javasoft/sqe/tests/jakarta/mail/Multipart/testlist.html#getContentType_Test +javasoft/sqe/tests/jakarta/mail/Multipart/testlist.html#getCount_Test +javasoft/sqe/tests/jakarta/mail/Multipart/testlist.html#writeTo_Test +javasoft/sqe/tests/jakarta/mail/search/AndTerm/testlist.html#andterm_Test +javasoft/sqe/tests/jakarta/mail/search/BodyTerm/testlist.html#bodyterm_Test +javasoft/sqe/tests/jakarta/mail/search/FlagTerm/testlist.html#flagterm_Test +javasoft/sqe/tests/jakarta/mail/search/FromTerm/testlist.html#fromterm_Test +javasoft/sqe/tests/jakarta/mail/search/HeaderTerm/testlist.html#headerterm_Test +javasoft/sqe/tests/jakarta/mail/search/MessageIDTerm/testlist.html#messageidterm_Test +javasoft/sqe/tests/jakarta/mail/search/MessageNumberTerm/testlist.html#messagenumberterm_Test +javasoft/sqe/tests/jakarta/mail/search/NotTerm/testlist.html#notterm_Test +javasoft/sqe/tests/jakarta/mail/search/OrTerm/testlist.html#orterm_Test +javasoft/sqe/tests/jakarta/mail/search/ReceivedDateTerm/testlist.html#receiveddateterm_Test +javasoft/sqe/tests/jakarta/mail/search/SentDateTerm/testlist.html#sentdateterm_Test +javasoft/sqe/tests/jakarta/mail/search/SizeTerm/testlist.html#sizeterm_Test +javasoft/sqe/tests/jakarta/mail/search/SubjectTerm/testlist.html#subjectterm_Test diff --git a/pom.xml b/pom.xml index 1df2ebb..964b36a 100644 --- a/pom.xml +++ b/pom.xml @@ -91,6 +91,7 @@ <modules> <module>geronimo-mail_2.1_spec</module> <module>geronimo-mail_2.1_impl</module> + <module>geronimo-mail_2.1_tck</module> </modules> </project>