trellis_testing/resource_error.rs
1use std::collections::BTreeSet;
2
3use trellis_core::{
4 ResourceCommandKind, ResourceCommandTrace, ResourceKey, Revision, ScopeId, TransactionId,
5};
6
7use crate::{HostStatusClass, HostStatusEvent};
8
9/// Structural context for a resource command observed by the ledger.
10#[derive(Clone, Debug, Eq, PartialEq)]
11pub struct ResourceCommandContext {
12 /// Resource key targeted by the command.
13 pub key: ResourceKey,
14 /// Scope associated with the command.
15 pub scope: ScopeId,
16 /// Transaction that emitted the command.
17 pub transaction_id: TransactionId,
18 /// Graph revision that emitted the command.
19 pub revision: Revision,
20 /// Ledger-assigned command generation for this resource key.
21 pub generation: u64,
22 /// Command operation without application payload.
23 pub kind: ResourceCommandKind,
24}
25
26/// Structural context for a host status classification.
27#[derive(Clone, Debug, Eq, PartialEq)]
28pub struct ResourceStatusContext {
29 /// Status supplied by the host simulator.
30 pub status: HostStatusEvent,
31 /// Classification assigned by the ledger.
32 pub class: HostStatusClass,
33 /// Last command transaction known for this resource key, if any.
34 pub last_transaction_id: Option<TransactionId>,
35 /// Last command revision known for this resource key, if any.
36 pub last_command_revision: Option<Revision>,
37}
38
39/// Resource ledger assertion failure.
40#[derive(Clone, Debug, Eq, PartialEq)]
41pub enum ResourceLedgerError {
42 /// Resource has no owner.
43 Orphan {
44 /// Resource key.
45 key: ResourceKey,
46 /// Last known command context for the resource.
47 context: Option<ResourceCommandContext>,
48 },
49 /// Resource was closed without a matching owner.
50 DuplicateClose {
51 /// Resource key.
52 key: ResourceKey,
53 /// Command context that attempted the duplicate close.
54 context: ResourceCommandContext,
55 },
56 /// Forbidden resource demand was opened.
57 ForbiddenOpen {
58 /// Resource key.
59 key: ResourceKey,
60 /// Command context that opened the forbidden resource.
61 context: Option<ResourceCommandContext>,
62 },
63 /// Resource is still open.
64 StillOpen {
65 /// Resource key.
66 key: ResourceKey,
67 /// Last known command context for the resource.
68 context: Option<ResourceCommandContext>,
69 },
70 /// A closed scope still owns resources.
71 ClosedScopeOwnsResources {
72 /// Closed scope.
73 scope: ScopeId,
74 /// Resources still owned by the closed scope.
75 resources: Vec<ResourceKey>,
76 /// Last command contexts for the resources.
77 contexts: Vec<ResourceCommandContext>,
78 },
79 /// Resource command count differed from expectation.
80 CountMismatch {
81 /// Resource key.
82 key: ResourceKey,
83 /// Count that differed.
84 field: &'static str,
85 /// Expected count.
86 expected: usize,
87 /// Actual count.
88 actual: usize,
89 /// Last known command context for the resource.
90 context: Option<ResourceCommandContext>,
91 },
92 /// Resource generation differed from expectation.
93 GenerationMismatch {
94 /// Resource key.
95 key: ResourceKey,
96 /// Expected generation.
97 expected: u64,
98 /// Actual generation.
99 actual: u64,
100 /// Last known command context for the resource.
101 context: Option<ResourceCommandContext>,
102 },
103 /// Resource does not have the expected owners.
104 OwnerMismatch {
105 /// Resource key.
106 key: ResourceKey,
107 /// Expected owner set.
108 expected: BTreeSet<ScopeId>,
109 /// Actual owner set.
110 actual: BTreeSet<ScopeId>,
111 /// Last known command context for the resource.
112 context: Option<ResourceCommandContext>,
113 },
114 /// Resource command order did not match the expected structural trace.
115 CommandOrderMismatch {
116 /// Expected command trace.
117 expected: Vec<ResourceCommandTrace>,
118 /// Actual command trace.
119 actual: Vec<ResourceCommandTrace>,
120 },
121 /// No matching status classification was recorded.
122 MissingStatus {
123 /// Resource key.
124 key: ResourceKey,
125 /// Command revision expected in the status record.
126 command_revision: Revision,
127 },
128 /// A status was classified differently than expected.
129 StatusClassMismatch {
130 /// Recorded status context.
131 context: ResourceStatusContext,
132 /// Expected classification.
133 expected: HostStatusClass,
134 },
135 /// A host status appeared to mutate ownership for a closed scope.
136 StatusMutatedClosedScope {
137 /// Scope that should remain closed.
138 scope: ScopeId,
139 /// Status context that caused the failure.
140 context: ResourceStatusContext,
141 },
142}