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