microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.19.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

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

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