feat: complete Steam execution

This commit is contained in:
2026-07-20 15:51:11 -04:00
parent bc0090c63d
commit 7d1077c0cb
13 changed files with 438 additions and 83 deletions
+59 -1
View File
@@ -1,6 +1,7 @@
//! Isolated CLI contract tests for Phase 1 machine output.
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
use std::process::Command;
@@ -28,11 +29,23 @@ impl TestDirectory {
}
fn run(&self, arguments: &[&str]) -> std::process::Output {
self.run_with_path(
arguments,
&format!(
"{}:{}",
self.0.join("bin").display(),
std::env::var("PATH").unwrap_or_default()
),
)
}
fn run_with_path(&self, arguments: &[&str], path: &str) -> std::process::Output {
Command::new(env!("CARGO_BIN_EXE_kiln"))
.args(arguments)
.env("XDG_CONFIG_HOME", self.0.join("config"))
.env("XDG_STATE_HOME", self.0.join("state"))
.env("HOME", self.0.join("home"))
.env("PATH", path)
.output()
.expect("kiln runs")
}
@@ -66,6 +79,11 @@ impl TestDirectory {
),
)
.unwrap();
let bin = self.0.join("bin");
fs::create_dir_all(&bin).unwrap();
let steam = bin.join("steam");
fs::write(&steam, "#!/bin/sh\nprintf 'steam %s\\n' \"$*\"\n").unwrap();
fs::set_permissions(steam, fs::Permissions::from_mode(0o755)).unwrap();
fs::write(
steamapps.join(format!("appmanifest_{app_id}.acf")),
format!(
@@ -230,7 +248,7 @@ fn invalid_configuration_and_failed_launch_are_structured() {
}
#[test]
fn steam_provider_cli_discovers_searches_and_resolves_without_launching() {
fn steam_provider_cli_discovers_plans_and_submits_without_a_shell() {
let directory = TestDirectory::new();
directory.add_steam_game("620", "Portal 2");
@@ -240,6 +258,12 @@ fn steam_provider_cli_discovers_searches_and_resolves_without_launching() {
assert_eq!(records[0]["id"], "steam:620");
assert_eq!(records[0]["runtime"], "steam-managed");
assert_eq!(records[0]["client_required"], true);
assert!(
records[0]["capabilities"]
.as_array()
.unwrap()
.contains(&Value::String("launch".into()))
);
let search = directory.run(&["search", "portal", "--provider", "steam", "--json"]);
assert!(search.status.success());
@@ -260,4 +284,38 @@ fn steam_provider_cli_discovers_searches_and_resolves_without_launching() {
let result: Value = serde_json::from_slice(&scan.stdout).unwrap();
assert_eq!(result["provider"], "steam");
assert_eq!(result["discovered"], 1);
let dry_run = directory.run(&[
"launch",
"Portal 2",
"--provider",
"steam",
"--dry-run",
"--json",
]);
assert!(dry_run.status.success());
let plan: Value = serde_json::from_slice(&dry_run.stdout).unwrap();
assert_eq!(plan["runtime"], "steam-managed");
assert_eq!(plan["lifecycle_confidence"], "unknown");
assert_eq!(plan["command"]["arguments"][2], "620");
let launch = directory.run(&["launch", "steam:620", "--json"]);
assert!(launch.status.success());
let outcome: Value = serde_json::from_slice(&launch.stdout).unwrap();
assert_eq!(outcome["status"], "submitted");
assert!(outcome["process_id"].as_u64().unwrap() > 0);
assert!(
fs::read_to_string(directory.0.join("state/kiln/logs/steam.log"))
.unwrap()
.contains("submitted")
);
fs::remove_file(directory.0.join("bin/steam")).unwrap();
let failed = directory.run_with_path(
&["launch", "steam:620", "--json"],
directory.0.join("bin").to_str().unwrap(),
);
assert_eq!(failed.status.code(), Some(2));
let error: Value = serde_json::from_slice(&failed.stderr).unwrap();
assert_eq!(error["code"], "launch-failed");
}