use std::sync::Arc;
use armdb::armour::Db;
use armdb::{DbError, FixedConfig, QueueConfig, TxConfig, queue};
use armour_core::GetType;
use rapira::Rapira;
const DATA_KEY: [u8; 32] = [0x31; 32];
const LOG_KEY: [u8; 32] = [0x32; 32];
#[derive(Clone, Debug, PartialEq, Eq, GetType, Rapira)]
pub struct SecretJob {
body: String,
}
queue!(
EncryptedJobs,
payload = SecretJob,
name = "queue_encrypted_jobs",
var
);
fn payload_config() -> armdb::Config {
armdb::Config::balanced()
.shard_count(1)
.encryption_key(DATA_KEY)
.build()
}
fn queue_config() -> QueueConfig {
let config = QueueConfig::balanced()
.header_config(FixedConfig::balanced().reversed(true).grow_step(64).build())
.payload_config(payload_config());
let header = config.fixed_config();
assert!(!header.reversed);
assert_eq!(header.grow_step, 64);
config.build().unwrap()
}
#[test]
fn encrypted_var_queue_direct_and_transactional_operations_require_the_right_keys() {
let dir = tempfile::tempdir().unwrap();
let db = Arc::new(
Db::builder(dir.path())
.for_tests()
.tx_config(TxConfig {
log_encryption_key: Some(LOG_KEY),
..TxConfig::default()
})
.open()
.unwrap(),
);
let queue = db.open_queue::<EncryptedJobs>(queue_config()).unwrap();
queue
.push(
SecretJob {
body: "first".into(),
},
None,
)
.unwrap();
queue
.push(
SecretJob {
body: "second".into(),
},
None,
)
.unwrap();
let direct = queue.lease(1, None).unwrap().pop().unwrap();
assert_eq!(direct.payload().body, "first");
queue.ack(direct.token()).unwrap();
let direct = queue.lease(1, None).unwrap().pop().unwrap();
assert_eq!(direct.payload().body, "second");
queue.ack(direct.token()).unwrap();
db.tx()
.push(
&queue,
SecretJob {
body: "transactional".into(),
},
None,
)
.unwrap()
.commit()
.unwrap();
let transactional = queue.lease(1, None).unwrap().pop().unwrap();
assert_eq!(transactional.payload().body, "transactional");
queue.ack(transactional.token()).unwrap();
drop(queue);
drop(db);
let missing_log_dir = tempfile::tempdir().unwrap();
let db = Arc::new(Db::open_test(missing_log_dir.path()).unwrap());
let queue = db.open_queue::<EncryptedJobs>(queue_config()).unwrap();
let err = db
.tx()
.push(
&queue,
SecretJob {
body: "must-not-commit".into(),
},
None,
)
.unwrap()
.commit()
.err()
.expect("opening with no payload key must fail");
assert!(matches!(err, DbError::Config(_)), "{err}");
assert_eq!(queue.len(), 0);
assert_eq!(queue.debug_payload_len(), 0);
drop(queue);
drop(db);
let db = Arc::new(
Db::builder(dir.path())
.for_tests()
.tx_config(TxConfig {
log_encryption_key: Some(LOG_KEY),
..TxConfig::default()
})
.open()
.unwrap(),
);
db.open_queue::<EncryptedJobs>(queue_config())
.expect("the matching payload key reopens the encrypted queue");
drop(db);
let missing_key = Db::open_test(dir.path()).unwrap();
let err = missing_key
.open_queue::<EncryptedJobs>(
QueueConfig::balanced()
.payload_config(armdb::Config::balanced().shard_count(1).build())
.build()
.unwrap(),
)
.err()
.expect("opening with no payload key must fail");
assert!(
matches!(err, DbError::EncryptionError(_) | DbError::Config(_)),
"{err}"
);
drop(missing_key);
let wrong_key = Db::open_test(dir.path()).unwrap();
let err = wrong_key
.open_queue::<EncryptedJobs>(
QueueConfig::balanced()
.payload_config(
armdb::Config::balanced()
.shard_count(1)
.encryption_key([0x33; 32])
.build(),
)
.build()
.unwrap(),
)
.err()
.expect("opening with the wrong payload key must fail");
assert!(
matches!(err, DbError::EncryptionError(_) | DbError::Config(_)),
"{err}"
);
}