debugger/testing/config.rs
1//! Test scenario configuration types
2//!
3//! Defines the data structures for deserializing YAML test scenarios.
4
5use serde::Deserialize;
6use std::path::PathBuf;
7
8/// A complete test scenario loaded from a YAML file
9#[derive(Deserialize, Debug)]
10pub struct TestScenario {
11 /// Name of the test scenario
12 pub name: String,
13 /// Optional description of what the test verifies
14 pub description: Option<String>,
15 /// Optional setup steps to run before the test (e.g., compilation)
16 pub setup: Option<Vec<SetupStep>>,
17 /// Configuration for the debug target
18 pub target: TargetConfig,
19 /// The sequence of test steps to execute
20 pub steps: Vec<TestStep>,
21}
22
23/// A setup step that runs before the test
24#[derive(Deserialize, Debug)]
25pub struct SetupStep {
26 /// Shell command to execute
27 pub shell: String,
28}
29
30/// Configuration for the debug target
31#[derive(Deserialize, Debug)]
32pub struct TargetConfig {
33 /// Path to the program to debug
34 pub program: PathBuf,
35 /// Arguments to pass to the program
36 pub args: Option<Vec<String>>,
37 /// Debug mode: "launch" (default) or "attach"
38 #[serde(default = "default_mode")]
39 pub mode: String,
40 /// PID to attach to (for attach mode)
41 pub pid: Option<u32>,
42 /// Path to file containing PID (for attach mode with setup-generated PIDs)
43 pub pid_file: Option<PathBuf>,
44 /// Debug adapter to use (e.g., "lldb-dap", "codelldb", "debugpy")
45 pub adapter: Option<String>,
46 /// Whether to stop at the program entry point
47 #[serde(default)]
48 pub stop_on_entry: bool,
49}
50
51fn default_mode() -> String {
52 "launch".to_string()
53}
54
55/// A single test step in the execution flow
56#[derive(Deserialize, Debug)]
57#[serde(tag = "action", rename_all = "snake_case")]
58pub enum TestStep {
59 /// Execute a debugger command
60 Command {
61 /// The command to execute (e.g., "break add main", "continue")
62 command: String,
63 /// Optional expectations for the command result
64 expect: Option<CommandExpectation>,
65 },
66 /// Wait for a stop event (breakpoint, step completion, etc.)
67 Await {
68 /// Timeout in seconds (default: 30)
69 timeout: Option<u64>,
70 /// Expected stop event properties
71 expect: Option<StopExpectation>,
72 },
73 /// Inspect local variables and make assertions
74 InspectLocals {
75 /// Variable assertions to check
76 asserts: Vec<VariableAssertion>,
77 },
78 /// Inspect the call stack
79 InspectStack {
80 /// Frame assertions to check
81 asserts: Vec<FrameAssertion>,
82 },
83 /// Check program output
84 CheckOutput {
85 /// Expected substring in output
86 contains: Option<String>,
87 /// Expected exact output
88 equals: Option<String>,
89 },
90 /// Evaluate an expression
91 Evaluate {
92 /// Expression to evaluate
93 expression: String,
94 /// Expected result
95 expect: Option<EvaluateExpectation>,
96 },
97}
98
99/// Expectations for a command result
100#[derive(Deserialize, Debug)]
101pub struct CommandExpectation {
102 /// Whether the command should succeed
103 pub success: Option<bool>,
104 /// Substring that should be in the output
105 pub output_contains: Option<String>,
106}
107
108/// Expectations for a stop event
109#[derive(Deserialize, Debug)]
110pub struct StopExpectation {
111 /// Expected stop reason (e.g., "breakpoint", "step", "exited")
112 pub reason: Option<String>,
113 /// Expected source file name (partial match)
114 pub file: Option<String>,
115 /// Expected line number
116 pub line: Option<u32>,
117 /// Expected exit code (for "exited" reason)
118 pub exit_code: Option<i64>,
119 /// Expected thread ID
120 pub thread_id: Option<i64>,
121}
122
123/// Assertion for a variable
124#[derive(Deserialize, Debug)]
125pub struct VariableAssertion {
126 /// Variable name to check
127 pub name: String,
128 /// Expected value (exact match)
129 pub value: Option<String>,
130 /// Expected value substring (partial match)
131 pub value_contains: Option<String>,
132 /// Expected type name
133 #[serde(rename = "type")]
134 pub type_name: Option<String>,
135}
136
137/// Assertion for a stack frame
138#[derive(Deserialize, Debug)]
139pub struct FrameAssertion {
140 /// Frame index (0 = current/innermost)
141 pub index: usize,
142 /// Expected function name
143 pub function: Option<String>,
144 /// Expected source file (partial match)
145 pub file: Option<String>,
146 /// Expected line number
147 pub line: Option<u32>,
148}
149
150/// Expectations for an evaluate result
151#[derive(Deserialize, Debug)]
152pub struct EvaluateExpectation {
153 /// Whether the evaluation should succeed (default: true)
154 /// Set to false to test error scenarios (undefined variables, syntax errors)
155 pub success: Option<bool>,
156 /// Expected result value
157 pub result: Option<String>,
158 /// Expected result substring
159 pub result_contains: Option<String>,
160 /// Expected type name
161 #[serde(rename = "type")]
162 pub type_name: Option<String>,
163}