common_procedure/
test_util.rs1use std::collections::hash_map::Entry;
16use std::collections::HashMap;
17use std::sync::{Arc, RwLock};
18
19use snafu::ensure;
20
21use super::*;
22use crate::error;
23use crate::store::poison_store::PoisonStore;
24
25#[derive(Debug, Default)]
27pub struct InMemoryPoisonStore {
28 map: Arc<RwLock<HashMap<String, String>>>,
29}
30
31impl InMemoryPoisonStore {
32 pub fn new() -> Self {
34 Self::default()
35 }
36}
37
38#[async_trait::async_trait]
39impl PoisonStore for InMemoryPoisonStore {
40 async fn try_put_poison(&self, key: String, token: String) -> Result<()> {
41 let mut map = self.map.write().unwrap();
42 match map.entry(key) {
43 Entry::Vacant(v) => {
44 v.insert(token.to_string());
45 }
46 Entry::Occupied(o) => {
47 let value = o.get();
48 ensure!(
49 value == &token,
50 error::UnexpectedSnafu {
51 err_msg: format!("The poison is already set by other token {}", value)
52 }
53 );
54 }
55 }
56 Ok(())
57 }
58
59 async fn delete_poison(&self, key: String, token: String) -> Result<()> {
60 let mut map = self.map.write().unwrap();
61 match map.entry(key) {
62 Entry::Vacant(_) => {
63 }
65 Entry::Occupied(o) => {
66 let value = o.get();
67 ensure!(
68 value == &token,
69 error::UnexpectedSnafu {
70 err_msg: format!("The poison is not set by the token {}", value)
71 }
72 );
73
74 o.remove();
75 }
76 }
77 Ok(())
78 }
79
80 async fn get_poison(&self, key: &str) -> Result<Option<String>> {
81 let map = self.map.read().unwrap();
82 let key = key.to_string();
83 Ok(map.get(&key).cloned())
84 }
85}