OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #region | |
6 | |
7 using Google.NaClVsx.DebugSupport; | |
8 using Microsoft.VisualStudio; | |
9 using Microsoft.VisualStudio.Debugger.Interop; | |
10 using Microsoft.VisualStudio.TestTools.UnitTesting; | |
11 using NaClVsx.DebugHelpers; | |
12 | |
13 #endregion | |
14 | |
15 namespace NaClVsx.Package_UnitTestProject { | |
16 ///<summary> | |
17 /// This is a test class for ThreadTest and is intended | |
18 /// to contain all ThreadTest Unit Tests | |
19 ///</summary> | |
20 [TestClass] | |
21 public class ThreadTest { | |
22 ///<summary> | |
23 /// Gets or sets the test context which provides | |
24 /// information about and functionality for the current test run. | |
25 ///</summary> | |
26 public TestContext TestContext { get; set; } | |
27 | |
28 /// <summary> | |
29 /// A test for EnumFrameInfo. This test is bulky because it's the only | |
30 /// test in this class at the moment. A lot of the code here can be | |
31 /// reused and should be factored when more tests are added. | |
32 /// </summary> | |
33 [TestMethod] | |
34 public void EnumFrameInfoTest() { | |
35 // In order for this test to mean anything we need a real symbol | |
36 // provider. | |
37 var symbolProvider = NaClPackageTestUtils.LoadLoopNexe(); | |
38 Assert.IsNotNull( | |
39 symbolProvider, | |
40 "NaClSymbolProviderTest could not initialize."); | |
41 var debuggerMock = new NaClDebuggerMock(); | |
42 var symbolProviderPrivates = new PrivateObject(symbolProvider); | |
43 symbolProviderPrivates.SetField("dbg_", debuggerMock); | |
44 debuggerMock.Symbols = symbolProvider; | |
45 // We can also use a real NaClDebugProcess which can be equipped with | |
46 // some mocks. | |
47 IDebugPort2 debugPort2 = new DebugPort2Mock(); | |
48 var process = new NaClDebugProcess( | |
49 debugPort2, "connectionString", 123, "imagePath"); | |
50 var program = new ProgramNode(process); | |
51 var programPrivates = new PrivateObject(program); | |
52 programPrivates.SetField("dbg_", debuggerMock); | |
53 | |
54 var name = "loop"; | |
55 uint tid = 1; | |
56 var target = new Thread(program, name, tid); | |
57 var dwFieldSpec = new enum_FRAMEINFO_FLAGS(); | |
58 uint nRadix = 0; | |
59 IEnumDebugFrameInfo2 ppDebugFrames; | |
60 // Now it's time to prime the mocks. | |
61 var loopCCPath = NaClPackageTestUtils.GetLoopCCPath(); | |
62 var mockRegisters = new RegsX86_64(); | |
63 | |
64 // We need the following addresses to create a simulated callstack. | |
65 var printLineAddress = NaClPackageTestUtils.GetAddressForPosition( | |
66 loopCCPath, NaClPackageTestUtils.kPrintLineRow, symbolProvider); | |
67 var printLoopAddress = NaClPackageTestUtils.GetAddressForPosition( | |
68 loopCCPath, | |
69 NaClPackageTestUtils.kPrintLineCallSiteRow, | |
70 symbolProvider); | |
71 var fooAddress = NaClPackageTestUtils.GetAddressForPosition( | |
72 loopCCPath, | |
73 NaClPackageTestUtils.kPrintLoopCallSiteRow, | |
74 symbolProvider); | |
75 var mainAddress = NaClPackageTestUtils.GetAddressForPosition( | |
76 loopCCPath, NaClPackageTestUtils.kFooCallSiteRow, symbolProvider); | |
77 // A million is a nice round number which makes it easy to calculate the | |
78 // expected register values. We can use it for the register values we | |
79 // mock. | |
80 var dummyValidAddress = 1000000 + symbolProvider.BaseAddress; | |
81 | |
82 mockRegisters.Rip = printLineAddress; | |
83 mockRegisters.Rbp = dummyValidAddress; | |
84 // As the stack is being analyzed, the debugger will traverse up the | |
85 // call chain. The mock will thus return code locations from the inside | |
86 // out to simulate this procedure. | |
87 // Note that the symbolprovider has been loaded with real call frame | |
88 // information, and that the non-dummy addresses have been parsed out of | |
89 // the loop nexe as well. | |
90 debuggerMock.RecordCall("GetRegisters", (uint) 1, mockRegisters); | |
91 debuggerMock.RecordCall("GetU64", (ulong) 1000008, printLoopAddress); | |
92 debuggerMock.RecordCall("GetU64", (ulong) 1000000, dummyValidAddress); | |
93 debuggerMock.RecordCall("GetU64", (ulong) 1000008, fooAddress); | |
94 debuggerMock.RecordCall("GetU64", (ulong) 1000000, dummyValidAddress); | |
95 debuggerMock.RecordCall("GetU64", (ulong) 1000008, mainAddress); | |
96 debuggerMock.RecordCall("GetU64", (ulong) 1000000, dummyValidAddress); | |
97 // Having the same mainAddress returned twice simulates the infinite loop | |
98 // that was fixed in RefreshFrameInfo() | |
99 // http://code.google.com/p/nativeclient/issues/detail?id=2012 | |
100 debuggerMock.RecordCall("GetU64", (ulong) 1000008, mainAddress); | |
101 debuggerMock.RecordCall("GetU64", (ulong) 1000000, dummyValidAddress); | |
102 debuggerMock.RecordCall("GetU64", (ulong) 999984, dummyValidAddress); | |
103 debuggerMock.RecordCall("GetU64", (ulong) 999992, dummyValidAddress); | |
104 var returned = target.EnumFrameInfo( | |
105 dwFieldSpec, nRadix, out ppDebugFrames); | |
106 Assert.AreEqual(VSConstants.S_OK, returned); | |
107 uint frameCount; | |
108 ppDebugFrames.GetCount(out frameCount); | |
109 Assert.AreEqual((uint) 4, frameCount); | |
110 } | |
111 } | |
112 } | |
OLD | NEW |