162 lines
8.2 KiB
Rust
162 lines
8.2 KiB
Rust
#[cfg(test)]
|
|
mod cache_revision_tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn operational_saves_keep_cache_identity_but_cache_affecting_saves_rotate_it() {
|
|
let base = config::demo_config("127.0.0.1:9000".parse().unwrap());
|
|
let identity = cache_revision(&base);
|
|
|
|
let mut file_transport = base.clone();
|
|
file_transport.web_services.push(crate::web_server::Service {
|
|
id: "static-test".into(), name: "Static Test".into(),
|
|
document_root: "/var/www/static-test".into(),
|
|
..Default::default()
|
|
});
|
|
let mut zero_copy = file_transport.clone();
|
|
zero_copy.web_services[0].sendfile = crate::web_server::SendfileMode::Auto;
|
|
assert_eq!(cache_revision(&file_transport), cache_revision(&zero_copy));
|
|
assert!(matches!(cache_invalidation(&file_transport, &zero_copy), CacheInvalidation::None));
|
|
|
|
let mut logging = base.clone();
|
|
logging.logging.file.path = "/tmp/rustproxy-test-access.jsonl".into();
|
|
assert_eq!(cache_revision(&logging), identity);
|
|
assert!(matches!(
|
|
cache_invalidation(&base, &logging),
|
|
CacheInvalidation::None
|
|
));
|
|
|
|
let mut metrics = base.clone();
|
|
metrics.prometheus.include_system = !metrics.prometheus.include_system;
|
|
assert_eq!(cache_revision(&metrics), identity);
|
|
|
|
let mut response = base.clone();
|
|
response.server_header.value = "edge-test".into();
|
|
response.diagnostic_headers.request_id = !response.diagnostic_headers.request_id;
|
|
response.compression.gzip = !response.compression.gzip;
|
|
assert_eq!(cache_revision(&response), identity);
|
|
|
|
let mut docker = base.clone();
|
|
docker.docker_agents.agents.push(crate::docker::Agent {
|
|
id: "node1".into(),
|
|
name: "Node 1".into(),
|
|
..Default::default()
|
|
});
|
|
assert_eq!(cache_revision(&docker), identity);
|
|
|
|
let mut preset = base.clone();
|
|
preset.cache.memory_preset = Some(crate::cache::MemoryPreset::Recommended);
|
|
preset.cache.cold_preset = Some(crate::cache::ColdPreset::Recommended);
|
|
preset.transform.preset = Some(crate::transform::Preset::Uber);
|
|
preset.transform.memory_budget_bytes = 1024 * 1024 * 1024;
|
|
preset.transform.max_inflight = 128;
|
|
assert_eq!(cache_revision(&preset), identity);
|
|
assert!(matches!(
|
|
cache_invalidation(&base, &preset),
|
|
CacheInvalidation::None
|
|
));
|
|
|
|
let mut transform_policy = base.clone();
|
|
transform_policy.transform.json = !transform_policy.transform.json;
|
|
assert_ne!(cache_revision(&transform_policy), identity);
|
|
|
|
let mut transform_body_limit = base.clone();
|
|
transform_body_limit.transform.max_body_bytes += 1024;
|
|
assert_ne!(cache_revision(&transform_body_limit), identity);
|
|
|
|
let mut wire_only = base.clone();
|
|
wire_only.cache.bypass_query = !wire_only.cache.bypass_query;
|
|
wire_only.cache.bypass_prefixes.push("/private".into());
|
|
wire_only.cache.expose_status = !wire_only.cache.expose_status;
|
|
wire_only.cache.expose_hits = !wire_only.cache.expose_hits;
|
|
wire_only.cache.expose_cache_status = !wire_only.cache.expose_cache_status;
|
|
wire_only.cache.expose_resident_age = !wire_only.cache.expose_resident_age;
|
|
wire_only.cache.expose_only_hits = !wire_only.cache.expose_only_hits;
|
|
wire_only.cache.via_header = Some("RustProxy edge".into());
|
|
wire_only.cache.http_invalidation_allowed_cidrs = vec!["192.0.2.42".into()];
|
|
assert_eq!(cache_revision(&wire_only), identity);
|
|
assert!(matches!(
|
|
cache_invalidation(&base, &wire_only),
|
|
CacheInvalidation::None
|
|
));
|
|
|
|
for label in ["http2", "http3"] {
|
|
let mut protocol_only = base.clone();
|
|
if label == "http2" {
|
|
protocol_only.vhosts[0].http2_enabled = !base.vhosts[0].http2_enabled;
|
|
} else {
|
|
protocol_only.vhosts[0].http3_enabled = !base.vhosts[0].http3_enabled;
|
|
}
|
|
// The effective configuration really changes, but the cache key
|
|
// does not. This must hold for both toggling directions.
|
|
assert_ne!(
|
|
(protocol_only.vhosts[0].http2_enabled, protocol_only.vhosts[0].http3_enabled),
|
|
(base.vhosts[0].http2_enabled, base.vhosts[0].http3_enabled),
|
|
"{label} toggle did not change a transport switch"
|
|
);
|
|
assert_eq!(cache_revision(&protocol_only), identity, "{label} rotated cache");
|
|
assert!(matches!(cache_invalidation(&base, &protocol_only), CacheInvalidation::None));
|
|
assert!(matches!(cache_invalidation(&protocol_only, &base), CacheInvalidation::None));
|
|
}
|
|
let mut both_protocols = base.clone();
|
|
both_protocols.vhosts[0].http2_enabled = !base.vhosts[0].http2_enabled;
|
|
both_protocols.vhosts[0].http3_enabled = !base.vhosts[0].http3_enabled;
|
|
assert_eq!(cache_revision(&both_protocols), identity);
|
|
assert!(matches!(cache_invalidation(&base, &both_protocols), CacheInvalidation::None));
|
|
|
|
let mut vhost_diagnostics = base.clone();
|
|
vhost_diagnostics.vhosts[0].cache.expose_only_hits = Some(true);
|
|
assert_eq!(cache_revision(&vhost_diagnostics), identity);
|
|
assert!(matches!(cache_invalidation(&base, &vhost_diagnostics), CacheInvalidation::None));
|
|
|
|
let mut cache = base.clone();
|
|
cache.cache.max_entries += 1;
|
|
let cache_identity = cache_revision(&cache);
|
|
assert_ne!(cache_identity, identity);
|
|
assert!(matches!(
|
|
cache_invalidation(&base, &cache),
|
|
CacheInvalidation::All(value) if value == cache_identity
|
|
));
|
|
|
|
let mut operational = base.clone();
|
|
operational.vhosts[0].load_balancing.keepalive.enabled = false;
|
|
operational.vhosts[0].load_balancing.keepalive.idle_timeout_seconds = 90;
|
|
operational.vhosts[0].load_balancing.keepalive.max_idle_per_host = 32;
|
|
operational.vhosts[0].load_balancing.keepalive.tcp_keepalive_seconds = 90;
|
|
operational.vhosts[0].load_balancing.keepalive.pool_recycle_requests = 1_000;
|
|
operational.vhosts[0].load_balancing.keepalive.pool_recycle_seconds = 1_800;
|
|
operational.vhosts[0].load_balancing.keepalive.http1_max_buffer_bytes = 65_536;
|
|
operational.vhosts[0].backends[0].weight += 1;
|
|
operational.vhosts[0].backends[0].max_concurrent_requests = 16;
|
|
operational.vhosts[0].backends[0].queue_timeout_ms = 100;
|
|
operational.vhosts[0].timing_headers = true;
|
|
operational.vhosts[0].acl_profile_id = Some("test-only-acl".into());
|
|
operational.vhosts[0].user_agent_blocking = Default::default();
|
|
operational.vhosts[0].proxy_timeouts.read_timeout_seconds = Some(180);
|
|
assert_eq!(cache_revision(&operational), identity);
|
|
assert_eq!(vhost_cache_revision(&operational.vhosts[0]), vhost_cache_revision(&base.vhosts[0]));
|
|
assert!(matches!(cache_invalidation(&base, &operational), CacheInvalidation::None));
|
|
assert!(matches!(cache_invalidation(&operational, &base), CacheInvalidation::None));
|
|
|
|
let mut vhost = base.clone();
|
|
vhost.vhosts[0].backends[0].url = "http://127.0.0.1:9001".into();
|
|
assert_eq!(cache_revision(&vhost), identity);
|
|
let affected_id = base.vhosts[0].id.clone();
|
|
assert!(matches!(cache_invalidation(&base, &vhost), CacheInvalidation::Scopes(ids) if ids == vec![affected_id]));
|
|
|
|
// A content change must not invalidate another independent vhost.
|
|
let mut multiple = base.clone();
|
|
let mut another = multiple.vhosts[0].clone();
|
|
another.id = "other-scope".into();
|
|
another.frontend.hosts = vec!["other.example.test".into()];
|
|
multiple.vhosts.push(another);
|
|
let mut changed_one = multiple.clone();
|
|
changed_one.vhosts[0].backends[0].url = "http://127.0.0.1:9002".into();
|
|
assert!(matches!(cache_invalidation(&multiple, &changed_one), CacheInvalidation::Scopes(ids)
|
|
if ids == vec![base.vhosts[0].id.clone()]));
|
|
let mut changed_global = multiple.clone();
|
|
changed_global.transform.max_body_bytes += 1;
|
|
assert!(matches!(cache_invalidation(&multiple, &changed_global), CacheInvalidation::All(_)));
|
|
}
|
|
}
|