use super::*; #[test] fn tenant_configuration_rejects_unknown_controls_and_escaping_locations() { for tenant in [ serde_json::json!({"database":"missing"}), serde_json::json!({"database":"default","mode":"table"}), serde_json::json!({"database":"default","max_pools":0}), serde_json::json!({"database":"default","idle_timeout_ms":0}), serde_json::Value::Null, ] { let document = serde_json::json!({"database":{"default":{"type":"sqlite","path":"app.db","tenant_directory":"tenants"}}, "tenant":tenant}); assert!(Settings::load(&Document::parse(document.to_string()).unwrap()).is_err()); } for path in ["", "../tenants", "/tmp/tenants", "data/../tenants"] { let mut config = settings(true, 2); config.0.get_mut("default").unwrap().tenant_directory = Some(path.to_owned()); assert!(config.0["default"].validate().is_err()); } } #[test] fn overlapping_tenant_namespaces_and_platform_files_are_rejected() { let directory = Directory::new(); runtime() .run(async |scope| { let mut config = settings(true, 2); let mut secondary = config.0["default"].clone(); secondary.path = "secondary.db".to_owned(); secondary.tenant_directory = Some("tenants//".to_owned()); config.0.insert("secondary".to_owned(), secondary); let mut models = bindings(); models[0].database = Some("secondary"); assert_eq!( Registry::prepare(&directory.0, config, &models, scope) .await .err() .unwrap() .kind, Kind::Connection ); let mut config = settings(true, 2); config.0.get_mut("default").unwrap().path = "tenants/1.db".to_owned(); assert_eq!( Registry::prepare(&directory.0, config, &bindings(), scope) .await .err() .unwrap() .kind, Kind::Connection ); }) .unwrap(); } #[test] fn control_database_is_selected_explicitly_and_multiple_physical_sources_migrate() { let directory = Directory::new(); runtime().run(async |scope| { let mut config = settings(true, 1); let mut security = config.0["default"].clone(); security.path = "security.db".to_owned(); security.tenant_directory = Some("security-tenants".to_owned()); config.0.insert("security".to_owned(), security); config.1.as_mut().unwrap().database = "security".to_owned(); let registry = Registry::prepare(&directory.0, config, &bindings(), scope).await.unwrap(); registry.migrate_tenant(scope, 1).await.unwrap(); let mut context = Context::new(registry.clone()); context.select_tenant(scope, 1).await.unwrap(); let marker = context.control(scope).await.unwrap().query(scope, "SELECT COUNT(*) FROM _dever_tenant_storage WHERE ready=1 AND length(fingerprint)=64", vec![], 1, |row| row.get::<_, i64>(0)).await.unwrap(); assert_eq!(marker, [2]); assert!(registry.check_transactions(&[&[0,2]]).is_err()); assert!(context.select_tenant(scope, 2).await.is_err()); assert_eq!(context.tenant_id(), None); assert!(context.on(0, scope).await.is_err()); registry.close().await; assert!(directory.0.join("security-tenants/1.db").exists()); assert!(directory.0.join("tenants/1.db").exists()); }).unwrap(); }