objects/store/
store_compliance.rs1use crate::{
9 object::{Attribution, Blob, ContentHash, Principal, State, Tree},
10 store::ObjectStore,
11};
12
13fn attribution() -> Attribution {
14 Attribution::human(Principal::new("Compliance Test", "test@example.com"))
15}
16
17pub fn run_compliance_tests<S: ObjectStore>(store: &S) {
23 blob_round_trip(store);
24 blob_missing_returns_none(store);
25 blob_has(store);
26 blob_list(store);
27 tree_round_trip(store);
28 tree_missing_returns_none(store);
29 state_round_trip(store);
30 state_has(store);
31 state_list(store);
32}
33
34fn blob_round_trip<S: ObjectStore>(store: &S) {
37 let blob = Blob::from("compliance: blob round-trip");
38 let hash = store.put_blob(&blob).expect("put_blob failed");
39 let got = store
40 .get_blob(&hash)
41 .expect("get_blob failed")
42 .expect("blob missing after put");
43 assert_eq!(
44 got.content(),
45 blob.content(),
46 "blob content changed after round-trip"
47 );
48}
49
50fn blob_missing_returns_none<S: ObjectStore>(store: &S) {
51 let hash = ContentHash::compute(b"compliance-nonexistent-blob");
52 let result = store
53 .get_blob(&hash)
54 .expect("get_blob error on missing key");
55 assert!(
56 result.is_none(),
57 "get_blob should return None for unknown hash"
58 );
59}
60
61fn blob_has<S: ObjectStore>(store: &S) {
62 let blob = Blob::from("compliance: has_blob");
63 let hash = store.put_blob(&blob).expect("put_blob failed");
64 assert!(
65 store.has_blob(&hash).expect("has_blob failed"),
66 "has_blob returned false immediately after put"
67 );
68}
69
70fn blob_list<S: ObjectStore>(store: &S) {
71 let blob = Blob::from("compliance: list_blobs");
72 let hash = store.put_blob(&blob).expect("put_blob failed");
73 let list = store.list_blobs().expect("list_blobs failed");
74 assert!(
75 list.contains(&hash),
76 "list_blobs does not contain hash after put"
77 );
78}
79
80fn tree_round_trip<S: ObjectStore>(store: &S) {
83 let tree = Tree::new();
84 let hash = store.put_tree(&tree).expect("put_tree failed");
85 let got = store
86 .get_tree(&hash)
87 .expect("get_tree failed")
88 .expect("tree missing after put");
89 assert_eq!(got.hash(), hash, "tree hash changed after round-trip");
90}
91
92fn tree_missing_returns_none<S: ObjectStore>(store: &S) {
93 let hash = ContentHash::compute(b"compliance-nonexistent-tree");
94 let result = store
95 .get_tree(&hash)
96 .expect("get_tree error on missing key");
97 assert!(
98 result.is_none(),
99 "get_tree should return None for unknown hash"
100 );
101}
102
103fn state_round_trip<S: ObjectStore>(store: &S) {
106 let tree = Tree::new();
107 let tree_hash = store
108 .put_tree(&tree)
109 .expect("put_tree in state test failed");
110 let state = State::new(tree_hash, vec![], attribution());
111 let id = state.change_id;
112
113 store.put_state(&state).expect("put_state failed");
114
115 let got = store
116 .get_state(&id)
117 .expect("get_state failed")
118 .expect("state missing after put");
119
120 assert_eq!(got.change_id, id, "change_id changed after round-trip");
121 assert_eq!(got.tree, tree_hash, "tree hash changed after round-trip");
122}
123
124fn state_has<S: ObjectStore>(store: &S) {
125 let tree = Tree::new();
126 let tree_hash = store
127 .put_tree(&tree)
128 .expect("put_tree in state test failed");
129 let state = State::new(tree_hash, vec![], attribution());
130 let id = state.change_id;
131 store.put_state(&state).expect("put_state failed");
132 assert!(
133 store.has_state(&id).expect("has_state failed"),
134 "has_state returned false immediately after put"
135 );
136}
137
138fn state_list<S: ObjectStore>(store: &S) {
139 let tree = Tree::new();
140 let tree_hash = store
141 .put_tree(&tree)
142 .expect("put_tree in state test failed");
143 let state = State::new(tree_hash, vec![], attribution());
144 let id = state.change_id;
145 store.put_state(&state).expect("put_state failed");
146 let ids = store.list_states().expect("list_states failed");
147 assert!(
148 ids.contains(&id),
149 "list_states does not contain id after put"
150 );
151}