v0.25.1
This commit is contained in:
1 parent
87e571c170
commit
fa7abc9e53
308 files changed
+49746
-50237
No files matched your search
+200
@@ -0,0 +1,200 @@
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[tokio::test]
|
||||
async fn persists_and_rejects_stale_writes() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let file = dir.path().join("test.sqlite3");
|
||||
let store = Store::open(&file, &Config::default()).await.unwrap();
|
||||
assert_eq!(store.load().await.unwrap().revision, 0);
|
||||
let mut config = crate::config::demo_config("127.0.0.1:9000".parse().unwrap());
|
||||
config.cache.memory_preset = Some(crate::cache::MemoryPreset::Recommended);
|
||||
config.cache.cold_preset = Some(crate::cache::ColdPreset::Recommended);
|
||||
config.transform.preset = Some(crate::transform::Preset::Performance);
|
||||
config.transform.memory_budget_bytes = 512 * 1024 * 1024;
|
||||
config.transform.max_inflight = 64;
|
||||
assert!(store.replace(0, &config).await.unwrap());
|
||||
assert!(!store.replace(0, &Config::default()).await.unwrap());
|
||||
assert_eq!(store.recent_audit().await.unwrap().len(), 1);
|
||||
store.close().await;
|
||||
let reopened = Store::open(&file, &Config::default()).await.unwrap();
|
||||
let data = reopened.load().await.unwrap();
|
||||
assert_eq!(data.revision, 1);
|
||||
assert_eq!(data.config.vhosts[0].backends[0].id, "demo");
|
||||
assert_eq!(
|
||||
data.config.cache.memory_preset,
|
||||
Some(crate::cache::MemoryPreset::Recommended)
|
||||
);
|
||||
assert_eq!(
|
||||
data.config.cache.cold_preset,
|
||||
Some(crate::cache::ColdPreset::Recommended)
|
||||
);
|
||||
assert_eq!(
|
||||
data.config.transform.preset,
|
||||
Some(crate::transform::Preset::Performance)
|
||||
);
|
||||
assert_eq!(data.config.transform.memory_budget_bytes, 512 * 1024 * 1024);
|
||||
assert_eq!(data.config.transform.max_inflight, 64);
|
||||
reopened.close().await;
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn certificate_renewal_observations_survive_reopen_in_schema_v3() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let file = dir.path().join("renewals.sqlite3");
|
||||
let store = Store::open(&file, &Config::default()).await.unwrap();
|
||||
let mut values = std::collections::BTreeMap::new();
|
||||
values.insert(
|
||||
"example-cert".to_string(),
|
||||
crate::acme::RenewalState {
|
||||
last_checked: 100,
|
||||
next_check: 200,
|
||||
last_renewed: Some(50),
|
||||
not_after: Some(500),
|
||||
failures: 2,
|
||||
status: "retry".to_string(),
|
||||
message: "temporary CA failure".to_string(),
|
||||
},
|
||||
);
|
||||
store.replace_certificate_renewals(&values).await.unwrap();
|
||||
let version: i64 = sqlx::query_scalar("PRAGMA user_version")
|
||||
.fetch_one(&store.pool)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(version, SCHEMA_VERSION);
|
||||
store.close().await;
|
||||
|
||||
let reopened = Store::open(&file, &Config::default()).await.unwrap();
|
||||
let saved = reopened.load_certificate_renewals().await.unwrap();
|
||||
let state = saved.get("example-cert").unwrap();
|
||||
assert_eq!(state.last_checked, 100);
|
||||
assert_eq!(state.next_check, 200);
|
||||
assert_eq!(state.last_renewed, Some(50));
|
||||
assert_eq!(state.not_after, Some(500));
|
||||
assert_eq!(state.failures, 2);
|
||||
assert_eq!(state.status, "retry");
|
||||
assert_eq!(state.message, "temporary CA failure");
|
||||
reopened.close().await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn certificate_api_credentials_persist_hash_comments_and_individual_usage() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let file = dir.path().join("certificate-api.sqlite3");
|
||||
let store = Store::open(&file, &Config::default()).await.unwrap();
|
||||
let token = "b".repeat(64);
|
||||
let hash = crate::auth::secret_hash(&token);
|
||||
let saved = store
|
||||
.upsert_certificate_api_credential(
|
||||
"certbot-main",
|
||||
&hash,
|
||||
"production certbot",
|
||||
"owner",
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(saved.key_id, "certbot-main");
|
||||
assert_eq!(saved.comment, "production certbot");
|
||||
assert!(saved.last_used_at.is_none());
|
||||
|
||||
let raw: String = sqlx::query_scalar(
|
||||
"SELECT token_hash FROM certificate_api_credentials WHERE key_id = ?",
|
||||
)
|
||||
.bind("certbot-main")
|
||||
.fetch_one(&store.pool)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(raw, hash);
|
||||
assert_ne!(raw, token);
|
||||
|
||||
let second_hash = crate::auth::secret_hash(&"d".repeat(64));
|
||||
store
|
||||
.upsert_certificate_api_credential(
|
||||
"deploy-hook",
|
||||
&second_hash,
|
||||
"secondary deploy hook",
|
||||
"owner",
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(store.certificate_api_credentials().await.unwrap().len(), 2);
|
||||
|
||||
assert!(store
|
||||
.verify_certificate_api_credential("certbot-main", &hash)
|
||||
.await
|
||||
.unwrap());
|
||||
assert!(!store
|
||||
.verify_certificate_api_credential(
|
||||
"certbot-main",
|
||||
&crate::auth::secret_hash(&"c".repeat(64)),
|
||||
)
|
||||
.await
|
||||
.unwrap());
|
||||
let credentials = store.certificate_api_credentials().await.unwrap();
|
||||
assert!(credentials
|
||||
.iter()
|
||||
.find(|item| item.key_id == "certbot-main")
|
||||
.unwrap()
|
||||
.last_used_at
|
||||
.is_some());
|
||||
assert!(credentials
|
||||
.iter()
|
||||
.find(|item| item.key_id == "deploy-hook")
|
||||
.unwrap()
|
||||
.last_used_at
|
||||
.is_none());
|
||||
|
||||
assert!(store
|
||||
.revoke_certificate_api_credential("certbot-main", "owner")
|
||||
.await
|
||||
.unwrap());
|
||||
let remaining = store.certificate_api_credentials().await.unwrap();
|
||||
assert_eq!(remaining.len(), 1);
|
||||
assert_eq!(remaining[0].key_id, "deploy-hook");
|
||||
assert_eq!(store.revoke_all_certificate_api_credentials("owner").await.unwrap(), 1);
|
||||
assert!(store.certificate_api_credentials().await.unwrap().is_empty());
|
||||
store.close().await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn existing_empty_config_is_not_reseeded() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let file = dir.path().join("test.sqlite3");
|
||||
let store = Store::open(&file, &Config::default()).await.unwrap();
|
||||
store.close().await;
|
||||
let demo = crate::config::demo_config("127.0.0.1:9000".parse().unwrap());
|
||||
let store = Store::open(&file, &demo).await.unwrap();
|
||||
assert!(store.load().await.unwrap().config.vhosts.is_empty());
|
||||
store.close().await;
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn migration_keeps_v1_config_and_revision() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let path = dir.path().join("old.sqlite3");
|
||||
let options = SqliteConnectOptions::new()
|
||||
.filename(&path)
|
||||
.create_if_missing(true);
|
||||
let pool = SqlitePoolOptions::new()
|
||||
.max_connections(1)
|
||||
.connect_with(options)
|
||||
.await
|
||||
.unwrap();
|
||||
sqlx::query("CREATE TABLE configuration(id INTEGER PRIMARY KEY, revision INTEGER NOT NULL, document TEXT NOT NULL)")
|
||||
.execute(&pool).await.unwrap();
|
||||
let demo = crate::config::demo_config("127.0.0.1:9000".parse().unwrap());
|
||||
sqlx::query("INSERT INTO configuration VALUES(1, 42, ?)")
|
||||
.bind(serde_json::to_string(&demo).unwrap())
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
sqlx::query("PRAGMA user_version = 1")
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
pool.close().await;
|
||||
let store = Store::open(&path, &Config::default()).await.unwrap();
|
||||
let saved = store.load().await.unwrap();
|
||||
assert_eq!(saved.revision, 42);
|
||||
assert_eq!(saved.config.vhosts[0].backends[0].id, "demo");
|
||||
assert!(store.admin_record().await.unwrap().is_none());
|
||||
store.close().await;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user