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/debug/tests.rs

176lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use expect_test::expect;
5use indoc::indoc;
6use miette::Result;
7use qsc_data_structures::{
8 language_features::LanguageFeatures, source::SourceMap, target::TargetCapabilityFlags,
9};
10use qsc_eval::{output::CursorReceiver, val::Value};
11use qsc_passes::PackageType;
12use std::io::Cursor;
13
14use crate::interpret::{Error, InterpretResult, Interpreter};
15
16fn line(interpreter: &mut Interpreter, line: impl AsRef<str>) -> (InterpretResult, String) {
17 let mut cursor = Cursor::new(Vec::<u8>::new());
18 let mut receiver = CursorReceiver::new(&mut cursor);
19 (
20 interpreter.eval_fragments(&mut receiver, line.as_ref()),
21 receiver.dump(),
22 )
23}
24
25fn eval(interpreter: &mut Interpreter) -> (Result<Value, Vec<Error>>, String) {
26 let mut cursor = Cursor::new(Vec::<u8>::new());
27 let mut receiver = CursorReceiver::new(&mut cursor);
28 (interpreter.eval_entry(&mut receiver), receiver.dump())
29}
30
31#[test]
32fn stack_traces_can_cross_eval_session_and_file_boundaries() {
33 let source1 = indoc! { r#"
34 namespace Test {
35 operation B(input : Int) : Unit is Adj {
36 body ... {
37 C(input)
38 }
39 adjoint invert;
40 }
41
42 operation C(input : Int) : Unit is Adj {
43 body ... {
44 1 / input;
45 }
46 adjoint self;
47 }
48 }
49 "#};
50 let source2 = indoc! { r#"
51 namespace Test2 {
52 open Test;
53 operation A(input : Int) : Unit is Adj {
54 body ... {
55 B(input)
56 }
57 adjoint invert;
58 }
59 }
60 "#};
61
62 let source_map = SourceMap::new(
63 [
64 ("1.qs".into(), source1.into()),
65 ("2.qs".into(), source2.into()),
66 ],
67 None,
68 );
69
70 let (std_id, store) = crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
71 let mut interpreter = Interpreter::new(
72 source_map,
73 PackageType::Lib,
74 TargetCapabilityFlags::all(),
75 LanguageFeatures::default(),
76 store,
77 &[(std_id, None)],
78 )
79 .expect("Failed to compile base environment.");
80
81 let (result, _) = line(
82 &mut interpreter,
83 "operation Z(input : Int) : Unit { Adjoint Test2.A(input); }",
84 );
85 result.expect("code should compile");
86
87 let (result, _output) = line(&mut interpreter, "Z(0)");
88
89 match result {
90 Ok(_) => panic!("Expected error"),
91 Err(e) => {
92 let stack_trace = e[0]
93 .stack_trace()
94 .expect("code should have a valid stack trace");
95 expect![[r#"
96 Error: division by zero
97 Call stack:
98 at Adjoint Test.C in 1.qs:11:13
99 at Adjoint Test.B in 1.qs:4:13
100 at Adjoint Test2.A in 2.qs:5:13
101 at Z in line_0:1:35
102 "#]]
103 .assert_eq(stack_trace);
104 }
105 }
106}
107
108#[test]
109fn stack_traces_can_cross_file_and_entry_boundaries() {
110 let source1 = indoc! { r#"
111 namespace Test {
112 operation B(input : Int) : Unit is Adj {
113 body ... {
114 C(input)
115 }
116 adjoint invert;
117 }
118
119 operation C(input : Int) : Unit is Adj {
120 body ... {
121 1 / input;
122 }
123 adjoint self;
124 }
125 }
126 "#};
127 let source2 = indoc! { r#"
128 namespace Test2 {
129 open Test;
130 operation A(input : Int) : Unit is Adj {
131 body ... {
132 B(input)
133 }
134 adjoint invert;
135 }
136 }
137 "#};
138
139 let source_map = SourceMap::new(
140 [
141 ("1.qs".into(), source1.into()),
142 ("2.qs".into(), source2.into()),
143 ],
144 Some("Adjoint Test2.A(0)".into()),
145 );
146
147 let (std_id, store) = crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
148 let mut interpreter = Interpreter::new(
149 source_map,
150 PackageType::Exe,
151 TargetCapabilityFlags::all(),
152 LanguageFeatures::default(),
153 store,
154 &[(std_id, None)],
155 )
156 .expect("Failed to compile base environment.");
157
158 let (result, _) = eval(&mut interpreter);
159
160 match result {
161 Ok(_) => panic!("Expected error"),
162 Err(e) => {
163 let stack_trace = e[0]
164 .stack_trace()
165 .expect("code should have a valid stack trace");
166 expect![[r#"
167 Error: division by zero
168 Call stack:
169 at Adjoint Test.C in 1.qs:11:13
170 at Adjoint Test.B in 1.qs:4:13
171 at Adjoint Test2.A in 2.qs:5:13
172 "#]]
173 .assert_eq(stack_trace);
174 }
175 }
176}
177