1#![deny(
20 clippy::expect_used,
21 clippy::indexing_slicing,
22 clippy::panic,
23 clippy::todo,
24 clippy::unimplemented,
25 clippy::unwrap_used,
26 unsafe_op_in_unsafe_fn
27)]
28#![warn(missing_docs)]
29
30#[cfg(all(
31 feature = "graph-cypher",
32 not(any(
33 target_os = "macos",
34 all(target_os = "windows", target_arch = "x86_64")
35 ))
36))]
37compile_error!("graph-cypher supports macOS (arm64, x86_64) and Windows x64 only");
38
39#[cfg(feature = "allocation-audit")]
40mod allocation_audit;
41
42#[cfg(any(test, feature = "test-seams"))]
43#[doc(hidden)]
44pub mod adversarial_test_support;
45
46#[cfg(all(feature = "graph-cypher", feature = "test-seams"))]
48#[doc(hidden)]
49pub mod graph_structured_write_test_support {
50 use crate::lifecycle::{CancelToken, QueryControl, Store};
51 use crate::property_graph::staging::{StructuredOperation, StructuredWrite, WriteImage};
52 use crate::property_graph::{
53 ApplicationKey, CanonicalContents, EntityId, EntityKind, GraphGeneration, GraphName,
54 GraphProperty, GraphRevision, NodeId, PropertyData, PropertyValue,
55 };
56
57 pub fn create_keyed_node(store: &Store) -> Result<(NodeId, GraphGeneration), String> {
59 let mut labels = [GraphName::new("A").map_err(|e| format!("label: {e:?}"))?];
60 let mut properties = [GraphProperty::new(
61 GraphName::new("v").map_err(|e| format!("property name: {e:?}"))?,
62 PropertyValue::new(PropertyData::I64(1))
63 .map_err(|e| format!("property value: {e:?}"))?,
64 )];
65 let image = CanonicalContents::node(&mut labels, &mut properties, None, None)
66 .map_err(|e| format!("node image: {e:?}"))?;
67 let receipts = store
68 .apply_native_graph(
69 &[StructuredWrite {
70 key: ApplicationKey::new(EntityKind::Node, "app", "ze214")
71 .map_err(|e| format!("application key: {e:?}"))?,
72 revision: GraphRevision::new(1).map_err(|e| format!("revision: {e:?}"))?,
73 operation: StructuredOperation::Create,
74 image: Some(WriteImage::Node(&image)),
75 }],
76 &QueryControl::Cancel(CancelToken::new()),
77 )
78 .map_err(|e| format!("structured create: {e:?}"))?;
79 if receipts.len() != 1 {
80 return Err("structured create did not return exactly one receipt".to_owned());
81 }
82 let receipt = receipts
83 .first()
84 .ok_or_else(|| "structured create returned no receipt".to_owned())?;
85 match receipt.entity {
86 EntityId::Node(node) => Ok((node, receipt.generation)),
87 EntityId::Relationship(_) => {
88 Err("structured create returned a relationship".to_owned())
89 }
90 }
91 }
92}
93
94#[cfg(all(feature = "graph-cypher", feature = "test-seams"))]
95#[doc(hidden)]
96pub mod graph_native_vector_index_test_support {
97 pub use crate::property_graph::storage::search::{
98 ActualProbeReport, CleanPreparationObservation, CloseFailureObservation,
99 ControlProbeReport, IdentityProbeReport, KernelProbeReport, LimitProbeReport,
100 NativeFailureObservation, OracleControlObservation, OracleProbeReport, PhysicalReadReceipt,
101 PhysicalReadReport, ReopenIndexObservation, ReopenProbeReport, SmallWriteSourceObservation,
102 SmallWritesProbeReport, TraceBatchObservation, TraceProbeReport, TraceSourceObservation,
103 run_actual_probe, run_identity_probe, run_kernel_probe, run_oracle_probe,
104 run_preparation_schedule_probe, run_reopen_probe, run_small_writes_probe, run_trace_probe,
105 };
106}
107
108#[cfg(all(feature = "graph-cypher", feature = "test-seams"))]
109#[doc(hidden)]
110pub mod graph_read_view_test_support {
111 #[derive(Clone, Debug, Eq, PartialEq)]
114 pub struct PathReceipt {
115 pub key: &'static str,
117 pub fires: u64,
119 pub clean_controls: u64,
121 }
122
123 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
126 pub struct ObservedRelationship {
127 pub rel: u128,
128 pub source: u128,
129 pub target: u128,
130 pub relationship_type: u64,
131 }
132
133 #[derive(Clone, Debug, Eq, PartialEq)]
135 pub struct ActualProbeReport {
136 pub receipts: Vec<PathReceipt>,
137 pub relationships: Vec<ObservedRelationship>,
138 }
139 pub fn controlled_boundary_is_available() -> bool {
143 std::mem::size_of::<crate::lifecycle::native_graph::NativeReadLease>() > 0
144 && std::mem::size_of::<crate::property_graph::storage::GraphReadView<'_, '_, '_, '_>>()
145 > 0
146 }
147
148 pub fn run_actual_probe(seed: u64) -> ActualProbeReport {
152 crate::lifecycle::native_graph::tests::run_adversarial_probe(seed)
153 }
154}
155
156#[cfg(all(feature = "graph-cypher", feature = "test-seams"))]
157#[doc(hidden)]
158pub mod graph_publication_test_support {
159 pub fn run_actual_probe(seed: u64) -> crate::graph_read_view_test_support::ActualProbeReport {
161 crate::lifecycle::native_graph::tests::publication::run_actual_probe(seed)
162 }
163}
164
165#[cfg(all(feature = "graph-cypher", feature = "test-seams"))]
166#[doc(hidden)]
167pub mod graph_identity_test_support {
168 use crate::graph_read_view_test_support::PathReceipt;
169
170 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
172 pub struct ObservedAdjacency {
173 pub bound_node: u128,
175 pub relationship_type: u64,
177 pub rel: u128,
179 pub neighbor: u128,
181 }
182
183 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
185 pub struct ObservedOutcome {
186 pub key: u32,
188 pub rejection: Option<&'static str>,
190 pub entity: u128,
192 pub revision: u64,
194 pub generation: u64,
196 pub replayed: bool,
198 }
199
200 #[derive(Clone, Debug, Eq, PartialEq)]
202 pub struct ObservedWatch {
203 pub batch: usize,
205 pub generation: u64,
207 pub key: u32,
209 pub outgoing: bool,
211 pub rows: Vec<ObservedAdjacency>,
213 }
214
215 #[derive(Clone, Debug, Eq, PartialEq)]
217 pub struct IdentityState {
218 pub outcomes: Vec<ObservedOutcome>,
220 pub watched: Vec<ObservedWatch>,
222 pub retained_generation: u64,
224 pub retained_rows: Vec<ObservedAdjacency>,
227 pub fresh_generation: u64,
229 pub fresh_rows: Vec<ObservedAdjacency>,
231 }
232
233 #[derive(Clone, Debug, Eq, PartialEq)]
235 pub struct IdentityProbeReport {
236 pub receipts: Vec<PathReceipt>,
238 pub state: IdentityState,
240 }
241
242 pub fn run_actual_probe(seed: u64) -> IdentityProbeReport {
244 crate::lifecycle::native_graph::tests::run_identity_probe(seed)
245 }
246}
247
248#[cfg(all(feature = "graph-cypher", feature = "test-seams"))]
249#[doc(hidden)]
250pub mod graph_reclaim_test_support {
251 use crate::graph_read_view_test_support::{ObservedRelationship, PathReceipt};
252
253 #[derive(Clone, Debug, Eq, PartialEq)]
256 pub struct ReclaimState {
257 pub first_node: u128,
259 pub second_node: u128,
261 pub relationships: Vec<ObservedRelationship>,
263 pub replay_generation: u64,
265 pub replayed: bool,
267 pub removed_bytes: u64,
269 pub unlinked_file_bytes: u64,
271 }
272
273 #[derive(Clone, Debug, Eq, PartialEq)]
275 pub struct ReclaimProbeReport {
276 pub receipts: Vec<PathReceipt>,
278 pub state: ReclaimState,
280 pub detach_sweep: (bool, u64),
282 }
283
284 #[derive(Clone, Debug, Eq, PartialEq)]
286 pub struct RaceProbeReport {
287 pub observation: (u64, Vec<u8>, bool, bool),
289 pub control: (u64, Vec<u8>, bool, bool),
291 }
292
293 pub fn run_ze176_race_probe(seed: u64) -> RaceProbeReport {
295 crate::lifecycle::native_graph::tests::run_ze176_race_probe(seed)
296 }
297
298 pub fn run_actual_probe(seed: u64) -> ReclaimProbeReport {
301 crate::lifecycle::native_graph::tests::run_reclaim_probe(seed)
302 }
303}
304
305#[cfg(all(feature = "graph-cypher", feature = "test-seams"))]
306#[doc(hidden)]
307pub mod graph_storage_fault_test_support {
308 use crate::graph_read_view_test_support::{ObservedRelationship, PathReceipt};
309 use crate::lifecycle::{OpenOptions, Store};
310 use crate::vfs::Vfs;
311 use std::path::Path;
312 use std::sync::Arc;
313
314 #[derive(Clone, Debug, Eq, PartialEq)]
317 pub struct ObservedKeyedNode {
318 pub key: Vec<u8>,
320 pub node: u128,
322 pub revision: u64,
324 }
325
326 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
329 pub struct StorageFaultSchedule {
330 pub artifact_ref_offset: u64,
332 pub split_keys: u32,
335 pub split_probe: u32,
337 pub split_skip: u32,
339 pub out_in_append: u32,
341 pub root_variant: u8,
343 pub qualification_seed: u64,
345 }
346
347 #[derive(Clone, Debug, Default, Eq, PartialEq)]
349 pub struct QualificationCell {
350 pub name: String,
352 pub fires: u64,
354 pub controls: u64,
355 pub refusal: String,
357 pub unauthorized_unlinks: u64,
359 pub changed_live_files: u64,
360 pub intent_preserved: bool,
362 pub resumed: bool,
363 pub removed_bytes: u64,
365 pub unlinked_bytes: u64,
366 pub exposed_blocks: u64,
368 pub filled: usize,
370 pub opens: usize,
372 pub logged_opens: usize,
373 pub scoped_opens: usize,
374 pub runs: usize,
376 pub merges: usize,
377 pub folded: usize,
378 pub count_debt: u64,
380 }
381
382 #[derive(Clone, Debug, Eq, PartialEq)]
384 pub struct QualificationPack {
385 pub serial: u64,
386 pub bytes: u32,
387 pub live: u64,
388 pub pages: u32,
389 pub records: u32,
390 pub graph_live: bool,
391 }
392 #[derive(Clone, Debug, Default, Eq, PartialEq)]
394 pub struct QualificationSelection {
395 pub packs: Vec<QualificationPack>,
396 pub selected_serials: Vec<u64>,
397 pub clean_serials: Vec<u64>,
398 pub byte_limit: u64,
399 pub ranges: Vec<(u8, usize, usize)>,
401 pub selected_ranges: Vec<(u8, usize)>,
402 pub clean_ranges: Vec<(u8, usize)>,
403 pub fixture_pending: Vec<usize>,
404 }
405
406 #[derive(Clone, Debug, Eq, PartialEq)]
408 pub struct QualificationCommit {
409 pub generation: u64,
410 pub opens: usize,
411 pub logged_opens: usize,
412 pub filled: usize,
413 pub scoped_opens: usize,
414 }
415
416 #[derive(Clone, Debug, Default, Eq, PartialEq)]
418 pub struct QualificationReport {
419 pub cells: Vec<QualificationCell>,
420 pub selection: Option<QualificationSelection>,
421 pub commits: Vec<QualificationCommit>,
422 }
423
424 pub fn run_qualification_probe(seed: u64, mapping: bool) -> QualificationReport {
426 crate::lifecycle::native_graph::tests::storage_faults::run_qualification_probe(
427 seed, mapping,
428 )
429 }
430
431 #[derive(Clone, Debug, Eq, PartialEq)]
433 pub struct StorageFaultState {
434 pub artifact_refusals: Vec<String>,
436 pub surviving_nodes: Vec<ObservedKeyedNode>,
438 pub split_level: u16,
441 pub retained_split_level: u16,
444 pub pre_split_keys: u32,
447 pub committed_keys: Vec<ObservedKeyedNode>,
449 pub old_root_keys: Vec<ObservedKeyedNode>,
451 pub split_generations: (u64, u64),
454 pub retained_root_digests: (u64, u64),
457 pub unsplit_generations: (u64, u64),
461 pub unsplit_reopen_level: u16,
464 pub split_refusals: Vec<String>,
466 pub out_rows: Vec<ObservedRelationship>,
468 pub in_rows: Vec<ObservedRelationship>,
470 pub out_in_refusals: Vec<String>,
472 pub root_refusals: Vec<String>,
474 pub reopened_generation: u64,
476 pub previous_generation: u64,
478 pub qualification: QualificationReport,
480 }
481
482 #[derive(Clone, Debug, Eq, PartialEq)]
484 pub struct StorageFaultProbeReport {
485 pub receipts: Vec<PathReceipt>,
487 pub state: StorageFaultState,
489 }
490
491 pub fn run_actual_probe(seed: u64, schedule: StorageFaultSchedule) -> StorageFaultProbeReport {
494 crate::lifecycle::native_graph::tests::run_storage_fault_probe(seed, schedule)
495 }
496
497 pub fn create_native_graph_with_infrastructure(
502 path: &Path,
503 options: OpenOptions,
504 vfs: Arc<dyn Vfs>,
505 ) -> Result<Store, String> {
506 Store::create_native_graph_with_infrastructure(
507 path,
508 options,
509 None,
510 vfs,
511 Arc::new(crate::lifecycle::SystemMonotonicClock),
512 &mut crate::property_graph::storage::allocation::OsEntropy,
513 )
514 .map_err(|error| error.to_string())
515 }
516
517 pub fn open_native_graph_with_infrastructure(
520 path: &Path,
521 options: OpenOptions,
522 vfs: Arc<dyn Vfs>,
523 ) -> Result<Store, String> {
524 Store::open_native_graph_with_infrastructure(
525 path,
526 options,
527 None,
528 vfs,
529 Arc::new(crate::lifecycle::SystemMonotonicClock),
530 )
531 .map_err(|error| error.to_string())
532 }
533}
534
535#[cfg(all(feature = "graph-cypher", feature = "test-seams"))]
536#[doc(hidden)]
537pub mod graph_recovery_test_support {
538 use crate::graph_read_view_test_support::{ObservedRelationship, PathReceipt};
539
540 #[derive(Clone, Debug, Eq, PartialEq)]
542 pub struct RecoveryState {
543 pub store: u128,
545 pub generation: u64,
547 pub sequence: u64,
549 pub first_node: u128,
551 pub second_node: u128,
553 pub relationship: ObservedRelationship,
555 }
556
557 #[derive(Clone, Debug, Eq, PartialEq)]
559 pub struct RecoveryProbeReport {
560 pub receipts: Vec<PathReceipt>,
562 pub state: RecoveryState,
564 }
565
566 pub fn run_actual_probe(seed: u64) -> RecoveryProbeReport {
568 crate::lifecycle::native_graph::tests::run_recovery_probe(seed)
569 }
570}
571
572#[cfg(all(feature = "graph-cypher", any(test, feature = "test-seams")))]
574pub mod graph_commit_recovery_test_support {
575 pub use crate::property_graph::commit_recovery_test_support::*;
576}
577
578pub mod diag;
580pub mod epoch;
582pub mod format;
584pub mod fts;
586pub mod fusion;
588pub mod graph;
590pub mod ingest;
592pub mod kernels;
594pub mod lifecycle;
596pub mod manifest;
598pub mod meta;
600pub mod planner;
602#[cfg(feature = "graph-cypher")]
604pub mod property_graph;
605pub mod quant;
607pub mod scan;
609pub mod segment;
611pub mod sys;
613pub mod tier;
615pub mod verify;
617pub mod vfs;
619pub mod wal;
621
622#[cfg(test)]
623mod test_support;
624
625pub const VERSION: &str = env!("CARGO_PKG_VERSION");
627
628#[cfg(test)]
629#[allow(
630 clippy::expect_used,
631 clippy::indexing_slicing,
632 clippy::panic,
633 clippy::unwrap_used
634)]
635mod tests {
636 use rand::RngCore;
637
638 #[test]
639 #[cfg_attr(miri, ignore = "environment-dependent RNG is outside the Miri subset")]
640 fn seeded_rng_is_deterministic_per_name_and_env() {
641 let mut first =
642 crate::test_support::seeded_rng("tests::seeded_rng_is_deterministic_per_name_and_env");
643 let mut second =
644 crate::test_support::seeded_rng("tests::seeded_rng_is_deterministic_per_name_and_env");
645 let mut other_name = crate::test_support::seeded_rng("tests::another_test");
646
647 let first_draw = first.next_u64();
648 let second_draw = second.next_u64();
649 let other_name_draw = other_name.next_u64();
650
651 let environment_seed = std::env::var("ZE_TEST_SEED").unwrap_or_else(|_| String::from("0"));
652 let other_environment_seed = format!("{environment_seed}-different");
653 let mut other_env = crate::test_support::seeded_rng_from(
654 "tests::seeded_rng_is_deterministic_per_name_and_env",
655 &other_environment_seed,
656 );
657 let other_env_draw = other_env.next_u64();
658
659 assert_eq!(first_draw, second_draw);
660 assert_ne!(first_draw, other_name_draw);
661 assert_ne!(first_draw, other_env_draw);
662 }
663
664 #[test]
665 fn version_constant_is_current() {
666 assert_eq!(crate::VERSION, "0.6.0");
667 }
668}