diff --git a/docs/spec/SPEC.md b/docs/spec/SPEC.md index 7d10911..d77fdcb 100644 --- a/docs/spec/SPEC.md +++ b/docs/spec/SPEC.md @@ -108,6 +108,27 @@ repository. Instead: disabled or replaced on `main` before the repository is ever pushed 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 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 diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 9681328..114b1ea 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -4,6 +4,10 @@ version = "0.16.22" edition = "2024" [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", "foundationdb"] default = ["rocks", "sqlite"] diff --git a/tests/src/directory/mod.rs b/tests/src/directory/mod.rs index a03234b..d34f375 100644 --- a/tests/src/directory/mod.rs +++ b/tests/src/directory/mod.rs @@ -15,6 +15,7 @@ pub mod unavailable; #[tokio::test(flavor = "multi_thread")] pub async fn directory_tests() { ldap::test().await; + #[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/ oidc::test().await; unavailable::test().await; discovery::test().await; diff --git a/tests/src/smtp/inbound/antispam.rs b/tests/src/smtp/inbound/antispam.rs index 97a03d9..587f2c5 100644 --- a/tests/src/smtp/inbound/antispam.rs +++ b/tests/src/smtp/inbound/antispam.rs @@ -4,6 +4,12 @@ * 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::{ dns::DnsCache, http_server::{HttpMessage, spawn_mock_http_server}, @@ -14,9 +20,6 @@ use common::{ Server, auth::{AccountCache, AccountInfo}, config::mailstore::spamfilter::SpamFilterAction, - enterprise::llm::{ - ChatCompletionChoice, ChatCompletionRequest, ChatCompletionResponse, Message, - }, }; use http_proto::{JsonResponse, ToHttpResponse}; use hyper::Method; @@ -46,7 +49,7 @@ use spam_filter::{ dmarc::SpamFilterAnalyzeDmarc, domain::SpamFilterAnalyzeDomain, ehlo::SpamFilterAnalyzeEhlo, from::SpamFilterAnalyzeFrom, headers::SpamFilterAnalyzeHeaders, html::SpamFilterAnalyzeHtml, init::SpamFilterInit, - ip::SpamFilterAnalyzeIp, llm::SpamFilterAnalyzeLlm, messageid::SpamFilterAnalyzeMid, + ip::SpamFilterAnalyzeIp, messageid::SpamFilterAnalyzeMid, mime::SpamFilterAnalyzeMime, pyzor::SpamFilterAnalyzePyzor, received::SpamFilterAnalyzeReceived, recipient::SpamFilterAnalyzeRecipient, replyto::SpamFilterAnalyzeReplyTo, rules::SpamFilterAnalyzeRules, @@ -220,6 +223,7 @@ async fn antispam() { } // Spawn mock OpenAI server + #[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/ let _tx = spawn_mock_http_server( &test, Arc::new(|req: HttpMessage| { @@ -289,6 +293,10 @@ async fn antispam() { { 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} ====="); let contents = fs::read_to_string(base_path.join(format!("{test_name}.test"))).unwrap(); @@ -657,6 +665,7 @@ async fn antispam() { "pyzor" => { server.spam_filter_analyze_pyzor(&mut spam_ctx).await; } + #[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/ "llm" => { server.spam_filter_analyze_llm(&mut spam_ctx).await; } diff --git a/tests/src/system/mod.rs b/tests/src/system/mod.rs index a287321..3eca1f1 100644 --- a/tests/src/system/mod.rs +++ b/tests/src/system/mod.rs @@ -60,6 +60,7 @@ pub async fn system_tests() { authentication::test(&test).await; oidc::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; security::test(&mut test).await; quota::test(&mut test).await; @@ -67,6 +68,7 @@ pub async fn system_tests() { delivery::test(&mut test).await; crypto::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; task::test(&mut test).await; diff --git a/tests/src/telemetry/mod.rs b/tests/src/telemetry/mod.rs index 86201fe..f75a680 100644 --- a/tests/src/telemetry/mod.rs +++ b/tests/src/telemetry/mod.rs @@ -4,9 +4,13 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ +#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/ pub mod alerts; +#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/ pub mod metrics; +#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/ pub mod tracing; +#[cfg(feature = "pending-rebuild")] // inbuxa: pending-rebuild, see docs/spec/features/ pub mod webhooks; use crate::utils::server::TestServerBuilder; @@ -55,9 +59,13 @@ pub async fn telemetry_tests() { .await; test.insert_account(admin); + #[cfg(feature = "pending-rebuild")] alerts::test(&test).await; + #[cfg(feature = "pending-rebuild")] metrics::test(&test).await; + #[cfg(feature = "pending-rebuild")] tracing::test(&test).await; + #[cfg(feature = "pending-rebuild")] webhooks::test(&test).await; if test.is_reset() {