forked from microsoft/Quantum
-
Notifications
You must be signed in to change notification settings - Fork 0
/
QuantumSimulatorTestTargets.cs
84 lines (73 loc) · 3.97 KB
/
QuantumSimulatorTestTargets.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.Quantum.Simulation.Simulators;
using Microsoft.Quantum.Simulation.XUnit;
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
///////////////////////////////////////////////////////////////////////////////////////////////////
// This file makes sure that all Q# operations ending with Test
// in Microsoft.Quantum.Samples.UnitTesting namespace are
// executed as Tests on QuantumSimulator.
///////////////////////////////////////////////////////////////////////////////////////////////////
namespace Microsoft.Quantum.Samples.UnitTesting
{
public class SimulatorTestTargets
{
/// <summary>
/// Interface provided by Xunit framework for logging during test execution.
/// When the test is selected in Visual Studio Test Explore window
/// there is an Output text link available for each test.
/// </summary>
private readonly Xunit.Abstractions.ITestOutputHelper output;
public SimulatorTestTargets(Xunit.Abstractions.ITestOutputHelper output)
{
this.output = output;
}
/// <summary>All Q# procedures ending with Test in the same namespace as this class are
/// discovered and passed to this function as an argument.
/// </summary>
[OperationDriver]
public void QuantumSimulatorTarget(TestOperation operationDescription)
{
try
{
// Generate seed based on name of testclass, so testruns are more deterministic
// but we don't always use the same seed throughout the solution.
byte[] bytes = Encoding.Unicode.GetBytes(operationDescription.fullClassName);
byte[] hash = hashMethod.ComputeHash(bytes);
uint seed = BitConverter.ToUInt32(hash, 0);
using var sim = new QuantumSimulator(randomNumberGeneratorSeed:seed);
// Frequently tests include measurement and randomness.
// To reproduce the failed test it is useful to record seed that has been used
// for the random number generator inside the simulator.
output.WriteLine($"The seed used for this test is {sim.Seed}");
Debug.WriteLine($"The seed used for this test is {sim.Seed}");
// This ensures that when the test is run in Debug mode, all message logged in
// Q# by calling Microsoft.Quantum.Primitives.Message show-up
// in Debug output.
// Note that since this method only exists when DEBUG is
// enabled, we need to guard with an #if block wrap the call
// in an explicit lambda function.
#if DEBUG
sim.OnLog += msg => Debug.WriteLine(msg);
#endif
// this ensures that all message logged in Q# by calling
// Microsoft.Quantum.Primitives.Message show-up
// in test output
sim.OnLog += output.WriteLine;
// Executes operation described by operationDescription on a QuantumSimulator
operationDescription.TestOperationRunner(sim);
}
catch (System.BadImageFormatException e)
{
throw new System.BadImageFormatException($"Could not load Quantum Simulator. If you are running tests using Visual Studio 2017, " +
$"this problem can be fixed by using menu Test > Test Settings > Default Processor Architecture " +
$"and switching to X64 instead of X86. Alternatively, press Ctrl+Q and type `Default Processor Architecture`. If you are running from command line using " +
$"vstest.console.exe use command line option /Platform:x64.", e);
}
}
private static readonly SHA256Managed hashMethod = new SHA256Managed();
}
}