microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
iadavis/pipeline-issue-debugging

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

source/compiler/qsc/src/interpret/debugger_tests.rs

242lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::interpret::Debugger;
5use crate::line_column::Encoding;
6use qsc_data_structures::language_features::LanguageFeatures;
7use qsc_eval::{StepAction, StepResult, output::CursorReceiver};
8use qsc_fir::fir::StmtId;
9use std::io::Cursor;
10
11fn get_breakpoint_ids(debugger: &Debugger, path: &str) -> Vec<StmtId> {
12 let mut bps = debugger.get_breakpoints(path);
13 bps.sort_by_key(|f| f.id);
14 bps.iter().map(|f| f.id.into()).collect::<Vec<_>>()
15}
16
17fn expect_return(mut debugger: Debugger, expected: &str) {
18 let r = step_next(&mut debugger, &[]);
19 match r.0 {
20 Ok(StepResult::Return(value)) => assert_eq!(value.to_string(), expected),
21 Ok(v) => panic!("Expected Return, got {v:?}"),
22 Err(e) => panic!("Expected Return, got {e:?}"),
23 }
24}
25
26fn expect_bp(debugger: &mut Debugger, ids: &[StmtId], expected_id: StmtId) {
27 let r = step_next(debugger, ids);
28 match r.0 {
29 Ok(StepResult::BreakpointHit(actual_id)) => assert!(actual_id == expected_id),
30 Ok(v) => panic!("Expected BP, got {v:?}"),
31 Err(e) => panic!("Expected BP, got {e:?}"),
32 }
33}
34
35fn step_in(
36 debugger: &mut Debugger,
37 breakpoints: &[StmtId],
38) -> (Result<StepResult, Vec<crate::interpret::Error>>, String) {
39 step(debugger, breakpoints, qsc_eval::StepAction::In)
40}
41
42fn step_next(
43 debugger: &mut Debugger,
44 breakpoints: &[StmtId],
45) -> (Result<StepResult, Vec<crate::interpret::Error>>, String) {
46 step(debugger, breakpoints, qsc_eval::StepAction::Next)
47}
48
49fn step_out(
50 debugger: &mut Debugger,
51 breakpoints: &[StmtId],
52) -> (Result<StepResult, Vec<crate::interpret::Error>>, String) {
53 step(debugger, breakpoints, qsc_eval::StepAction::Out)
54}
55
56fn step(
57 debugger: &mut Debugger,
58 breakpoints: &[StmtId],
59 step: StepAction,
60) -> (Result<StepResult, Vec<crate::interpret::Error>>, String) {
61 let mut cursor = Cursor::new(Vec::<u8>::new());
62 let mut receiver = CursorReceiver::new(&mut cursor);
63 (
64 debugger.eval_step(&mut receiver, breakpoints, step),
65 receiver.dump(),
66 )
67}
68
69fn expect_next(debugger: &mut Debugger) {
70 let result = step_next(debugger, &[]);
71 match result.0 {
72 Ok(StepResult::Next) => (),
73 Ok(v) => panic!("Expected Next, got {v:?}"),
74 Err(e) => panic!("Expected Next, got {e:?}"),
75 }
76}
77
78fn expect_in(debugger: &mut Debugger) {
79 let result = step_in(debugger, &[]);
80 match result.0 {
81 Ok(StepResult::StepIn) => (),
82 Ok(v) => panic!("Expected StepIn, got {v:?}"),
83 Err(e) => panic!("Expected StepIn, got {e:?}"),
84 }
85}
86
87fn expect_out(debugger: &mut Debugger) {
88 let result = step_out(debugger, &[]);
89 match result.0 {
90 Ok(StepResult::StepOut) => (),
91 Ok(v) => panic!("Expected StepOut, got {v:?}"),
92 Err(e) => panic!("Expected StepOut, got {e:?}"),
93 }
94}
95
96#[cfg(test)]
97mod given_debugger {
98 use super::*;
99
100 static STEPPING_SOURCE: &str = r#"
101 namespace Test {
102 @EntryPoint()
103 operation A() : Int {
104 let d = B();
105 let e = d / 1;
106 e
107 }
108 operation B() : Int {
109 let g = 10;
110 let h = 20;
111 let l = C(g, h);
112 42
113 }
114 operation C(m: Int, n: Int) : Int {
115 let o = 42 - (m + n);
116 let p = (m + n) + o;
117 p
118 }
119 }"#;
120 #[cfg(test)]
121 mod step {
122 use qsc_data_structures::{source::SourceMap, target::TargetCapabilityFlags};
123
124 use super::*;
125
126 #[test]
127 fn in_one_level_operation_works() -> Result<(), Vec<crate::interpret::Error>> {
128 use qsc_data_structures::language_features::LanguageFeatures;
129 let sources = SourceMap::new([("test".into(), STEPPING_SOURCE.into())], None);
130 let (std_id, store) =
131 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
132 let mut debugger = Debugger::new(
133 sources,
134 TargetCapabilityFlags::all(),
135 Encoding::Utf8,
136 LanguageFeatures::default(),
137 store,
138 &[(std_id, None)],
139 )?;
140 let ids = get_breakpoint_ids(&debugger, "test");
141 let expected_id = ids[0];
142 expect_bp(&mut debugger, &ids, expected_id);
143 expect_in(&mut debugger);
144 expect_next(&mut debugger);
145 expect_next(&mut debugger);
146 expect_next(&mut debugger);
147 expect_next(&mut debugger);
148 expect_next(&mut debugger);
149 expect_next(&mut debugger);
150 expect_next(&mut debugger);
151 let expected = "42";
152 expect_return(debugger, expected);
153 Ok(())
154 }
155
156 #[test]
157 fn next_crosses_operation_works() -> Result<(), Vec<crate::interpret::Error>> {
158 let sources = SourceMap::new([("test".into(), STEPPING_SOURCE.into())], None);
159 let (std_id, store) =
160 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
161 let mut debugger = Debugger::new(
162 sources,
163 TargetCapabilityFlags::all(),
164 Encoding::Utf8,
165 LanguageFeatures::default(),
166 store,
167 &[(std_id, None)],
168 )?;
169 let ids = get_breakpoint_ids(&debugger, "test");
170 let expected_id = ids[0];
171 expect_bp(&mut debugger, &ids, expected_id);
172 expect_next(&mut debugger);
173 expect_next(&mut debugger);
174 expect_next(&mut debugger);
175 let expected = "42";
176 expect_return(debugger, expected);
177 Ok(())
178 }
179
180 #[test]
181 fn in_multiple_operations_works() -> Result<(), Vec<crate::interpret::Error>> {
182 let sources = SourceMap::new([("test".into(), STEPPING_SOURCE.into())], None);
183 let (std_id, store) =
184 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
185 let mut debugger = Debugger::new(
186 sources,
187 TargetCapabilityFlags::all(),
188 Encoding::Utf8,
189 LanguageFeatures::default(),
190 store,
191 &[(std_id, None)],
192 )?;
193 let ids = get_breakpoint_ids(&debugger, "test");
194 let expected_id = ids[0];
195 expect_bp(&mut debugger, &ids, expected_id);
196 expect_in(&mut debugger);
197 expect_next(&mut debugger);
198 expect_next(&mut debugger);
199 expect_in(&mut debugger);
200 expect_next(&mut debugger);
201 expect_next(&mut debugger);
202 expect_next(&mut debugger);
203 expect_next(&mut debugger);
204 expect_next(&mut debugger);
205 expect_next(&mut debugger);
206 expect_next(&mut debugger);
207 expect_next(&mut debugger);
208 let expected = "42";
209 expect_return(debugger, expected);
210 Ok(())
211 }
212
213 #[test]
214 fn out_multiple_operations_works() -> Result<(), Vec<crate::interpret::Error>> {
215 let sources = SourceMap::new([("test".into(), STEPPING_SOURCE.into())], None);
216 let (std_id, store) =
217 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
218 let mut debugger = Debugger::new(
219 sources,
220 TargetCapabilityFlags::all(),
221 Encoding::Utf8,
222 LanguageFeatures::default(),
223 store,
224 &[(std_id, None)],
225 )?;
226 let ids = get_breakpoint_ids(&debugger, "test");
227 let expected_id = ids[0];
228 expect_bp(&mut debugger, &ids, expected_id);
229 expect_in(&mut debugger);
230 expect_next(&mut debugger);
231 expect_next(&mut debugger);
232 expect_in(&mut debugger);
233 expect_out(&mut debugger);
234 expect_out(&mut debugger);
235 expect_next(&mut debugger);
236 expect_next(&mut debugger);
237 let expected = "42";
238 expect_return(debugger, expected);
239 Ok(())
240 }
241 }
242}
243