microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.1.3

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc/src/interpret/debugger_tests.rs

207lines · modecode

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