v0.3.6-pre.003

This commit is contained in:
2026-09-01 11:58:38 +02:00
parent cb670952e8
commit f92c22d55a
12 changed files with 604 additions and 48 deletions

View File

@@ -1,10 +1,10 @@
// file: crates/ksp-job-api/tests/release_completeness.rs
// version: 1
// version: 2
//! Completeness canaries for the initial Job API foundation.
//! Completeness canaries for the current Job API foundation.
#[test]
fn pre_002_crate_root_export_inventory_is_exact() {
fn pre_003_crate_root_export_inventory_is_exact() {
let crate_root = include_str!("../src/lib.rs");
let mut actual = std::vec::Vec::new();
for line in crate_root.lines() {
@@ -18,6 +18,7 @@ fn pre_002_crate_root_export_inventory_is_exact() {
"pub use self::cancellation::JobCancellationToken;",
"pub use self::error::ERROR_CODE_JOB_ID_INVALID;",
"pub use self::error::ERROR_CODE_JOB_KIND_INVALID;",
"pub use self::error::ERROR_CODE_JOB_NOTIFICATION_SEQUENCE_EXHAUSTED;",
"pub use self::error::ERROR_CODE_JOB_TRANSITION_INVALID;",
"pub use self::identity::JobId;",
"pub use self::identity::JobKindCode;",
@@ -26,6 +27,10 @@ fn pre_002_crate_root_export_inventory_is_exact() {
"pub use self::lifecycle::JobCompletion;",
"pub use self::lifecycle::JobLifecycle;",
"pub use self::lifecycle::JobState;",
"pub use self::notification::JobNotification;",
"pub use self::notification::JobNotificationSequence;",
"pub use self::notification::JobSnapshotFuture;",
"pub use self::notification::JobSnapshotSource;",
"pub use ksp_core_lib::Error;",
"pub use ksp_core_lib::ErrorCode;",
"pub use ksp_core_lib::ErrorContext;",
@@ -38,7 +43,7 @@ fn pre_002_crate_root_export_inventory_is_exact() {
}
#[test]
fn pre_002_production_module_inventory_is_exact() -> std::io::Result<()> {
fn pre_003_production_module_inventory_is_exact() -> std::io::Result<()> {
let source_root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src");
let entries = match std::fs::read_dir(source_root) {
std::result::Result::Ok(value) => value,
@@ -66,35 +71,29 @@ fn pre_002_production_module_inventory_is_exact() -> std::io::Result<()> {
}
}
names.sort_unstable();
assert_eq!(names, std::vec!["cancellation.rs", "error.rs", "identity.rs", "lib.rs", "lifecycle.rs"]);
assert_eq!(names, std::vec!["cancellation.rs", "error.rs", "identity.rs", "lib.rs", "lifecycle.rs", "notification.rs"]);
return std::result::Result::Ok(());
}
#[test]
fn pre_002_surface_does_not_open_notifications_backfill_or_worker_contracts() {
fn pre_003_surface_opens_only_generic_notifications_without_backfill_or_worker_contracts() {
let sources = [
include_str!("../src/cancellation.rs"),
include_str!("../src/identity.rs"),
include_str!("../src/lib.rs"),
include_str!("../src/lifecycle.rs"),
include_str!("../src/notification.rs"),
];
for source in sources {
for forbidden in [
"JobNotification",
"JobNotificationSequence",
"JobSnapshot",
"JobSnapshotSource",
"BackfillRequest",
"WorkerControl",
"WorkerState",
"spawn(",
"RawTransaction",
"provider",
"endpoint",
] {
for forbidden in ["BackfillRequest", "WorkerControl", "WorkerState", "spawn(", "RawTransaction", "provider", "endpoint"] {
assert!(!source.contains(forbidden), "future or domain-specific Job contract leaked early: {forbidden}");
}
}
let notification_source = include_str!("../src/notification.rs");
assert!(notification_source.contains("pub struct JobNotification<S>"));
assert!(notification_source.contains("pub trait JobSnapshotSource"));
assert!(notification_source.contains("std::future::Future"));
assert!(!notification_source.contains("tokio::"));
let lifecycle_source = include_str!("../src/lifecycle.rs");
assert!(lifecycle_source.contains("#[derive(Eq, PartialEq)]\npub struct JobLifecycle"));
assert!(!lifecycle_source.contains("#[derive(Clone, Eq, PartialEq)]\npub struct JobLifecycle"));