Gate integration tests of unrebuilt Enterprise features behind pending-rebuild; record what v0.16.22 proved

This commit is contained in:
2026-09-18 10:29:20 -07:00
parent 0c6b3dffc0
commit 0db5ab9155
6 changed files with 49 additions and 4 deletions
+21
View File
@@ -108,6 +108,27 @@ repository. Instead:
disabled or replaced on `main` before the repository is ever pushed disabled or replaced on `main` before the repository is ever pushed
anywhere that runs them. anywhere that runs them.
### 2.2b What the first import proved (v0.16.22, 2026-09-18)
- The stripped tree builds (`cargo build -p stalwart`, 3 min 14 s on 16
cores) and the binary runs. There are 6 warnings, all unused imports left
where Enterprise snippets were cut out.
- Every crate's unit tests pass: 263 passed, 0 failed, 2 ignored. They build
with the integration crate in the build, because that's what switches on the
test features the unit tests rely on, and run from each crate's own directory
(`dav-proto` loads fixtures by relative path).
- The integration crate (`tests/`) compiles once the shared tests of
unrebuilt features are gated behind its `pending-rebuild` feature, off by
default: the OIDC-directory, tenant and archiving suites; the four
telemetry suites (alerts, metrics, tracing, webhooks); and the LLM parts of
the spam-filter suite. Each gate carries an `inbuxa: pending-rebuild` comment
and comes off when its feature is rebuilt.
- Those gated suites are shared, AGPL test code that exercises Enterprise
behavior. That makes them a clean source for the feature specs, and ready-made
acceptance tests for the rebuilds.
- Not yet run: the integration suite itself, which needs its database
services, and a first boot of the binary (SPEC.md §6).
Layout on `main`: the server source at the root, exactly as upstream lays it Layout on `main`: the server source at the root, exactly as upstream lays it
out (so merges line up), the specs under `docs/spec/`, strip reports under out (so merges line up), the specs under `docs/spec/`, strip reports under
`docs/fork/`, and the fork tooling under `tools/fork/`. Upstream has no `docs/fork/`, and the fork tooling under `tools/fork/`. Upstream has no
+4
View File
@@ -4,6 +4,10 @@ version = "0.16.22"
edition = "2024" edition = "2024"
[features] [features]
# Tests for Enterprise features the fork hasn't rebuilt yet. Off by default, so
# the crate compiles without them. Each gate is marked `inbuxa: pending-rebuild`,
# and comes off when its feature's rebuild lands.
pending-rebuild = []
#default = ["sqlite", "postgres", "mysql", "rocks", "s3", "redis", "nats", "azure", "foundationdb"] #default = ["sqlite", "postgres", "mysql", "rocks", "s3", "redis", "nats", "azure", "foundationdb"]
#default = ["sqlite", "postgres", "mysql", "rocks", "s3", "redis", "foundationdb"] #default = ["sqlite", "postgres", "mysql", "rocks", "s3", "redis", "foundationdb"]
default = ["rocks", "sqlite"] default = ["rocks", "sqlite"]
+1
View File
@@ -15,6 +15,7 @@ pub mod unavailable;
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
pub async fn directory_tests() { pub async fn directory_tests() {
ldap::test().await; ldap::test().await;
#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/
oidc::test().await; oidc::test().await;
unavailable::test().await; unavailable::test().await;
discovery::test().await; discovery::test().await;
+13 -4
View File
@@ -4,6 +4,12 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/ */
#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/
use common::enterprise::llm::{
ChatCompletionChoice, ChatCompletionRequest, ChatCompletionResponse, Message,
};
#[cfg(feature = "pending-rebuild")]
use spam_filter::analysis::llm::SpamFilterAnalyzeLlm;
use crate::utils::{ use crate::utils::{
dns::DnsCache, dns::DnsCache,
http_server::{HttpMessage, spawn_mock_http_server}, http_server::{HttpMessage, spawn_mock_http_server},
@@ -14,9 +20,6 @@ use common::{
Server, Server,
auth::{AccountCache, AccountInfo}, auth::{AccountCache, AccountInfo},
config::mailstore::spamfilter::SpamFilterAction, config::mailstore::spamfilter::SpamFilterAction,
enterprise::llm::{
ChatCompletionChoice, ChatCompletionRequest, ChatCompletionResponse, Message,
},
}; };
use http_proto::{JsonResponse, ToHttpResponse}; use http_proto::{JsonResponse, ToHttpResponse};
use hyper::Method; use hyper::Method;
@@ -46,7 +49,7 @@ use spam_filter::{
dmarc::SpamFilterAnalyzeDmarc, domain::SpamFilterAnalyzeDomain, dmarc::SpamFilterAnalyzeDmarc, domain::SpamFilterAnalyzeDomain,
ehlo::SpamFilterAnalyzeEhlo, from::SpamFilterAnalyzeFrom, ehlo::SpamFilterAnalyzeEhlo, from::SpamFilterAnalyzeFrom,
headers::SpamFilterAnalyzeHeaders, html::SpamFilterAnalyzeHtml, init::SpamFilterInit, headers::SpamFilterAnalyzeHeaders, html::SpamFilterAnalyzeHtml, init::SpamFilterInit,
ip::SpamFilterAnalyzeIp, llm::SpamFilterAnalyzeLlm, messageid::SpamFilterAnalyzeMid, ip::SpamFilterAnalyzeIp, messageid::SpamFilterAnalyzeMid,
mime::SpamFilterAnalyzeMime, pyzor::SpamFilterAnalyzePyzor, mime::SpamFilterAnalyzeMime, pyzor::SpamFilterAnalyzePyzor,
received::SpamFilterAnalyzeReceived, recipient::SpamFilterAnalyzeRecipient, received::SpamFilterAnalyzeReceived, recipient::SpamFilterAnalyzeRecipient,
replyto::SpamFilterAnalyzeReplyTo, rules::SpamFilterAnalyzeRules, replyto::SpamFilterAnalyzeReplyTo, rules::SpamFilterAnalyzeRules,
@@ -220,6 +223,7 @@ async fn antispam() {
} }
// Spawn mock OpenAI server // Spawn mock OpenAI server
#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/
let _tx = spawn_mock_http_server( let _tx = spawn_mock_http_server(
&test, &test,
Arc::new(|req: HttpMessage| { Arc::new(|req: HttpMessage| {
@@ -289,6 +293,10 @@ async fn antispam() {
{ {
continue; continue;
} }
// inbuxa: pending-rebuild. The LLM case needs the AI classifier rebuilt.
if cfg!(not(feature = "pending-rebuild")) && test_name == "llm" {
continue;
}
println!("===== {test_name} ====="); println!("===== {test_name} =====");
let contents = fs::read_to_string(base_path.join(format!("{test_name}.test"))).unwrap(); let contents = fs::read_to_string(base_path.join(format!("{test_name}.test"))).unwrap();
@@ -657,6 +665,7 @@ async fn antispam() {
"pyzor" => { "pyzor" => {
server.spam_filter_analyze_pyzor(&mut spam_ctx).await; server.spam_filter_analyze_pyzor(&mut spam_ctx).await;
} }
#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/
"llm" => { "llm" => {
server.spam_filter_analyze_llm(&mut spam_ctx).await; server.spam_filter_analyze_llm(&mut spam_ctx).await;
} }
+2
View File
@@ -60,6 +60,7 @@ pub async fn system_tests() {
authentication::test(&test).await; authentication::test(&test).await;
oidc::test(&mut test).await; oidc::test(&mut test).await;
authorization::test(&mut test).await; authorization::test(&mut test).await;
#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/multi-tenancy.md
tenant::test(&mut test).await; tenant::test(&mut test).await;
security::test(&mut test).await; security::test(&mut test).await;
quota::test(&mut test).await; quota::test(&mut test).await;
@@ -67,6 +68,7 @@ pub async fn system_tests() {
delivery::test(&mut test).await; delivery::test(&mut test).await;
crypto::test(&mut test).await; crypto::test(&mut test).await;
antispam::test(&mut test).await; antispam::test(&mut test).await;
#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/undelete.md
archiving::test(&mut test).await; archiving::test(&mut test).await;
task::test(&mut test).await; task::test(&mut test).await;
+8
View File
@@ -4,9 +4,13 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/ */
#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/
pub mod alerts; pub mod alerts;
#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/
pub mod metrics; pub mod metrics;
#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/
pub mod tracing; pub mod tracing;
#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/
pub mod webhooks; pub mod webhooks;
use crate::utils::server::TestServerBuilder; use crate::utils::server::TestServerBuilder;
@@ -55,9 +59,13 @@ pub async fn telemetry_tests() {
.await; .await;
test.insert_account(admin); test.insert_account(admin);
#[cfg(feature = "pending-rebuild")]
alerts::test(&test).await; alerts::test(&test).await;
#[cfg(feature = "pending-rebuild")]
metrics::test(&test).await; metrics::test(&test).await;
#[cfg(feature = "pending-rebuild")]
tracing::test(&test).await; tracing::test(&test).await;
#[cfg(feature = "pending-rebuild")]
webhooks::test(&test).await; webhooks::test(&test).await;
if test.is_reset() { if test.is_reset() {