lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

package_boundary.rs (12324B)


      1 use std::collections::BTreeSet;
      2 use std::fs;
      3 use std::path::Path;
      4 
      5 const MANIFEST: &str = include_str!("../Cargo.toml");
      6 const README: &str = include_str!("../README.md");
      7 const EXAMPLE: &str = include_str!("../examples/configure_transport.rs");
      8 const PUBLIC_API: &str =
      9     include_str!("../../../contracts/api_baselines/radroots_transport_nostr.txt");
     10 const ROOT: &str = include_str!("../src/lib.rs");
     11 const ERROR: &str = include_str!("../src/error.rs");
     12 const PROFILE: &str = include_str!("../src/profile.rs");
     13 const SINK: &str = include_str!("../src/sink.rs");
     14 const SUBSCRIPTION: &str = include_str!("../src/subscription.rs");
     15 
     16 #[test]
     17 fn manifest_and_root_match_the_governed_transport_boundary() {
     18     for required in [
     19         "name = \"radroots_transport_nostr\"",
     20         "version = \"0.1.0-alpha\"",
     21         "publish = [\"crates-io\"]",
     22         "[lib]\nname = \"radroots_transport_nostr\"",
     23     ] {
     24         assert!(
     25             MANIFEST.contains(required),
     26             "manifest is missing `{required}`"
     27         );
     28     }
     29     assert!(!MANIFEST.contains("[features]"));
     30     assert_eq!(
     31         radroots_dependency_keys(MANIFEST),
     32         BTreeSet::from([
     33             "radroots_event_codec",
     34             "radroots_nostr",
     35             "radroots_protocol",
     36             "radroots_transport",
     37         ])
     38     );
     39     assert_eq!(
     40         private_modules(ROOT),
     41         BTreeSet::from([
     42             "auth",
     43             "client",
     44             "cursor",
     45             "error",
     46             "exact_delivery",
     47             "profile",
     48             "relay",
     49             "sink",
     50             "socket_write",
     51             "source",
     52             "source_ingress",
     53             "source_wire",
     54             "status",
     55             "subscription"
     56         ])
     57     );
     58     for export in [
     59         "pub use client::{Config, NostrTransport, ReconnectBackoff};",
     60         "pub use cursor::RelayCursor;",
     61         "pub use error::Error;",
     62         "pub use profile::{",
     63         "pub use relay::{RelayUrl, RelayUrlPolicy};",
     64         "pub use sink::PreparedDelivery;",
     65     ] {
     66         assert!(ROOT.contains(export), "crate root is missing `{export}`");
     67     }
     68 }
     69 
     70 #[test]
     71 fn documentation_example_and_reviewed_api_baseline_are_complete() {
     72     for required in [
     73         "## Configure without connecting",
     74         "## Public surface",
     75         "## Relay and network security",
     76         "## Fetch, live subscription, delivery, and outcome behavior",
     77         "## Prepared delivery boundary",
     78         "## Deadlines, cancellation, and commit points",
     79         "## Serialization and diagnostics",
     80         "## Features and runtime requirements",
     81         "## Intended consumers",
     82         "radroots_crates_release_v1.toml",
     83         "examples/configure_transport.rs",
     84         "contracts/api_baselines/radroots_transport_nostr.txt",
     85         "Live subscriptions use the same explicit readable targets",
     86         "exact indexed single-letter tag",
     87         "Fetch reports `Complete` only after the exact subscription receives EOSE",
     88         "Deadline expiry is `Cancelled`",
     89         "exceeds the bounded inventory is `Partial`",
     90         "inclusive `since` timestamp",
     91         "permits at-least-once",
     92         "same-second events in relay arrival order",
     93         "never regresses the canonical target checkpoint",
     94         "upstream auto-close deadline",
     95         "adapter-owned worker",
     96         "validates the exact request, writable\nrelay bindings, and signed-event conversion without reading a clock, polling\nstatus, or performing relay I/O",
     97         "Executing a capability\nthrough a differently configured transport fails closed",
     98         "let _forged = PreparedDelivery {",
     99         "request: panic!(),",
    100         "skipped: panic!(),",
    101         "literal RFC1918 IPv4 or ULA IPv6 destinations",
    102         "relay URLs and resolved addresses",
    103     ] {
    104         assert!(README.contains(required), "README is missing `{required}`");
    105     }
    106     for required in [
    107         "Config::from_profile(",
    108         "RelayEndpoint::new(",
    109         "RelayProfile::explicit(",
    110         "NostrTransport::new(config)",
    111         "let source: &dyn EventSource",
    112         "let subscriber: &dyn EventSubscriber",
    113         "let sink: &dyn EventSink",
    114         "drop(source.status())",
    115         "let _ = subscriber",
    116         "drop(sink.status())",
    117     ] {
    118         assert!(
    119             EXAMPLE.contains(required),
    120             "example is missing `{required}`"
    121         );
    122     }
    123     for required in [
    124         "pub struct radroots_transport_nostr::Config",
    125         "pub struct radroots_transport_nostr::NostrTransport",
    126         "pub struct radroots_transport_nostr::PreparedDelivery",
    127         "pub enum radroots_transport_nostr::RelayAggregateState",
    128         "pub struct radroots_transport_nostr::RelayProfile",
    129         "pub fn radroots_transport_nostr::RelayEndpoint::new(",
    130         "pub fn radroots_transport_nostr::RelayProfile::explicit<I>(",
    131         "pub struct radroots_transport_nostr::RelayStatusReport",
    132         "pub struct radroots_transport_nostr::RelayUrl(_)",
    133         "pub enum radroots_transport_nostr::RelayUrlPolicy",
    134         "pub enum radroots_transport_nostr::Error",
    135         "impl radroots_transport::sink::EventSink for radroots_transport_nostr::NostrTransport",
    136         "impl radroots_transport::source::EventSource for radroots_transport_nostr::NostrTransport",
    137         "impl radroots_transport::source::EventSubscriber for radroots_transport_nostr::NostrTransport",
    138         "NostrTransport::begin_authentication",
    139         "NostrTransport::complete_authentication",
    140         "NostrTransport::reject_authentication",
    141         "NostrTransport::prepare_delivery",
    142         "NostrTransport::execute_prepared_delivery",
    143     ] {
    144         assert!(
    145             PUBLIC_API.contains(required),
    146             "public API baseline is missing `{required}`"
    147         );
    148     }
    149     for forbidden in [
    150         "nostr_sdk",
    151         "nostr_relay_pool",
    152         "tokio::",
    153         "radroots_storage",
    154         "radroots_outbox",
    155         "pub trait radroots_transport_nostr",
    156         "impl core::clone::Clone for radroots_transport_nostr::PreparedDelivery",
    157         "impl serde_core::ser::Serialize for radroots_transport_nostr::PreparedDelivery",
    158     ] {
    159         assert!(
    160             !PUBLIC_API.contains(forbidden),
    161             "reviewed public API baseline exposes `{forbidden}`"
    162         );
    163     }
    164 }
    165 
    166 #[test]
    167 fn public_errors_retain_no_network_or_dependency_owned_material() {
    168     let declaration = ERROR
    169         .split_once("pub enum Error {")
    170         .expect("error declaration")
    171         .1
    172         .split_once("\n}")
    173         .expect("error declaration end")
    174         .0;
    175     for forbidden in [
    176         "url:",
    177         "address:",
    178         "reason:",
    179         "String",
    180         "url::",
    181         "nostr_sdk::",
    182         "nostr_relay_pool::",
    183     ] {
    184         assert!(
    185             !declaration.contains(forbidden),
    186             "public error retains forbidden network material `{forbidden}`"
    187         );
    188     }
    189 }
    190 
    191 #[test]
    192 fn preparation_is_sealed_and_separated_from_execution_io() {
    193     let prepare = SINK
    194         .split_once("pub fn prepare_delivery(")
    195         .expect("prepared delivery function")
    196         .1
    197         .split_once("pub fn execute_prepared_delivery(")
    198         .expect("execution boundary")
    199         .0;
    200     for forbidden in [".await", "unix_time_ms", "self.status", ".publish("] {
    201         assert!(
    202             !prepare.contains(forbidden),
    203             "delivery preparation contains I/O authority `{forbidden}`"
    204         );
    205     }
    206     for required in [
    207         "pub struct PreparedDelivery",
    208         "#[must_use = \"prepared delivery must be durably bound before execution or deliberately discarded\"]",
    209         "request: DeliveryRequest",
    210         "event: ExactEvent",
    211         "config: crate::Config",
    212         "formatter.write_str(\"PreparedDelivery([redacted])\")",
    213         "pub const fn request(&self) -> &DeliveryRequest",
    214     ] {
    215         assert!(
    216             SINK.contains(required),
    217             "prepared boundary is missing `{required}`"
    218         );
    219     }
    220     for forbidden in [
    221         "impl Clone for PreparedDelivery",
    222         "derive(Clone",
    223         "pub fn new(",
    224         "pub request:",
    225         "pub event:",
    226         "pub config:",
    227     ] {
    228         assert!(
    229             !prepare.contains(forbidden),
    230             "prepared boundary exposes `{forbidden}`"
    231         );
    232     }
    233 }
    234 
    235 #[test]
    236 fn relay_profiles_have_no_implicit_destination_or_policy_constructor() {
    237     for forbidden in [
    238         "DEFAULT_PUBLIC_RELAY",
    239         "pub fn public",
    240         "pub fn simulator",
    241         "pub fn device",
    242     ] {
    243         assert!(!ROOT.contains(forbidden));
    244         assert!(!PROFILE.contains(forbidden));
    245         assert!(!PUBLIC_API.contains(forbidden));
    246     }
    247     for required in [
    248         "pub fn new(",
    249         "policy: RelayUrlPolicy",
    250         "access: RelayAccess",
    251         "IntoIterator<Item = RelayEndpoint>",
    252         ".take(crate::client::MAX_RELAYS + 1)",
    253         "Error::RelayProfilePolicyMismatch",
    254     ] {
    255         assert!(
    256             PROFILE.contains(required),
    257             "profile is missing `{required}`"
    258         );
    259     }
    260 }
    261 
    262 fn radroots_dependency_keys(manifest: &str) -> BTreeSet<&str> {
    263     dependency_keys(manifest)
    264         .into_iter()
    265         .filter(|key| key.starts_with("radroots_"))
    266         .collect()
    267 }
    268 
    269 fn dependency_keys(manifest: &str) -> BTreeSet<&str> {
    270     manifest
    271         .split_once("[dependencies]")
    272         .map(|(_, dependencies)| dependencies)
    273         .unwrap_or_default()
    274         .lines()
    275         .skip(1)
    276         .take_while(|line| !line.starts_with('['))
    277         .filter_map(|line| line.split_once('=').map(|(key, _)| key.trim()))
    278         .filter(|key| !key.is_empty())
    279         .collect()
    280 }
    281 
    282 fn private_modules(root: &str) -> BTreeSet<&str> {
    283     root.lines()
    284         .filter_map(|line| line.trim().strip_prefix("mod "))
    285         .filter_map(|module| module.strip_suffix(';'))
    286         .collect()
    287 }
    288 
    289 #[test]
    290 fn adapter_owns_no_storage_outbox_or_orchestration_surface() {
    291     for forbidden in [
    292         "radroots_event_store",
    293         "radroots_outbox",
    294         "radroots_storage",
    295         "publish_claimed",
    296         "fetch_and_ingest",
    297         "projection_refresh",
    298         "retry_schedule",
    299     ] {
    300         assert!(!MANIFEST.contains(forbidden));
    301         assert!(!ROOT.contains(forbidden));
    302     }
    303 
    304     let source_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("src");
    305     let source_files = fs::read_dir(source_root)
    306         .expect("source directory")
    307         .map(|entry| {
    308             entry
    309                 .expect("source entry")
    310                 .file_name()
    311                 .into_string()
    312                 .expect("utf-8 source name")
    313         })
    314         .collect::<BTreeSet<_>>();
    315     assert_eq!(
    316         source_files,
    317         BTreeSet::from([
    318             "auth.rs".to_owned(),
    319             "client.rs".to_owned(),
    320             "cursor.rs".to_owned(),
    321             "error.rs".to_owned(),
    322             "exact_delivery.rs".to_owned(),
    323             "lib.rs".to_owned(),
    324             "profile.rs".to_owned(),
    325             "relay.rs".to_owned(),
    326             "sink.rs".to_owned(),
    327             "socket_write.rs".to_owned(),
    328             "socket_write_tests.rs".to_owned(),
    329             "source.rs".to_owned(),
    330             "source_budget.rs".to_owned(),
    331             "source_ingress.rs".to_owned(),
    332             "source_paging_tests.rs".to_owned(),
    333             "source_window.rs".to_owned(),
    334             "source_wire.rs".to_owned(),
    335             "source_wire_tests.rs".to_owned(),
    336             "status.rs".to_owned(),
    337             "subscription.rs".to_owned(),
    338         ])
    339     );
    340 
    341     for required in [
    342         "impl EventSubscriber for NostrTransport",
    343         "SubscribeAutoCloseOptions::default()",
    344         "ReqExitPolicy::WaitDurationAfterEOSE(query.timeout)",
    345         "self.seen_event_ids.contains(event_id.as_str())",
    346         "resume_cursors",
    347         "let cursor_advances = self",
    348         "self.terminate(SubscriptionEndReason::Cancelled)",
    349     ] {
    350         assert!(
    351             SUBSCRIPTION.contains(required),
    352             "subscription adapter is missing `{required}`"
    353         );
    354     }
    355     for forbidden in [
    356         "tokio::spawn",
    357         "spawn_blocking",
    358         "std::thread",
    359         "process::",
    360         "global_default",
    361     ] {
    362         assert!(
    363             !SUBSCRIPTION.contains(forbidden),
    364             "subscription adapter contains forbidden authority `{forbidden}`"
    365         );
    366     }
    367 }