flowey_lib_hvlite/
run_test_igvm_agent_rpc_server.rs1use crate::build_test_igvm_agent_rpc_server::TestIgvmAgentRpcServerOutput;
19use flowey::node::prelude::*;
20use std::collections::BTreeMap;
21
22flowey_request! {
23 pub struct Request {
24 pub test_igvm_agent_rpc_server: ReadVar<TestIgvmAgentRpcServerOutput>,
26 pub env: ReadVar<BTreeMap<String, String>>,
28 pub done: WriteVar<SideEffect>,
30 pub previous_done: Option<ReadVar<SideEffect>>,
32 }
33}
34
35new_simple_flow_node!(struct Node);
36
37impl SimpleFlowNode for Node {
38 type Request = Request;
39
40 fn imports(_ctx: &mut ImportCtx<'_>) {}
41
42 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
43 let Request {
44 test_igvm_agent_rpc_server,
45 env,
46 done,
47 previous_done,
48 } = request;
49
50 if !matches!(ctx.platform(), FlowPlatform::Windows) {
53 anyhow::bail!(
54 "run_test_igvm_agent_rpc_server only supports Windows. \
55 Callers should check the platform before requesting this node."
56 );
57 }
58
59 ctx.emit_rust_step("starting test_igvm_agent_rpc_server", |ctx| {
60 let test_igvm_agent_rpc_server = test_igvm_agent_rpc_server.claim(ctx);
61 let env = env.claim(ctx);
62 done.claim(ctx);
63 previous_done.claim(ctx);
64 move |rt| start_rpc_server(rt, test_igvm_agent_rpc_server, env)
65 });
66
67 Ok(())
68 }
69}
70
71#[cfg(windows)]
72fn start_rpc_server(
73 rt: &mut RustRuntimeServices<'_>,
74 test_igvm_agent_rpc_server: ReadVar<TestIgvmAgentRpcServerOutput, VarClaimed>,
75 env: ReadVar<BTreeMap<String, String>, VarClaimed>,
76) -> anyhow::Result<()> {
77 use std::os::windows::process::CommandExt;
78 use std::path::Path;
79
80 let env = rt.read(env);
81
82 let test_output_path = env
83 .get("TEST_OUTPUT_PATH")
84 .context("TEST_OUTPUT_PATH not set")?;
85
86 let TestIgvmAgentRpcServerOutput { exe, .. } = rt.read(test_igvm_agent_rpc_server);
87
88 let log_file_path = Path::new(test_output_path).join("test_igvm_agent_rpc_server.log");
90 let log_file = std::fs::File::create(&log_file_path)?;
91 let log_file_stderr = log_file.try_clone()?;
92
93 log::info!(
94 "starting test_igvm_agent_rpc_server from {}, logs at: {}",
95 exe.display(),
96 log_file_path.display()
97 );
98
99 const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
102
103 let mut child = std::process::Command::new(&exe)
104 .stdin(std::process::Stdio::null())
105 .stdout(log_file)
106 .stderr(log_file_stderr)
107 .creation_flags(CREATE_NEW_PROCESS_GROUP)
108 .spawn()
109 .with_context(|| {
110 format!(
111 "failed to spawn test_igvm_agent_rpc_server: {}",
112 exe.display()
113 )
114 })?;
115
116 std::thread::sleep(std::time::Duration::from_millis(500));
118
119 match child.try_wait()? {
121 Some(status) => {
122 anyhow::bail!(
123 "test_igvm_agent_rpc_server exited unexpectedly with status: {:?}. \
124 Check logs at: {}",
125 status.code(),
126 log_file_path.display()
127 );
128 }
129 None => {
130 log::info!(
131 "test_igvm_agent_rpc_server started successfully (pid: {})",
132 child.id()
133 );
134 }
135 }
136
137 drop(child);
141
142 Ok(())
143}
144
145#[cfg(not(windows))]
146fn start_rpc_server(
147 _rt: &mut RustRuntimeServices<'_>,
148 _test_igvm_agent_rpc_server: ReadVar<TestIgvmAgentRpcServerOutput, VarClaimed>,
149 _env: ReadVar<BTreeMap<String, String>, VarClaimed>,
150) -> anyhow::Result<()> {
151 anyhow::bail!("run_test_igvm_agent_rpc_server is only supported on Windows")
154}