use bytes::Bytes;
use crate::storage::{StorageError, StorageProvider};
pub async fn cas_conformance(p: &dyn StorageProvider, key: &str, expect_stale_rejected: bool) {
const V1: &[u8] = b"v1";
const V2: &[u8] = b"v2-xx";
const V3: &[u8] = b"v3-xxxx";
const V4: &[u8] = b"v4-xxxxxx";
let tok_create = p
.put_atomic(key, Bytes::from_static(V1))
.await
.expect("put_atomic create");
let (_, meta) = p.get(key).await.expect("get after create");
let read_tok = meta.etag.clone();
let tok_after_v2 = p
.put_if_match(key, Bytes::from_static(V2), read_tok.as_deref())
.await
.expect("conditional update with the read token");
if tok_after_v2.is_some() {
p.put_if_match(key, Bytes::from_static(V3), tok_after_v2.as_deref())
.await
.expect("chained update with the token RETURNED by put_if_match");
}
if expect_stale_rejected && tok_create.is_some() && tok_create != tok_after_v2 {
let stale = p
.put_if_match(key, Bytes::from_static(V4), tok_create.as_deref())
.await;
assert!(
matches!(stale, Err(StorageError::PreconditionFailed { .. })),
"stale token must be PreconditionFailed; got {stale:?}"
);
}
p.delete(key).await.expect("cleanup");
}