initial commit
This commit is contained in:
commit
c260d7bab8
235 files changed
+49786
No files matched your search
+214
@@ -0,0 +1,214 @@
|
||||
use rust_xmpp::config::{self, Config};
|
||||
use serde_json::json;
|
||||
use std::path::Path;
|
||||
|
||||
fn lua(text: &str) -> anyhow::Result<Config> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let path = dir.path().join("config.lua");
|
||||
std::fs::write(&path, text)?;
|
||||
config::load(&path)
|
||||
}
|
||||
#[test]
|
||||
fn supplied_configuration_scopes_arithmetic_and_modules() {
|
||||
let cfg = config::load(Path::new("tests/fixtures/prosody.cfg.lua")).unwrap();
|
||||
assert_eq!(cfg.hosts.len(), 4);
|
||||
assert_eq!(
|
||||
cfg.option("wthome.ru", "authentication"),
|
||||
Some(&json!("internal_hashed"))
|
||||
);
|
||||
assert_eq!(
|
||||
cfg.option("upload.wthome.ru", "http_file_share_size_limit"),
|
||||
Some(&json!(10737418240_u64))
|
||||
);
|
||||
assert_eq!(
|
||||
cfg.option("upload.wthome.ru", "http_file_share_global_quota"),
|
||||
Some(&json!(107374182400_u64))
|
||||
);
|
||||
assert!(cfg.modules("wthome.ru").unwrap().contains("sasl2"));
|
||||
assert_eq!(
|
||||
cfg.modules("conference.wthome.ru")
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>(),
|
||||
vec!["muc", "muc_mam"]
|
||||
);
|
||||
assert_eq!(
|
||||
cfg.modules("upload.wthome.ru")
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>(),
|
||||
vec!["http_file_share"]
|
||||
);
|
||||
assert!(
|
||||
cfg.diagnostics()
|
||||
.iter()
|
||||
.any(|d| d.message.contains("security_labels"))
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn all_formats_round_trip_actual_config() {
|
||||
let c = config::load(Path::new("tests/fixtures/prosody.cfg.lua")).unwrap();
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
for (ext, text) in [
|
||||
("json", serde_json::to_string(&c).unwrap()),
|
||||
("yaml", serde_yaml_ng::to_string(&c).unwrap()),
|
||||
("toml", toml::to_string(&c).unwrap()),
|
||||
] {
|
||||
let p = dir.path().join(format!("c.{ext}"));
|
||||
std::fs::write(&p, text).unwrap();
|
||||
assert_eq!(
|
||||
serde_json::to_value(&c).unwrap(),
|
||||
serde_json::to_value(config::load(&p).unwrap()).unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn include_has_own_global_scope_and_parent_scope_is_restored() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
std::fs::write(
|
||||
dir.path().join("main.lua"),
|
||||
"VirtualHost 'one.test'\nInclude 'child.lua'\nname='one'",
|
||||
)
|
||||
.unwrap();
|
||||
std::fs::write(
|
||||
dir.path().join("child.lua"),
|
||||
"archive_expires_after='never'\nVirtualHost 'two.test'\nname='two'",
|
||||
)
|
||||
.unwrap();
|
||||
let c = config::load(&dir.path().join("main.lua")).unwrap();
|
||||
assert_eq!(c.global["archive_expires_after"], json!("never"));
|
||||
assert_eq!(c.hosts["one.test"].options["name"], json!("one"));
|
||||
assert_eq!(c.hosts["two.test"].options["name"], json!("two"));
|
||||
}
|
||||
#[test]
|
||||
fn include_cycles_rejected() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let p = dir.path().join("c.lua");
|
||||
std::fs::write(&p, "Include 'c.lua'").unwrap();
|
||||
assert!(config::load(&p).unwrap_err().to_string().contains("cycle"));
|
||||
}
|
||||
#[test]
|
||||
fn declarations_and_overrides() {
|
||||
let c=lua("modules_enabled={'roster','mam'}\nVirtualHost 'ONE.TEST' {modules_disabled={'mam'}}\nComponent 'muc.test' 'muc' {name='Rooms'}\nallow_registration=false").unwrap();
|
||||
assert_eq!(
|
||||
c.modules("one.test")
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>(),
|
||||
vec!["roster"]
|
||||
);
|
||||
assert_eq!(c.global["allow_registration"], json!(false));
|
||||
assert_eq!(c.hosts["muc.test"].component.as_deref(), Some("muc"));
|
||||
}
|
||||
#[test]
|
||||
fn runtime_capabilities_are_unavailable() {
|
||||
for source in [
|
||||
"os.execute('true')",
|
||||
"io.open('/etc/passwd')",
|
||||
"require('socket')",
|
||||
"RunScript 'x'",
|
||||
"Lua.os.execute('true')",
|
||||
] {
|
||||
assert!(lua(source).is_err(), "{source}");
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn loops_are_bounded() {
|
||||
assert!(
|
||||
lua("while true do end")
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("budget")
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn malformed_values_rejected() {
|
||||
for text in [
|
||||
"VirtualHost 'x.test'\nc2s_ports={0}",
|
||||
"VirtualHost 'x.test'\nc2s_ports={65536}",
|
||||
"VirtualHost 'x.test'\nc2s_ports={5222,5222}",
|
||||
"VirtualHost 'x.test'\nmodules_enabled='mam'",
|
||||
"VirtualHost 'x.test'\nallow_registration='false'",
|
||||
"VirtualHost 'x.test'\nComponent 'x.test' 'muc'",
|
||||
"VirtualHost '../x'",
|
||||
"VirtualHost 'x.test'\nx={ [2]='hole' }",
|
||||
"VirtualHost 'x.test'\nx={ 'item', key='value' }",
|
||||
] {
|
||||
assert!(lua(text).is_err(), "accepted {text}");
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn tables_cannot_recurse_forever() {
|
||||
assert!(lua("local t={}\nt.self=t\nVirtualHost 'x.test'\nx=t").is_err());
|
||||
}
|
||||
#[test]
|
||||
fn component_can_explicitly_enable_global_modules() {
|
||||
let c = lua("modules_enabled={'ping'}\nComponent 'muc.test' 'muc'\nload_global_modules=true")
|
||||
.unwrap();
|
||||
assert!(c.modules("muc.test").unwrap().contains("ping"));
|
||||
}
|
||||
#[test]
|
||||
fn storage_paths_encode_like_prosody() {
|
||||
use rust_xmpp::storage::encode_name;
|
||||
assert_eq!(encode_name("wthome.ru"), "wthome%2eru");
|
||||
assert_eq!(encode_name("../x_y"), "%2e%2e%2fx%5fy");
|
||||
assert_eq!(encode_name("я"), "%d1%8f");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn supplied_config_matches_original_prosody_loader() {
|
||||
// The original loader is run only as a reference in tests, with stubs for
|
||||
// helpers unused by this fixture. This is not a runtime dependency.
|
||||
let vm = mlua::Lua::new();
|
||||
vm.load(
|
||||
r#"
|
||||
package.preload['prosody.util.envload'] = function()
|
||||
return { envload=function(s,n,e) return load(s,n,'t',e) end }
|
||||
end
|
||||
package.preload['prosody.util.dependencies'] = function()
|
||||
return { softreq=function() return nil end }
|
||||
end
|
||||
package.preload['prosody.util.iterators'] = function() return {} end
|
||||
package.preload['prosody.util.paths'] = function()
|
||||
return { resolve_relative_path=function(p,f) return p..f end }
|
||||
end
|
||||
package.preload['prosody.util.debug'] = function()
|
||||
return { get_traceback_table=function() return {} end }
|
||||
end
|
||||
package.preload['prosody.util.error'] = function()
|
||||
return { is_error=function() return false end }
|
||||
end
|
||||
package.preload['prosody.util.logger'] = function()
|
||||
return { init=function() return function() end end }
|
||||
end
|
||||
"#,
|
||||
)
|
||||
.exec()
|
||||
.unwrap();
|
||||
let reference: mlua::Table = vm
|
||||
.load(include_str!("reference/configmanager.lua"))
|
||||
.eval()
|
||||
.unwrap();
|
||||
let load: mlua::Function = reference.get("load").unwrap();
|
||||
let (ok, _, _): (bool, mlua::Value, mlua::Value) = load
|
||||
.call(("tests/fixtures/prosody.cfg.lua", "lua"))
|
||||
.unwrap();
|
||||
assert!(ok);
|
||||
let get: mlua::Function = reference.get("getconfig").unwrap();
|
||||
let table: mlua::Table = get.call(()).unwrap();
|
||||
let parsed = config::load(Path::new("tests/fixtures/prosody.cfg.lua")).unwrap();
|
||||
let global: mlua::Value = table.get("*").unwrap();
|
||||
assert_eq!(
|
||||
rust_xmpp::lua::json_value(global, 0).unwrap(),
|
||||
json!(parsed.global)
|
||||
);
|
||||
for (name, host) in &parsed.hosts {
|
||||
let v: mlua::Value = table.get(name.as_str()).unwrap();
|
||||
let mut reference = rust_xmpp::lua::json_value(v, 0).unwrap();
|
||||
let object = reference.as_object_mut().unwrap();
|
||||
object.remove("defined");
|
||||
let component = object.remove("component_module");
|
||||
assert_eq!(component, host.component.as_ref().map(|v| json!(v)));
|
||||
assert_eq!(reference, json!(host.options));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user