mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
chore(repo): remove dead code and useless tests (#3375)
This commit is contained in:
1 parent
7e177a1c90
commit
1cd62eb661
1391 files changed
+783
-120415
No files matched your search
@@ -6,7 +6,6 @@ license.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
fluxer_common = { path = "../../fluxer_common" }
|
||||
anyhow = "1.0.104"
|
||||
axum = "0.8.9"
|
||||
clap = { version = "4.6.7", features = ["derive", "env"] }
|
||||
|
||||
@@ -111,17 +111,6 @@ fn ensure_desktop_dependencies() -> Result<()> {
|
||||
install_desktop_dependencies()
|
||||
}
|
||||
|
||||
pub fn typecheck_desktop() -> Result<()> {
|
||||
run_command(
|
||||
&["pnpm", "typecheck"],
|
||||
RunOptions {
|
||||
cwd: DESKTOP_DIR.as_path(),
|
||||
..RunOptions::default()
|
||||
},
|
||||
)
|
||||
.map(drop)
|
||||
}
|
||||
|
||||
pub fn development_version(now: SystemTime) -> String {
|
||||
let seconds = now
|
||||
.duration_since(UNIX_EPOCH)
|
||||
@@ -1135,215 +1124,3 @@ fn codesign_ad_hoc(app_bundle: &Path) -> Result<()> {
|
||||
String::from_utf8_lossy(&output.stderr).trim_end()
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn strips_no_sandbox_only_by_container_policy() {
|
||||
let args = electron_args(&["--flag".to_owned()]);
|
||||
if cfg!(target_os = "linux")
|
||||
&& Path::new("/.dockerenv").exists()
|
||||
&& env::var("FLUXER_ELECTRON_NO_SANDBOX").as_deref() != Ok("0")
|
||||
{
|
||||
assert_eq!(args[0], "--no-sandbox");
|
||||
}
|
||||
assert!(args.contains(&"--flag".to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn disclaimed_electron_command_re_execs_through_the_launcher() {
|
||||
let command = disclaimed_electron_command(
|
||||
Path::new("/tmp/fluxer-dev"),
|
||||
Path::new("/tmp/Electron.app/Contents/MacOS/Electron"),
|
||||
);
|
||||
assert_eq!(
|
||||
command,
|
||||
vec![
|
||||
"/tmp/fluxer-dev",
|
||||
"desktop",
|
||||
"exec-disclaimed",
|
||||
"/tmp/Electron.app/Contents/MacOS/Electron",
|
||||
"."
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dev_electron_paths_point_inside_the_dev_bundle() {
|
||||
assert!(dev_electron_binary_path().ends_with(
|
||||
"fluxer_desktop/node_modules/electron/dist/Electron.app/Contents/MacOS/Electron"
|
||||
));
|
||||
assert!(dev_electron_info_plist_path().ends_with(
|
||||
"fluxer_desktop/node_modules/electron/dist/Electron.app/Contents/Info.plist"
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dev_electron_usage_descriptions_include_audio_capture() {
|
||||
assert!(
|
||||
MACOS_DEV_ELECTRON_USAGE_DESCRIPTIONS
|
||||
.iter()
|
||||
.any(|(key, _)| *key == "NSAudioCaptureUsageDescription")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn development_version_is_a_calver_electron_builder_accepts() {
|
||||
let at = |seconds: u64| development_version(UNIX_EPOCH + Duration::from_secs(seconds));
|
||||
assert_eq!(at(1_791_039_600), "2026.1003.150000");
|
||||
assert_eq!(at(1_767_225_605), "2026.101.5");
|
||||
assert_eq!(at(1_798_761_599), "2026.1231.235959");
|
||||
assert_eq!(at(1_709_208_000), "2024.229.120000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_the_developer_id_identity_and_skips_other_certificates() {
|
||||
let output = r#" 1) D9E17CA1546F517C814DFA8719A4FED295D7B019 "Apple Development: Someone (TT9JK7QNP2)"
|
||||
2) AA2A51260E57959F00CF6B117CEA2757748756FA "Developer ID Application: Fluxer Platform AB (3G5837T29K)"
|
||||
2 valid identities found"#;
|
||||
assert_eq!(
|
||||
parse_developer_id_identity(output).as_deref(),
|
||||
Some("Fluxer Platform AB (3G5837T29K)")
|
||||
);
|
||||
assert_eq!(
|
||||
parse_developer_id_identity(" 0 valid identities found"),
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn electron_builder_packages_a_development_dir_for_the_host_without_notarizing() {
|
||||
let args = electron_builder_args(
|
||||
Path::new("/tmp/out"),
|
||||
"arm64",
|
||||
&MacSigning::DeveloperId("Fluxer Platform AB (3G5837T29K)".to_owned()),
|
||||
&[],
|
||||
);
|
||||
assert!(args.contains(&"--dir".to_owned()));
|
||||
assert!(args.contains(&"-c.mac.notarize=false".to_owned()));
|
||||
assert!(args.contains(&"-c.directories.output=/tmp/out".to_owned()));
|
||||
assert!(args.contains(&"--arm64".to_owned()));
|
||||
assert!(
|
||||
!args
|
||||
.iter()
|
||||
.any(|arg| arg.starts_with("-c.mac.sign.identity"))
|
||||
);
|
||||
let ad_hoc = electron_builder_args(Path::new("/tmp/out"), "x64", &MacSigning::AdHoc, &[]);
|
||||
assert!(ad_hoc.contains(&"-c.mac.sign.identity=-".to_owned()));
|
||||
assert!(ad_hoc.contains(&"--x64".to_owned()));
|
||||
let linux = electron_builder_args(
|
||||
Path::new("/tmp/out"),
|
||||
"x64",
|
||||
&MacSigning::AdHoc,
|
||||
&["--linux".to_owned()],
|
||||
);
|
||||
assert_eq!(linux.iter().filter(|arg| *arg == "--linux").count(), 1);
|
||||
assert!(!linux.contains(&"--mac".to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_a_development_app_that_claims_the_production_scheme() {
|
||||
assert!(
|
||||
verify_url_schemes(
|
||||
r#"[{"CFBundleURLName":"app.fluxer.development","CFBundleURLSchemes":["fluxer-development"]}]"#
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(
|
||||
verify_url_schemes(r#"[{"CFBundleURLSchemes":["fluxer-development","Fluxer"]}]"#)
|
||||
.is_err()
|
||||
);
|
||||
assert!(verify_url_schemes(r#"[{"CFBundleURLSchemes":["fluxer"]}]"#).is_err());
|
||||
assert!(verify_url_schemes("[]").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_info_must_match_the_renderer_delivery() {
|
||||
let info = |channel: &str, offline: bool, modules: bool| {
|
||||
format!(
|
||||
r#"{{"buildVersion":"2026.1003.150000","releaseChannel":"development","buildChannel":"{channel}","offlineBuild":{offline},"modulesEnabled":{modules}}}"#
|
||||
)
|
||||
};
|
||||
let check = |raw: String, version: &str, delivery| {
|
||||
verify_development_build_info(&raw, version, delivery).is_ok()
|
||||
};
|
||||
let version = "2026.1003.150000";
|
||||
assert!(check(
|
||||
info("development", true, false),
|
||||
version,
|
||||
RendererDelivery::Offline
|
||||
));
|
||||
assert!(check(
|
||||
info("development", false, true),
|
||||
version,
|
||||
RendererDelivery::Modules
|
||||
));
|
||||
assert!(!check(
|
||||
info("canary", false, true),
|
||||
version,
|
||||
RendererDelivery::Modules
|
||||
));
|
||||
assert!(!check(
|
||||
info("development", true, false),
|
||||
version,
|
||||
RendererDelivery::Modules
|
||||
));
|
||||
assert!(!check(
|
||||
info("development", false, true),
|
||||
version,
|
||||
RendererDelivery::Offline
|
||||
));
|
||||
assert!(!check(
|
||||
info("development", true, true),
|
||||
version,
|
||||
RendererDelivery::Modules
|
||||
));
|
||||
assert!(!check(
|
||||
info("development", false, true),
|
||||
"2026.1003.150001",
|
||||
RendererDelivery::Modules
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_only_the_exact_main_executable_of_the_installed_app() {
|
||||
let ps = " 501 /Applications/Fluxer Development.app/Contents/MacOS/Fluxer Development\n\
|
||||
502 /Applications/Fluxer Development.app/Contents/Frameworks/Fluxer Development Helper.app/Contents/MacOS/Fluxer Development Helper\n\
|
||||
503 /Applications/Fluxer Canary.app/Contents/MacOS/Fluxer Canary\n\
|
||||
504 /tmp/copy/Fluxer Development.app/Contents/MacOS/Fluxer Development\n";
|
||||
assert_eq!(
|
||||
parse_pids_for_executable(
|
||||
ps,
|
||||
"/Applications/Fluxer Development.app/Contents/MacOS/Fluxer Development"
|
||||
),
|
||||
vec![501]
|
||||
);
|
||||
assert!(
|
||||
parse_pids_for_executable(ps, "/Applications/Fluxer.app/Contents/MacOS/Fluxer")
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn installs_under_the_development_bundle_name_only() {
|
||||
let app = installed_app_path(Path::new(DEFAULT_INSTALL_DIR));
|
||||
assert_eq!(app, Path::new("/Applications/Fluxer Development.app"));
|
||||
assert_eq!(
|
||||
app_executable_path(&app),
|
||||
Path::new("/Applications/Fluxer Development.app/Contents/MacOS/Fluxer Development")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn renderer_tree_must_be_complete_and_free_of_service_workers() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
assert!(verify_renderer_tree(dir.path()).is_err());
|
||||
fs::write(dir.path().join("index.html"), "<!doctype html>").unwrap();
|
||||
fs::create_dir(dir.path().join("assets")).unwrap();
|
||||
assert!(verify_renderer_tree(dir.path()).is_ok());
|
||||
fs::write(dir.path().join("sw.js"), "").unwrap();
|
||||
assert!(verify_renderer_tree(dir.path()).is_err());
|
||||
}
|
||||
}
|
||||
@@ -607,113 +607,3 @@ pub fn publish_renderer_modules(
|
||||
ensure_pkgs_server()?;
|
||||
verify_served_manifest(target, metadata_version)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn metadata_version_always_rises_above_the_live_feed() {
|
||||
assert_eq!(next_metadata_version(100, 50, None), 100);
|
||||
assert_eq!(next_metadata_version(100, 150, None), 150);
|
||||
assert_eq!(next_metadata_version(100, 50, Some(120)), 121);
|
||||
assert_eq!(next_metadata_version(100, 50, Some(99)), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn packed_module_stamps_round_trip() {
|
||||
let stamp = PackedModulesStamp {
|
||||
fingerprint: "abc".to_owned(),
|
||||
version: "2026.1005.171400".to_owned(),
|
||||
pub_date: "2026-10-05T17:14:00Z".to_owned(),
|
||||
};
|
||||
assert_eq!(PackedModulesStamp::parse(&stamp.render()), Some(stamp));
|
||||
assert_eq!(PackedModulesStamp::parse("abc 2026.1005.1"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formats_pub_dates_as_rfc3339_utc() {
|
||||
let at = UNIX_EPOCH + std::time::Duration::from_secs(1_791_220_440);
|
||||
assert_eq!(rfc3339_utc(at), "2026-10-05T17:14:00Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn publishes_one_coordinate_and_restamps_only_on_change() {
|
||||
let temp = tempfile::tempdir().unwrap();
|
||||
let payload = temp.path().join("payload");
|
||||
let root = temp.path().join("root");
|
||||
let package_dir = payload.join("development/modules/fluxer_renderer");
|
||||
let package_bytes = b"renderer";
|
||||
let digest = Sha256::digest(package_bytes)
|
||||
.iter()
|
||||
.map(|byte| format!("{byte:02x}"))
|
||||
.collect::<String>();
|
||||
fs::create_dir_all(package_dir.join(&digest)).unwrap();
|
||||
fs::write(
|
||||
package_dir.join(&digest).join(MODULE_PACKAGE_NAME),
|
||||
package_bytes,
|
||||
)
|
||||
.unwrap();
|
||||
let manifest = serde_json::json!({
|
||||
"release_channel": "development",
|
||||
"metadata_version": 10,
|
||||
"modules": {
|
||||
"fluxer_renderer": {
|
||||
"sha256": digest,
|
||||
"bytes": package_bytes.len(),
|
||||
"url": format!("{DEVELOPMENT_PACKAGE_ORIGIN}/desktop/development/modules/fluxer_renderer/{digest}/package.br"),
|
||||
}
|
||||
}
|
||||
});
|
||||
let manifest_dir = payload.join("development/darwin/arm64");
|
||||
fs::create_dir_all(&manifest_dir).unwrap();
|
||||
fs::write(
|
||||
manifest_dir.join(CHANNEL_MANIFEST_NAME),
|
||||
manifest.to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
let stamp = PackedModulesStamp {
|
||||
fingerprint: "f".to_owned(),
|
||||
version: "2026.1005.1".to_owned(),
|
||||
pub_date: "2026-10-05T00:00:00Z".to_owned(),
|
||||
};
|
||||
let target = ModuleCoordinate {
|
||||
channel: "development".to_owned(),
|
||||
platform: "darwin".to_owned(),
|
||||
arch: "arm64".to_owned(),
|
||||
};
|
||||
let first = publish_modules(&payload, &root, &stamp, &target).unwrap();
|
||||
assert!(first > 10);
|
||||
assert!(
|
||||
root.join(format!(
|
||||
"desktop/development/modules/fluxer_renderer/{digest}/package.br"
|
||||
))
|
||||
.is_file()
|
||||
);
|
||||
assert!(
|
||||
root.join("desktop/development/darwin/arm64/2026.1005.1/modules.json")
|
||||
.is_file()
|
||||
);
|
||||
assert_eq!(
|
||||
publish_modules(&payload, &root, &stamp, &target).unwrap(),
|
||||
first
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn refuses_a_manifest_whose_package_is_not_at_its_content_address() {
|
||||
let temp = tempfile::tempdir().unwrap();
|
||||
let manifest = serde_json::json!({
|
||||
"modules": {
|
||||
"fluxer_renderer": {
|
||||
"sha256": "00".repeat(32),
|
||||
"bytes": 1,
|
||||
"url": "https://pkgs.fluxer.com/desktop/development/modules/fluxer_renderer/x/package.br",
|
||||
}
|
||||
}
|
||||
});
|
||||
let error = verify_manifest_packages(temp.path(), "development", &manifest, Path::new("m"))
|
||||
.unwrap_err();
|
||||
assert!(error.to_string().contains("not its content address"));
|
||||
}
|
||||
}
|
||||
+1
-270
@@ -14,7 +14,7 @@ use crate::proc::{
|
||||
};
|
||||
use anyhow::{Context, Result, bail};
|
||||
use std::collections::{BTreeMap, VecDeque};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
use std::time::{Duration, Instant};
|
||||
use tokio::time::sleep;
|
||||
@@ -416,12 +416,6 @@ pub fn task_table() -> Result<BTreeMap<&'static str, DevTask>> {
|
||||
args: strings(&["cargo", "run", "-p", "fluxer_app_proxy"]),
|
||||
cwd: ROOT.clone(),
|
||||
env: vec![
|
||||
(
|
||||
"DISCOVERY_UPSTREAM_URL".to_owned(),
|
||||
Some(format!(
|
||||
"http://{LOOPBACK_HOST}:{DEV_PROXY_PORT}/api/.well-known/fluxer"
|
||||
)),
|
||||
),
|
||||
(
|
||||
"FLUXER_APP_PROXY_INDEX_UPSTREAM_URL".to_owned(),
|
||||
Some(format!("http://{LOOPBACK_HOST}:{APP_PORT}/")),
|
||||
@@ -906,266 +900,3 @@ fn check_startup_task_processes(
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn _cwd_is_root(path: &Path) -> bool {
|
||||
path == ROOT.as_path()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn default_tasks_use_lightweight_gateway() {
|
||||
assert_eq!(
|
||||
DEFAULT_TASKS,
|
||||
&[
|
||||
"proxy",
|
||||
"services",
|
||||
"media",
|
||||
"push",
|
||||
"admin",
|
||||
"api",
|
||||
"gateway-single",
|
||||
"worker",
|
||||
"app",
|
||||
"app-proxy"
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cloudflare_tunnel_task_is_deferred_until_after_stack_tasks() {
|
||||
let selected = normalize_selected_tasks(
|
||||
DEFAULT_TASKS
|
||||
.iter()
|
||||
.map(|name| (*name).to_owned())
|
||||
.collect(),
|
||||
true,
|
||||
);
|
||||
assert_eq!(
|
||||
selected.last().map(String::as_str),
|
||||
Some(CLOUDFLARE_TUNNEL_TASK)
|
||||
);
|
||||
assert_eq!(selected[..DEFAULT_TASKS.len()], *DEFAULT_TASKS);
|
||||
|
||||
let selected = normalize_selected_tasks(
|
||||
vec![
|
||||
CLOUDFLARE_TUNNEL_TASK.to_owned(),
|
||||
"proxy".to_owned(),
|
||||
"media".to_owned(),
|
||||
],
|
||||
false,
|
||||
);
|
||||
assert_eq!(
|
||||
selected,
|
||||
vec![
|
||||
"proxy".to_owned(),
|
||||
"media".to_owned(),
|
||||
CLOUDFLARE_TUNNEL_TASK.to_owned()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn js_dependency_preflight_only_runs_for_js_tasks() {
|
||||
assert!(selected_needs_js_dependency_preflight(&["api".to_owned()]));
|
||||
assert!(selected_needs_js_dependency_preflight(&[
|
||||
"worker".to_owned()
|
||||
]));
|
||||
assert!(selected_needs_js_dependency_preflight(&["app".to_owned()]));
|
||||
assert!(selected_needs_js_dependency_preflight(
|
||||
&["admin".to_owned()]
|
||||
));
|
||||
assert!(!selected_needs_js_dependency_preflight(&[
|
||||
"proxy".to_owned(),
|
||||
"gateway".to_owned(),
|
||||
"media".to_owned()
|
||||
]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn object_store_preflight_runs_for_upload_capable_tasks() {
|
||||
assert!(selected_needs_object_store(&["api".to_owned()]));
|
||||
assert!(selected_needs_object_store(&["worker".to_owned()]));
|
||||
assert!(selected_needs_object_store(&["media".to_owned()]));
|
||||
assert!(!selected_needs_object_store(&[
|
||||
"proxy".to_owned(),
|
||||
"gateway".to_owned(),
|
||||
"app".to_owned()
|
||||
]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn task_table_contains_recursive_binary_tasks() {
|
||||
let tasks = task_table().unwrap();
|
||||
let expected_public_url = public_url();
|
||||
let expected_app_port = APP_PORT.to_string();
|
||||
let expected_admin_port = ADMIN_PORT.to_string();
|
||||
let expected_app_upstream_url = format!("http://{LOOPBACK_HOST}:{APP_PORT}/");
|
||||
assert!(tasks["proxy"].args.ends_with(&["proxy".to_owned()]));
|
||||
assert!(
|
||||
tasks["gateway-single"]
|
||||
.args
|
||||
.ends_with(&["gateway".to_owned(), "single".to_owned()])
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["gateway"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "FLUXER_DISABLE_RATE_LIMITS")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some("true")
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["gateway-single"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "FLUXER_DISABLE_RATE_LIMITS")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some("true")
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["api"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "FLUXER_S3_PUBLIC_ENDPOINT")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some(expected_public_url.as_str())
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["api"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "FLUXER_S3_FORCE_PATH_STYLE")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some("true")
|
||||
);
|
||||
assert!(crate::manifest::PROXY_ROUTES.iter().any(|route| {
|
||||
route.prefix == "/fluxer-uploads" && route.host == LOOPBACK_HOST && route.port == 8333
|
||||
}));
|
||||
assert!(crate::manifest::PROXY_ROUTES.iter().any(|route| {
|
||||
route.prefix == "/admin"
|
||||
&& route.host == LOOPBACK_HOST
|
||||
&& route.port == ADMIN_PORT
|
||||
&& route.strip_prefix
|
||||
}));
|
||||
assert_eq!(
|
||||
tasks["app"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "FLUXER_APP_DEV_PORT")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some(expected_app_port.as_str())
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["app"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "FLUXER_STATIC_CDN_ENDPOINT")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some(expected_public_url.as_str())
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["app-proxy"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "FLUXER_APP_PROXY_INDEX_UPSTREAM_URL")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some(expected_app_upstream_url.as_str())
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["app"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "PUBLIC_STATIC_CDN_ENDPOINT")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some(expected_public_url.as_str())
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["app-proxy"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "RELEASE_CHANNEL")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some("canary")
|
||||
);
|
||||
assert!(tasks["media"].args.starts_with(&[
|
||||
"cargo".to_owned(),
|
||||
"run".to_owned(),
|
||||
"-p".to_owned(),
|
||||
"fluxer-media-proxy".to_owned()
|
||||
]));
|
||||
assert!(tasks["push"].args.starts_with(&[
|
||||
"cargo".to_owned(),
|
||||
"run".to_owned(),
|
||||
"-p".to_owned(),
|
||||
"fluxer-push".to_owned()
|
||||
]));
|
||||
assert!(
|
||||
tasks["push"]
|
||||
.args
|
||||
.ends_with(&["--port".to_owned(), PUSH_PORT.to_string()])
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["admin"].args,
|
||||
vec![
|
||||
"cargo".to_owned(),
|
||||
"watch".to_owned(),
|
||||
"--no-dot-ignores".to_owned(),
|
||||
"-w".to_owned(),
|
||||
"fluxer_admin/src".to_owned(),
|
||||
"-w".to_owned(),
|
||||
"fluxer_admin/Cargo.toml".to_owned(),
|
||||
"-w".to_owned(),
|
||||
"fluxer_admin/build.rs".to_owned(),
|
||||
"-w".to_owned(),
|
||||
"fluxer_admin/openapi-admin.json".to_owned(),
|
||||
"-w".to_owned(),
|
||||
"fluxer_admin/static".to_owned(),
|
||||
"-x".to_owned(),
|
||||
"run -p fluxer_admin".to_owned()
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["admin"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "FLUXER_ADMIN_BASE_PATH")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some("/admin")
|
||||
);
|
||||
assert_eq!(
|
||||
tasks["admin"]
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, _)| key == "FLUXER_ADMIN_PORT")
|
||||
.unwrap()
|
||||
.1
|
||||
.as_deref(),
|
||||
Some(expected_admin_port.as_str())
|
||||
);
|
||||
assert!(tasks.contains_key(CLOUDFLARE_TUNNEL_TASK));
|
||||
}
|
||||
}
|
||||
@@ -117,102 +117,3 @@ fn parse_env_value(mut value: &str) -> String {
|
||||
}
|
||||
value.to_owned()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn parses_env_values_with_shell_like_comments() {
|
||||
assert_eq!(parse_env_value("'quoted'"), "quoted");
|
||||
assert_eq!(parse_env_value("\"quoted\""), "quoted");
|
||||
assert_eq!(parse_env_value("value # comment"), "value");
|
||||
assert_eq!(parse_env_value("value#not-comment"), "value#not-comment");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_exports_and_reports_invalid_lines() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let file = dir.path().join("env");
|
||||
std::fs::write(
|
||||
&file,
|
||||
"\n# comment\nexport A=1\nB='two words'\nC=value # trailing\n",
|
||||
)
|
||||
.unwrap();
|
||||
let values = read_env_file(&file).unwrap();
|
||||
assert_eq!(values.get("A").unwrap(), "1");
|
||||
assert_eq!(values.get("B").unwrap(), "two words");
|
||||
assert_eq!(values.get("C").unwrap(), "value");
|
||||
|
||||
std::fs::write(&file, "nope\n").unwrap();
|
||||
assert!(
|
||||
read_env_file(&file)
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("Invalid env line")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_env_overrides_injected_development_defaults() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let development = dir.path().join("development.env");
|
||||
let local = dir.path().join("local.env");
|
||||
let root_local = dir.path().join(".env.local");
|
||||
std::fs::write(&development, "A=default\nB=default\nC=default\n").unwrap();
|
||||
std::fs::write(&local, "A=local\n").unwrap();
|
||||
std::fs::write(&root_local, "B=root\n").unwrap();
|
||||
let current = BTreeMap::from([
|
||||
("A".to_owned(), "default".to_owned()),
|
||||
("B".to_owned(), "custom".to_owned()),
|
||||
("C".to_owned(), "default".to_owned()),
|
||||
]);
|
||||
let merged = merge_default_env_with_current_and_baseline(
|
||||
&development,
|
||||
&local,
|
||||
&root_local,
|
||||
current,
|
||||
BTreeMap::new(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(merged.get("A").map(String::as_str), Some("local"));
|
||||
assert_eq!(merged.get("B").map(String::as_str), Some("custom"));
|
||||
assert_eq!(merged.get("C").map(String::as_str), Some("default"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stale_container_defaults_yield_to_file_overrides() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let development = dir.path().join("development.env");
|
||||
let local = dir.path().join("local.env");
|
||||
let root_local = dir.path().join(".env.local");
|
||||
std::fs::write(
|
||||
&development,
|
||||
"A=new-default\nB=new-default\nC=new-default\n",
|
||||
)
|
||||
.unwrap();
|
||||
std::fs::write(&local, "A=local\nC=local\n").unwrap();
|
||||
std::fs::write(&root_local, "").unwrap();
|
||||
let baseline = BTreeMap::from([
|
||||
("A".to_owned(), "old-default".to_owned()),
|
||||
("B".to_owned(), "old-default".to_owned()),
|
||||
("C".to_owned(), "old-default".to_owned()),
|
||||
]);
|
||||
let current = BTreeMap::from([
|
||||
("A".to_owned(), "old-default".to_owned()),
|
||||
("B".to_owned(), "custom".to_owned()),
|
||||
("C".to_owned(), "old-default".to_owned()),
|
||||
]);
|
||||
let merged = merge_default_env_with_current_and_baseline(
|
||||
&development,
|
||||
&local,
|
||||
&root_local,
|
||||
current,
|
||||
baseline,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(merged.get("A").map(String::as_str), Some("local"));
|
||||
assert_eq!(merged.get("B").map(String::as_str), Some("custom"));
|
||||
assert_eq!(merged.get("C").map(String::as_str), Some("local"));
|
||||
}
|
||||
}
|
||||
+4
-164
@@ -727,7 +727,7 @@ fn cmdline_has_managed_gateway_config(args: &[String]) -> bool {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", test))]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn cmdline_has_gateway_node(
|
||||
args: &[String],
|
||||
node_names: &std::collections::HashSet<String>,
|
||||
@@ -746,7 +746,7 @@ fn proc_cmdline(pid: i32) -> Vec<String> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", test))]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn parse_proc_stat_state_and_pgid(stat: &str) -> Option<(char, i32)> {
|
||||
let (_, after_comm) = stat.rsplit_once(')')?;
|
||||
let mut fields = after_comm.split_ascii_whitespace();
|
||||
@@ -766,13 +766,13 @@ fn parse_proc_stat_process(stat: &str) -> Option<(char, i32, i32, u64)> {
|
||||
Some((state, ppid, pgid, parse_proc_stat_starttime(stat)?))
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", test))]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn parse_proc_stat_starttime(stat: &str) -> Option<u64> {
|
||||
let (_, after_comm) = stat.rsplit_once(')')?;
|
||||
after_comm.split_ascii_whitespace().nth(19)?.parse().ok()
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", test))]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn proc_stat_state_is_dead(state: char) -> bool {
|
||||
state == 'Z' || state == 'X' || state == 'x'
|
||||
}
|
||||
@@ -1004,163 +1004,3 @@ pub fn build_gateway_command(config_dir: &Path) -> Result<Vec<String>> {
|
||||
]);
|
||||
Ok(args)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn builds_default_cluster_nodes() {
|
||||
let nodes = build_gateway_cluster_nodes().unwrap();
|
||||
assert_eq!(nodes.len(), 18);
|
||||
assert_eq!(nodes[0].name(), "websocket-1");
|
||||
assert_eq!(nodes[0].http_port, 8771);
|
||||
assert_eq!(nodes[17].name(), "push-3");
|
||||
assert_eq!(nodes[17].dist_port, 9018);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn node_env_contains_role_port_and_static_peers() {
|
||||
let node = GatewayNode {
|
||||
role: "calls".to_owned(),
|
||||
ordinal: 2,
|
||||
http_port: 8811,
|
||||
dist_port: 9014,
|
||||
};
|
||||
let env = gateway_node_env(&node, "a,b");
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(key, value)| key == "FLUXER_GATEWAY_ROLE"
|
||||
&& value.as_deref() == Some("calls"))
|
||||
);
|
||||
assert!(
|
||||
env.iter().any(
|
||||
|(key, value)| key == "FLUXER_GATEWAY_PORT" && value.as_deref() == Some("8811")
|
||||
)
|
||||
);
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(key, value)| key == "FLUXER_GATEWAY_CLUSTER_STATIC_PEERS"
|
||||
&& value.as_deref() == Some("a,b"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmdline_gateway_node_detection_matches_exact_name_argument() {
|
||||
let node_names =
|
||||
std::collections::HashSet::from([String::from("[email protected]")]);
|
||||
|
||||
assert!(cmdline_has_gateway_node(
|
||||
&strings(&[
|
||||
"/usr/local/bin/beam.smp",
|
||||
"-name",
|
||||
"[email protected]"
|
||||
]),
|
||||
&node_names
|
||||
));
|
||||
assert!(!cmdline_has_gateway_node(
|
||||
&strings(&[
|
||||
"/usr/local/bin/beam.smp",
|
||||
"-sname",
|
||||
"[email protected]"
|
||||
]),
|
||||
&node_names
|
||||
));
|
||||
assert!(!cmdline_has_gateway_node(
|
||||
&strings(&[
|
||||
"/usr/local/bin/beam.smp",
|
||||
"-name",
|
||||
"[email protected]"
|
||||
]),
|
||||
&node_names
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proc_stat_parsing_extracts_state_and_pgid() {
|
||||
assert_eq!(
|
||||
parse_proc_stat_state_and_pgid("1234 (beam.smp) S 1 1234 1234 0 -1 4194560 0"),
|
||||
Some(('S', 1234))
|
||||
);
|
||||
assert_eq!(
|
||||
parse_proc_stat_state_and_pgid("77 (erl_child_setup) R 42 42 9000 0 -1"),
|
||||
Some(('R', 42))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proc_stat_parsing_handles_parentheses_and_spaces_in_comm() {
|
||||
assert_eq!(
|
||||
parse_proc_stat_state_and_pgid("99 (weird) comm (name) Z 1 42 42 0 -1"),
|
||||
Some(('Z', 42))
|
||||
);
|
||||
assert_eq!(
|
||||
parse_proc_stat_state_and_pgid("99 (spaced comm) T 1 99 99 0 -1"),
|
||||
Some(('T', 99))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proc_stat_parsing_rejects_malformed_lines() {
|
||||
assert_eq!(parse_proc_stat_state_and_pgid(""), None);
|
||||
assert_eq!(parse_proc_stat_state_and_pgid("1234 (beam.smp)"), None);
|
||||
assert_eq!(parse_proc_stat_state_and_pgid("1234 (beam.smp) S"), None);
|
||||
assert_eq!(parse_proc_stat_state_and_pgid("1234 (beam.smp) S 1"), None);
|
||||
assert_eq!(
|
||||
parse_proc_stat_state_and_pgid("1234 (beam.smp) S 1 not-a-pgid"),
|
||||
None
|
||||
);
|
||||
assert_eq!(parse_proc_stat_state_and_pgid("no comm field here"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proc_stat_parsing_extracts_starttime() {
|
||||
let stat =
|
||||
"1234 (beam.smp) S 1 1234 1234 0 -1 4194560 0 0 0 0 5 3 0 0 20 0 30 0 12345678 4096";
|
||||
assert_eq!(parse_proc_stat_starttime(stat), Some(12_345_678));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proc_stat_starttime_parsing_handles_parentheses_and_spaces_in_comm() {
|
||||
let stat =
|
||||
"99 (weird) comm (name) S 1 42 42 0 -1 4194560 0 0 0 0 5 3 0 0 20 0 30 0 777 4096";
|
||||
assert_eq!(parse_proc_stat_starttime(stat), Some(777));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proc_stat_starttime_parsing_rejects_truncated_lines() {
|
||||
assert_eq!(parse_proc_stat_starttime(""), None);
|
||||
assert_eq!(parse_proc_stat_starttime("1234 (beam.smp)"), None);
|
||||
assert_eq!(
|
||||
parse_proc_stat_starttime("1234 (beam.smp) S 1 1234 1234 0 -1 4194560 0"),
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
parse_proc_stat_starttime(
|
||||
"1234 (beam.smp) S 1 1234 1234 0 -1 4194560 0 0 0 0 5 3 0 0 20 0 30 0 not-a-number"
|
||||
),
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zombie_and_reaped_states_count_as_dead() {
|
||||
assert!(proc_stat_state_is_dead('Z'));
|
||||
assert!(proc_stat_state_is_dead('X'));
|
||||
assert!(proc_stat_state_is_dead('x'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn live_states_do_not_count_as_dead() {
|
||||
assert!(!proc_stat_state_is_dead('R'));
|
||||
assert!(!proc_stat_state_is_dead('S'));
|
||||
assert!(!proc_stat_state_is_dead('D'));
|
||||
assert!(!proc_stat_state_is_dead('T'));
|
||||
assert!(!proc_stat_state_is_dead('t'));
|
||||
assert!(!proc_stat_state_is_dead('I'));
|
||||
}
|
||||
|
||||
fn strings(values: &[&str]) -> Vec<String> {
|
||||
values.iter().map(|value| (*value).to_owned()).collect()
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ pub mod disclaim;
|
||||
pub mod env;
|
||||
pub mod gateway;
|
||||
pub mod manifest;
|
||||
pub mod media_external;
|
||||
pub mod media_proxy;
|
||||
pub mod object_store;
|
||||
pub mod paths;
|
||||
|
||||
+1
-23
@@ -2,13 +2,10 @@
|
||||
|
||||
use anyhow::{Context, Result, bail};
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use fluxer_dev::cassandra::{
|
||||
apply_schema, compute_diff, render_target_schema, verify_schema, write_diff_file,
|
||||
};
|
||||
use fluxer_dev::cassandra::{apply_schema, compute_diff, verify_schema, write_diff_file};
|
||||
use fluxer_dev::desktop::{
|
||||
DEFAULT_INSTALL_DIR, DesktopAppOptions, RendererDelivery, build_desktop, desktop_app,
|
||||
install_desktop_app, install_desktop_dependencies, package_desktop, run_desktop,
|
||||
typecheck_desktop,
|
||||
};
|
||||
use fluxer_dev::env::merge_default_env_with_current;
|
||||
use fluxer_dev::manifest::{DEV_PROXY_PORT, LOCAL_APP_URL};
|
||||
@@ -114,7 +111,6 @@ enum CassandraCommand {
|
||||
},
|
||||
Apply,
|
||||
Verify,
|
||||
TargetSchema,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
@@ -132,7 +128,6 @@ enum DesktopCommand {
|
||||
#[arg(long)]
|
||||
skip_native: bool,
|
||||
},
|
||||
Typecheck,
|
||||
Pkgs,
|
||||
Package {
|
||||
#[arg(long)]
|
||||
@@ -194,8 +189,6 @@ enum MediaProxyCommand {
|
||||
#[arg(long)]
|
||||
path: Option<String>,
|
||||
},
|
||||
RustStressSmoke,
|
||||
SignExternalUrl(fluxer_dev::media_external::SignExternalUrlArgs),
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
@@ -279,7 +272,6 @@ async fn main() -> Result<()> {
|
||||
apply_schema(None).await?;
|
||||
}
|
||||
CassandraCommand::Verify => verify_schema(None, None).await?,
|
||||
CassandraCommand::TargetSchema => print!("{}", render_target_schema("fluxer")),
|
||||
},
|
||||
Command::Desktop(args) => match args.command {
|
||||
DesktopCommand::Deps => install_desktop_dependencies()?,
|
||||
@@ -292,7 +284,6 @@ async fn main() -> Result<()> {
|
||||
RendererDelivery::Offline,
|
||||
)?),
|
||||
DesktopCommand::Pkgs => fluxer_dev::desktop_modules::ensure_pkgs_server()?,
|
||||
DesktopCommand::Typecheck => typecheck_desktop()?,
|
||||
DesktopCommand::Package {
|
||||
rebuild_renderer,
|
||||
ad_hoc,
|
||||
@@ -341,19 +332,6 @@ async fn main() -> Result<()> {
|
||||
fluxer_dev::media_proxy::run_dev_media_doctor(repair, &base_url, path.as_deref())
|
||||
.await?;
|
||||
}
|
||||
MediaProxyCommand::RustStressSmoke => {
|
||||
fluxer_dev::media_proxy::run_rust_stress_smoke()?;
|
||||
}
|
||||
MediaProxyCommand::SignExternalUrl(args) => {
|
||||
println!(
|
||||
"{}",
|
||||
fluxer_dev::media_external::sign_external_url(
|
||||
&args.secret_key,
|
||||
&args.server_url,
|
||||
&args.upstream
|
||||
)?
|
||||
);
|
||||
}
|
||||
},
|
||||
Command::Tunnel(args) => match args.command {
|
||||
TunnelCommand::Configure { public_url, token } => {
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use clap::Args;
|
||||
|
||||
#[derive(Debug, Clone, Args)]
|
||||
pub struct SignExternalUrlArgs {
|
||||
#[arg(long)]
|
||||
pub secret_key: String,
|
||||
#[arg(long)]
|
||||
pub server_url: String,
|
||||
pub upstream: String,
|
||||
}
|
||||
|
||||
pub fn sign_external_url(secret_key: &str, server_url: &str, upstream: &str) -> Result<String> {
|
||||
fluxer_common::external_media_path::build_external_media_proxy_url(
|
||||
server_url.trim_end_matches('/'),
|
||||
upstream,
|
||||
secret_key.as_bytes(),
|
||||
)
|
||||
.context("failed to build the external media proxy url")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn signs_external_urls_with_urlsafe_components() {
|
||||
let signed = sign_external_url(
|
||||
"benchmark-secret",
|
||||
"http://127.0.0.1:19110/",
|
||||
"https://example.test/a b.jpg",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(signed.starts_with("http://127.0.0.1:19110/external/"));
|
||||
assert!(signed.ends_with("/https/example.test/a%20b.jpg"));
|
||||
assert_eq!(
|
||||
"https://example.test/a b.jpg",
|
||||
fluxer_common::external_media_path::reconstruct_original_url(
|
||||
signed
|
||||
.split_once("/external/")
|
||||
.unwrap()
|
||||
.1
|
||||
.split_once('/')
|
||||
.unwrap()
|
||||
.1
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -64,63 +64,6 @@ pub async fn ensure_dev_object_store(repair: bool, repair_timeout_secs: u64) ->
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_rust_stress_smoke() -> Result<()> {
|
||||
crate::proc::run(&["cargo", "test", "-p", "fluxer-media-proxy"])?;
|
||||
crate::proc::run(&[
|
||||
"cargo",
|
||||
"bench",
|
||||
"-p",
|
||||
"fluxer-media-proxy",
|
||||
"--bench",
|
||||
"core",
|
||||
"--",
|
||||
"--sample-size",
|
||||
"10",
|
||||
"--warm-up-time",
|
||||
"1",
|
||||
"--measurement-time",
|
||||
"1",
|
||||
])?;
|
||||
|
||||
if which("cargo-fuzz").is_none() {
|
||||
eprintln!("cargo-fuzz not installed; skipping fuzz smoke");
|
||||
return Ok(());
|
||||
}
|
||||
let use_nightly = rustup_has_nightly();
|
||||
for target in ["parsers", "signing_external_path", "thumbhash"] {
|
||||
run_fuzz_smoke(target, use_nightly)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn rustup_has_nightly() -> bool {
|
||||
let Ok(output) = Command::new("rustup").args(["toolchain", "list"]).output() else {
|
||||
return false;
|
||||
};
|
||||
if !output.status.success() {
|
||||
return false;
|
||||
}
|
||||
String::from_utf8_lossy(&output.stdout)
|
||||
.lines()
|
||||
.any(|line| line.starts_with("nightly"))
|
||||
}
|
||||
|
||||
fn run_fuzz_smoke(target: &str, use_nightly: bool) -> Result<()> {
|
||||
if use_nightly {
|
||||
crate::proc::run(&[
|
||||
"cargo",
|
||||
"+nightly",
|
||||
"fuzz",
|
||||
"run",
|
||||
target,
|
||||
"--",
|
||||
"-runs=1000",
|
||||
])
|
||||
} else {
|
||||
crate::proc::run(&["cargo", "fuzz", "run", target, "--", "-runs=1000"])
|
||||
}
|
||||
}
|
||||
|
||||
fn start_dev_seaweedfs() -> Result<()> {
|
||||
ensure_writable_dev_paths()?;
|
||||
if tcp_reachable(DEV_S3_HOST, DEV_S3_PORT) {
|
||||
|
||||
@@ -178,29 +178,3 @@ pub async fn bootstrap_schema() -> Result<()> {
|
||||
fn cassandra_backend_enabled() -> bool {
|
||||
env::var("FLUXER_DATABASE_BACKEND").as_deref() == Ok("cassandra")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn s3_env_uses_fluxer_defaults() {
|
||||
let env = s3_env();
|
||||
assert!(env.iter().any(
|
||||
|(key, value)| key == "AWS_DEFAULT_REGION" && value.as_deref() == Some("us-east-1")
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bucket_already_exists_output_matches_aws_errors() {
|
||||
assert!(s3_bucket_already_exists_output(
|
||||
"An error occurred (BucketAlreadyExists) when calling the CreateBucket operation"
|
||||
));
|
||||
assert!(s3_bucket_already_exists_output(
|
||||
"An error occurred (BucketAlreadyOwnedByYou) when calling the CreateBucket operation"
|
||||
));
|
||||
assert!(!s3_bucket_already_exists_output(
|
||||
"An error occurred (AccessDenied) when calling the CreateBucket operation"
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -450,46 +450,3 @@ impl ShutdownSignal {
|
||||
"signal"
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn formats_posix_commands_for_logs() {
|
||||
assert_eq!(format_command(&["pnpm", "build"]), "pnpm build");
|
||||
assert_eq!(
|
||||
format_command(&["", "two words", "a'b"]),
|
||||
"'' 'two words' 'a'\"'\"'b'"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn restart_budget_allows_limited_restarts_within_window() {
|
||||
let mut restarts = VecDeque::new();
|
||||
let base = Instant::now();
|
||||
for offset in 0..RESTART_LIMIT {
|
||||
assert!(!restart_budget_exceeded(
|
||||
&mut restarts,
|
||||
base + Duration::from_secs(offset as u64)
|
||||
));
|
||||
}
|
||||
assert!(restart_budget_exceeded(
|
||||
&mut restarts,
|
||||
base + Duration::from_secs(RESTART_LIMIT as u64)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn restart_budget_resets_after_window_elapses() {
|
||||
let mut restarts = VecDeque::new();
|
||||
let base = Instant::now();
|
||||
for _ in 0..RESTART_LIMIT {
|
||||
assert!(!restart_budget_exceeded(&mut restarts, base));
|
||||
}
|
||||
assert!(!restart_budget_exceeded(
|
||||
&mut restarts,
|
||||
base + RESTART_WINDOW + Duration::from_secs(1)
|
||||
));
|
||||
}
|
||||
}
|
||||
+1
-121
@@ -1,8 +1,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use crate::manifest::{
|
||||
ANY_HOST, DEV_PROXY_GATEWAY_PORTS_ENV, DEV_PROXY_PORT, GATEWAY_PORT, LOCAL_APP_URL,
|
||||
PROXY_ROUTES, ProxyRoute,
|
||||
DEV_PROXY_GATEWAY_PORTS_ENV, GATEWAY_PORT, LOCAL_APP_URL, PROXY_ROUTES, ProxyRoute,
|
||||
};
|
||||
use anyhow::{Context, Result, bail};
|
||||
use axum::{
|
||||
@@ -664,122 +663,3 @@ pub fn rewrite_head(
|
||||
lines.push(String::new());
|
||||
lines.join("\r\n").into_bytes()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn default_bind() -> (&'static str, u16) {
|
||||
(ANY_HOST, DEV_PROXY_PORT)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn routes_and_rewrites_prefixes() {
|
||||
let api = route_for_path("/api/users?x=1");
|
||||
assert_eq!(api.prefix, "/api");
|
||||
assert_eq!(rewrite_path("/api/users?x=1", api), "/users?x=1");
|
||||
let asset = route_for_path("/assets/app.js");
|
||||
assert_eq!(rewrite_path("/assets/app.js", asset), "/assets/app.js");
|
||||
let lazy = route_for_path("/lazy-compilation-using-foo");
|
||||
assert_eq!(lazy.prefix, "/lazy-compilation-using-");
|
||||
let devmail = route_for_path("/devmail/messages");
|
||||
assert_eq!(devmail.prefix, "/devmail");
|
||||
assert_eq!(
|
||||
rewrite_path("/devmail/messages?x=1", devmail),
|
||||
"/devmail/messages?x=1"
|
||||
);
|
||||
let admin = route_for_path("/admin/users");
|
||||
assert_eq!(admin.prefix, "/admin");
|
||||
assert_eq!(rewrite_path("/admin/users", admin), "/users");
|
||||
let absolute_gateway = route_for_path("https://dev.example.test/gateway?v=1&encoding=json");
|
||||
assert_eq!(absolute_gateway.prefix, "/gateway");
|
||||
assert_eq!(
|
||||
rewrite_path(
|
||||
"https://dev.example.test/gateway?v=1&encoding=json",
|
||||
absolute_gateway
|
||||
),
|
||||
"/?v=1&encoding=json"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rewrites_host_connection_and_forwarded_for() {
|
||||
let request = RequestHead {
|
||||
method: "GET".to_owned(),
|
||||
path: "/api/_health".to_owned(),
|
||||
version: "HTTP/1.1".to_owned(),
|
||||
headers: vec![
|
||||
("Host".to_owned(), "localhost:8088".to_owned()),
|
||||
("Connection".to_owned(), "keep-alive".to_owned()),
|
||||
("X-Forwarded-For".to_owned(), "1.1.1.1".to_owned()),
|
||||
],
|
||||
};
|
||||
let head = String::from_utf8(rewrite_head(
|
||||
&request,
|
||||
route_for_path("/api/_health"),
|
||||
Some("api"),
|
||||
Some(8080),
|
||||
Some("2.2.2.2"),
|
||||
))
|
||||
.unwrap();
|
||||
assert!(head.contains("GET /_health HTTP/1.1\r\n"));
|
||||
assert!(head.contains("Host: api:8080\r\n"));
|
||||
assert!(head.contains("Connection: close\r\n"));
|
||||
assert!(head.contains("X-Forwarded-For: 1.1.1.1, 2.2.2.2\r\n"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn redirects_local_html_navigation_to_public_tunnel_url() {
|
||||
let request = RequestHead {
|
||||
method: "GET".to_owned(),
|
||||
path: "/channels/@me?x=1".to_owned(),
|
||||
version: "HTTP/1.1".to_owned(),
|
||||
headers: vec![
|
||||
("Host".to_owned(), "localhost:8088".to_owned()),
|
||||
(
|
||||
"Accept".to_owned(),
|
||||
"text/html,application/xhtml+xml".to_owned(),
|
||||
),
|
||||
],
|
||||
};
|
||||
assert_eq!(
|
||||
redirect_location_for_public_url(&request, "https://dev.example.test"),
|
||||
Some("https://dev.example.test/channels/@me?x=1".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_tunnel_redirect_ignores_assets_and_local_public_url() {
|
||||
let asset = RequestHead {
|
||||
method: "GET".to_owned(),
|
||||
path: "/avatars/4.png".to_owned(),
|
||||
version: "HTTP/1.1".to_owned(),
|
||||
headers: vec![
|
||||
("Host".to_owned(), "localhost:8088".to_owned()),
|
||||
(
|
||||
"Accept".to_owned(),
|
||||
"image/avif,image/webp,image/apng,image/*,*/*;q=0.8".to_owned(),
|
||||
),
|
||||
],
|
||||
};
|
||||
assert_eq!(
|
||||
redirect_location_for_public_url(&asset, "https://dev.example.test"),
|
||||
None
|
||||
);
|
||||
|
||||
let local_public_url = RequestHead {
|
||||
method: "GET".to_owned(),
|
||||
path: "/channels/@me".to_owned(),
|
||||
version: "HTTP/1.1".to_owned(),
|
||||
headers: vec![
|
||||
("Host".to_owned(), "localhost:8088".to_owned()),
|
||||
("Accept".to_owned(), "text/html".to_owned()),
|
||||
],
|
||||
};
|
||||
assert_eq!(
|
||||
redirect_location_for_public_url(&local_public_url, LOCAL_APP_URL),
|
||||
None
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -582,13 +582,6 @@ fn format_pids(pids: &[i32]) -> String {
|
||||
.join(", ")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn cmdline_has_service_binary(args: &[String], binaries: &BTreeSet<String>) -> bool {
|
||||
args.first()
|
||||
.map(|arg| binaries.iter().any(|binary| arg.ends_with(binary)))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn proc_cmdline(pid: i32) -> Vec<String> {
|
||||
fs::read(format!("/proc/{pid}/cmdline"))
|
||||
@@ -599,7 +592,7 @@ fn proc_cmdline(pid: i32) -> Vec<String> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", test))]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn parse_proc_stat_state_and_pgid(stat: &str) -> Option<(char, i32)> {
|
||||
let (_, after_comm) = stat.rsplit_once(')')?;
|
||||
let mut fields = after_comm.split_ascii_whitespace();
|
||||
@@ -619,13 +612,13 @@ fn parse_proc_stat_process(stat: &str) -> Option<(char, i32, i32, u64)> {
|
||||
Some((state, ppid, pgid, parse_proc_stat_starttime(stat)?))
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", test))]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn parse_proc_stat_starttime(stat: &str) -> Option<u64> {
|
||||
let (_, after_comm) = stat.rsplit_once(')')?;
|
||||
after_comm.split_ascii_whitespace().nth(19)?.parse().ok()
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", test))]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn proc_stat_state_is_dead(state: char) -> bool {
|
||||
state == 'Z' || state == 'X' || state == 'x'
|
||||
}
|
||||
@@ -673,173 +666,3 @@ fn signal_process_groups(leaders: &[RustServiceLeader], signal: i32) -> Vec<i32>
|
||||
}
|
||||
failed
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::sync::Mutex;
|
||||
|
||||
static ENV_LOCK: Mutex<()> = Mutex::new(());
|
||||
|
||||
fn with_public_env(
|
||||
overrides: &[(&str, Option<&str>)],
|
||||
assertions: impl FnOnce(Vec<(String, Option<String>)>),
|
||||
) {
|
||||
let _guard = ENV_LOCK.lock().unwrap();
|
||||
let keys = [
|
||||
"FLUXER_MEDIA_PROXY_ENDPOINT",
|
||||
"FLUXER_MEDIA_PROXY_PUBLIC_ENDPOINT",
|
||||
"FLUXER_MEDIA_ENDPOINT",
|
||||
"FLUXER_STATIC_CDN_ENDPOINT",
|
||||
"FLUXER_PUBLIC_URL",
|
||||
];
|
||||
let saved = keys
|
||||
.iter()
|
||||
.map(|key| (*key, env::var(key).ok()))
|
||||
.collect::<Vec<_>>();
|
||||
for key in keys {
|
||||
unsafe {
|
||||
env::remove_var(key);
|
||||
}
|
||||
}
|
||||
for (key, value) in overrides {
|
||||
if let Some(value) = value {
|
||||
unsafe {
|
||||
env::set_var(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let spec = rust_services()
|
||||
.into_iter()
|
||||
.find(|spec| spec.name == "unfurl")
|
||||
.unwrap();
|
||||
let env = service_env(&spec, "router", spec.port_base);
|
||||
|
||||
for (key, value) in saved {
|
||||
match value {
|
||||
Some(value) => unsafe {
|
||||
env::set_var(key, value);
|
||||
},
|
||||
None => unsafe {
|
||||
env::remove_var(key);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
assertions(env);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_unknown_services() {
|
||||
let err = select_services(&["bogus".to_owned()])
|
||||
.unwrap_err()
|
||||
.to_string();
|
||||
assert!(err.contains("Unknown Rust service"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builds_unfurl_env_with_media_endpoints() {
|
||||
with_public_env(&[], |env| {
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(key, value)| key == "FLUXER_MEDIA_PROXY_PUBLIC_ENDPOINT"
|
||||
&& value.as_deref() == Some("http://localhost:8088/media"))
|
||||
);
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(key, value)| key == "FLUXER_STATIC_CDN_ENDPOINT"
|
||||
&& value.as_deref() == Some("http://localhost:8088"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unfurl_env_uses_public_url_overrides() {
|
||||
with_public_env(
|
||||
&[
|
||||
(
|
||||
"FLUXER_MEDIA_PROXY_PUBLIC_ENDPOINT",
|
||||
Some("https://dev.example.com/media"),
|
||||
),
|
||||
(
|
||||
"FLUXER_STATIC_CDN_ENDPOINT",
|
||||
Some("https://dev.example.com"),
|
||||
),
|
||||
],
|
||||
|env| {
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(key, value)| key == "FLUXER_MEDIA_PROXY_PUBLIC_ENDPOINT"
|
||||
&& value.as_deref() == Some("https://dev.example.com/media"))
|
||||
);
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(key, value)| key == "FLUXER_STATIC_CDN_ENDPOINT"
|
||||
&& value.as_deref() == Some("https://dev.example.com"))
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmdline_binary_match_uses_selected_service_binary_suffix() {
|
||||
let binaries = BTreeSet::from(["target/debug/fluxer_messages".to_owned()]);
|
||||
assert!(cmdline_has_service_binary(
|
||||
&["/workspaces/fluxer/target/debug/fluxer_messages".to_owned()],
|
||||
&binaries
|
||||
));
|
||||
assert!(!cmdline_has_service_binary(
|
||||
&["/workspaces/fluxer/target/debug/fluxer_users".to_owned()],
|
||||
&binaries
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proc_stat_parsing_handles_parentheses_and_spaces_in_comm() {
|
||||
assert_eq!(
|
||||
parse_proc_stat_state_and_pgid("99 (spaced comm) T 1 99 99 0 -1"),
|
||||
Some(('T', 99))
|
||||
);
|
||||
assert_eq!(
|
||||
parse_proc_stat_state_and_pgid("99 (weird) comm (name) Z 1 42 42 0 -1"),
|
||||
Some(('Z', 42))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proc_stat_parsing_rejects_malformed_lines() {
|
||||
assert_eq!(parse_proc_stat_state_and_pgid(""), None);
|
||||
assert_eq!(parse_proc_stat_state_and_pgid("1234 (svc)"), None);
|
||||
assert_eq!(parse_proc_stat_state_and_pgid("1234 (svc) S"), None);
|
||||
assert_eq!(parse_proc_stat_state_and_pgid("1234 (svc) S 1"), None);
|
||||
assert_eq!(
|
||||
parse_proc_stat_state_and_pgid("1234 (svc) S 1 not-a-pgid"),
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proc_stat_parsing_extracts_starttime() {
|
||||
let stat = "1234 (svc) S 1 1234 1234 0 -1 4194560 0 0 0 0 5 3 0 0 20 0 30 0 12345678 4096";
|
||||
assert_eq!(parse_proc_stat_starttime(stat), Some(12_345_678));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proc_stat_starttime_parsing_rejects_truncated_lines() {
|
||||
assert_eq!(parse_proc_stat_starttime(""), None);
|
||||
assert_eq!(parse_proc_stat_starttime("1234 (svc)"), None);
|
||||
assert_eq!(
|
||||
parse_proc_stat_starttime("1234 (svc) S 1 1234 1234 0 -1 4194560 0"),
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zombie_and_reaped_states_count_as_dead() {
|
||||
assert!(proc_stat_state_is_dead('Z'));
|
||||
assert!(proc_stat_state_is_dead('X'));
|
||||
assert!(proc_stat_state_is_dead('x'));
|
||||
assert!(!proc_stat_state_is_dead('S'));
|
||||
}
|
||||
}
|
||||
@@ -118,21 +118,3 @@ pub fn run_knip() -> Result<i32> {
|
||||
task_run(&["pnpm", "exec", "knip"])?;
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn default_nats_url_switches_inside_container() {
|
||||
let expected_host = if Path::new("/.dockerenv").exists() {
|
||||
"nats"
|
||||
} else {
|
||||
"127.0.0.1"
|
||||
};
|
||||
assert_eq!(
|
||||
default_test_nats_url(),
|
||||
format!("nats://{expected_host}:4222")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -371,43 +371,3 @@ fn set_private_file_mode(path: &Path) -> Result<()> {
|
||||
fn set_private_file_mode(_path: &Path) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn derives_https_public_url_env() {
|
||||
let env = public_url_env("https://dev.example.test").unwrap();
|
||||
assert!(env.iter().any(|(key, value)| {
|
||||
key == "FLUXER_GATEWAY_ENDPOINT" && value == "wss://dev.example.test/gateway"
|
||||
}));
|
||||
assert!(env.iter().any(|(key, value)| {
|
||||
key == "FLUXER_LIVEKIT_URL" && value == "wss://dev.example.test/livekit"
|
||||
}));
|
||||
assert!(env.iter().any(|(key, value)| {
|
||||
key == "FLUXER_MEDIA_PROXY_UPLOAD_RELAY_ENDPOINT"
|
||||
&& value == "https://dev.example.test/media"
|
||||
}));
|
||||
assert!(env.iter().any(|(key, value)| {
|
||||
key == "FLUXER_S3_PUBLIC_ENDPOINT" && value == "https://dev.example.test"
|
||||
}));
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(key, value)| { key == "FLUXER_PUBLIC_PORT" && value == "443" })
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_public_url_with_path() {
|
||||
assert!(parse_public_url("https://example.com/app").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolves_public_url_arg_normalized() {
|
||||
assert_eq!(
|
||||
resolve_cloudflare_public_url(Some("https://example.com/")).unwrap(),
|
||||
"https://example.com"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user