Skip to content
This repository was archived by the owner on May 9, 2022. It is now read-only.

Commit 71e1563

Browse files
committed
test(rtc_tenclave,kv_store): clean up, and test delete operations too
1 parent c810c9c commit 71e1563

File tree

1 file changed

+63
-26
lines changed

1 file changed

+63
-26
lines changed

rtc_tenclave/src/kv_store/tests.rs

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,54 +12,91 @@ use tempfile::TempDir;
1212
use super::fs::{std_filer::StdFiler, FsStore};
1313
use super::in_memory::{InMemoryJsonStore, InMemoryStore};
1414
use super::inspect::InspectStore;
15-
use super::KvStore;
15+
use super::{KvStore, StoreResult};
1616

1717
/// Verify that executing a sequence of store operations matches a simple model.
1818
#[test]
1919
fn prop_store_ops_match_model() {
20-
// Strategy to generate store operations: currently, just key / value pairs to save.
20+
// FIXME: This value type parameter needs better handling.
21+
type V = String;
22+
23+
/// Helper: Represent store operations.
24+
#[derive(Debug)]
25+
enum StoreOp {
26+
Save { key: String, value: V },
27+
Delete { key: String },
28+
}
29+
use StoreOp::*;
30+
impl StoreOp {
31+
/// Apply operation, and also check some invariants.
32+
fn apply(&self, store: &mut impl KvStore<V>) -> StoreResult<()> {
33+
match self {
34+
Save { key, value } => {
35+
store.save(key, value)?;
36+
assert_eq!(store.load(key)?.as_ref(), Some(value));
37+
}
38+
Delete { key } => {
39+
store.delete(key)?;
40+
assert_eq!(store.load(key)?, None);
41+
}
42+
};
43+
Ok(())
44+
}
45+
}
46+
47+
// Strategy to generate lists of store operations.
2148
let store_ops_strategy = {
2249
let keys = prop_oneof!(r"[a-z]{0,5}", ".*");
2350
let values = prop_oneof!(keys.clone()); // TODO: Non-string values
51+
let half_ops = prop_oneof!(
52+
(Just("Save"), values.clone().prop_map(Some)),
53+
(Just("Delete"), Just(None)),
54+
);
2455

2556
// This strategy will generate key / value pairs with multiple values per key,
2657
// and shuffle them to have some interleaving, for bugs that depend on that.
27-
proptest::collection::hash_map(keys, proptest::collection::vec(values, 0..10), 0..10)
58+
proptest::collection::hash_map(keys, proptest::collection::vec(half_ops, 0..10), 0..10)
2859
.prop_map(flatten_key_values)
60+
.prop_map(|pairs: Vec<_>| -> Vec<StoreOp> {
61+
pairs
62+
.into_iter()
63+
.map(|(key, half_op)| -> StoreOp {
64+
match half_op {
65+
("Save", Some(value)) => Save { key, value },
66+
("Delete", None) => Delete { key },
67+
unexpected => panic!("unexpected: {:?}", unexpected),
68+
}
69+
})
70+
.collect()
71+
})
2972
.prop_shuffle()
3073
};
3174

32-
fn test(store_ops_vec: Vec<(String, String)>) -> TestCaseResult {
33-
// FIXME: This value type parameter needs better handling.
34-
type V = String;
75+
/// Helper: Check that store state matches model.
76+
fn check_state(store1: &impl InspectStore<V>, store2: &impl InspectStore<V>) -> TestCaseResult {
77+
prop_assert_eq!(store1.as_map(), store2.as_map());
78+
Ok(())
79+
}
3580

81+
fn test(store_ops_vec: Vec<StoreOp>) -> TestCaseResult {
3682
// Init the models
37-
let mut store_model: InMemoryStore<V> = InMemoryStore::default();
38-
let mut store_model_json: InMemoryJsonStore = InMemoryJsonStore::default();
83+
let ref mut store_model = InMemoryStore::default();
84+
let ref mut store_model_json = InMemoryJsonStore::default();
3985

4086
// Init the store under test
4187
let temp_dir = TempDir::new().unwrap();
42-
let mut store_fs: FsStore<StdFiler> =
43-
FsStore::new(&temp_dir, StdFiler).expect("FsStore::new failed");
44-
45-
for (k, v) in store_ops_vec {
46-
store_model
47-
.save(&k, &v)
48-
.expect("InMemoryStore save failed!");
49-
store_model_json
50-
.save(&k, &v)
51-
.expect("InMemoryJsonStore save failed!");
52-
store_fs.save(&k, &v).expect("FsStore save failed!");
88+
let ref mut store_fs = FsStore::new(&temp_dir, StdFiler).expect("FsStore::new failed");
89+
90+
for ref op in store_ops_vec {
91+
op.apply(store_model).unwrap();
92+
op.apply(store_model_json).unwrap();
93+
op.apply(store_fs).unwrap();
5394

5495
// Models match each other
55-
prop_assert_eq!(store_model.as_map(), store_model_json.as_map());
96+
check_state(store_model, store_model_json)?;
5697
// Models match store_fs
57-
prop_assert_eq!(store_model.as_map(), store_fs.as_map());
58-
// FIXME: explicit coercion for as_map()
59-
prop_assert_eq!(
60-
store_model_json.as_map() as HashMap<String, V>,
61-
store_fs.as_map()
62-
);
98+
check_state(store_model, store_fs)?;
99+
check_state(store_model_json, store_fs)?;
63100
}
64101

65102
temp_dir.close()?;

0 commit comments

Comments
 (0)