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 System; | |
8 using System.Collections.Generic; | |
9 using System.Linq; | |
10 using Google.MsAd7.BaseImpl; | |
11 using Google.MsAd7.BaseImpl.DebugProperties; | |
12 using Google.MsAd7.BaseImpl.Interfaces.SimpleSymbolTypes; | |
13 using Google.NaClVsx.DebugSupport; | |
14 using Microsoft.VisualStudio.TestTools.UnitTesting; | |
15 | |
16 #endregion | |
17 | |
18 namespace NaClVsx.Package_UnitTestProject { | |
19 ///<summary> | |
20 /// This is a test class for NaClSymbolProviderTest and is intended | |
21 /// to contain all NaClSymbolProviderTest Unit Tests | |
22 ///</summary> | |
23 [TestClass] | |
24 public class NaClSymbolProviderTest { | |
25 ///<summary> | |
26 /// Gets or sets the test context which provides | |
27 /// information about and functionality for the current test run. | |
28 ///</summary> | |
29 public TestContext TestContext { get; set; } | |
30 | |
31 #region Additional test attributes | |
32 | |
33 //Use TestInitialize to run code before running each test | |
34 [TestInitialize] | |
35 public void MyTestInitialize() { | |
36 sym_ = NaClPackageTestUtils.LoadLoopNexe(); | |
37 Assert.IsNotNull(sym_, "NaClSymbolProviderTest could not initialize."); | |
38 } | |
39 | |
40 #endregion | |
41 | |
42 ///<summary> | |
43 /// A test for PositionFromAddress | |
44 ///</summary> | |
45 [TestMethod] | |
46 public void PositionFromAddressTest() { | |
47 const uint kLoopCCLine = NaClPackageTestUtils.kPrintLineRow; | |
48 var address = NaClPackageTestUtils.GetAddressForPosition( | |
49 NaClPackageTestUtils.GetLoopCCPath(), kLoopCCLine, sym_); | |
50 var returnedPosition = | |
51 sym_.PositionFromAddress(address); | |
52 Assert.IsNotNull(returnedPosition); | |
53 Assert.AreEqual(returnedPosition.BeginPos.dwLine, kLoopCCLine); | |
54 Assert.AreEqual( | |
55 NaClPackageTestUtils.GetLoopCCPath(), | |
56 returnedPosition.Path); | |
57 } | |
58 | |
59 ///<summary> | |
60 /// A test for AddressesFromPosition. We can't hardcode addresses so we | |
61 /// just test that an address is being returned. | |
62 ///</summary> | |
63 [TestMethod] | |
64 public void AddressesFromPositionTest() { | |
65 const uint kLoopCCLine = NaClPackageTestUtils.kPrintLineRow; | |
66 var address = NaClPackageTestUtils.GetAddressForPosition( | |
67 NaClPackageTestUtils.GetLoopCCPath(), kLoopCCLine, sym_); | |
68 Assert.IsTrue(address > sym_.BaseAddress); | |
69 } | |
70 | |
71 /// <summary> | |
72 /// A test for GetSymbolsInScope. We should test a function that is not | |
73 /// at the beginning of the file, to make sure the debugger can | |
74 /// disambiguate. We should also test the beginning and end of its scope | |
75 /// to make sure that there are no off-by-one errors. | |
76 /// </summary> | |
77 [TestMethod] | |
78 public void GetSymbolsInScopeTest() { | |
79 // This is the beginning of the main function. (Note that the lines are | |
80 // 0-indexed in this context, so we're really looking at line 44. If the | |
81 // function being tested works, we should get 5 symbols: argc, argv, | |
82 // g_GlobalData, x, and y. | |
83 var pos = new DocumentPosition( | |
84 NaClPackageTestUtils.GetLoopCCPath(), | |
85 NaClPackageTestUtils.kMainStartRow); | |
86 var expectedNames = new List<string> { | |
87 "x", | |
88 "y", | |
89 "test_string", | |
90 "argc", | |
91 "argv", | |
92 "g_GlobalData" | |
93 }; | |
94 TestForSymbolsInScopeAt(pos, expectedNames); | |
95 | |
96 // This is the line of the closing paren, at which the local variables | |
97 // should be out of scope. | |
98 pos = new DocumentPosition( | |
99 NaClPackageTestUtils.GetLoopCCPath(), | |
100 NaClPackageTestUtils.kMainEndRow); | |
101 expectedNames.Remove("x"); | |
102 expectedNames.Remove("y"); | |
103 expectedNames.Remove("test_string"); | |
104 TestForSymbolsInScopeAt(pos, expectedNames); | |
105 } | |
106 | |
107 [TestMethod] | |
108 public void GetSymbolTypeIntTest() { | |
109 var addr = NaClPackageTestUtils.GetAddressForPosition( | |
110 NaClPackageTestUtils.GetLoopCCPath(), | |
111 NaClPackageTestUtils.kDeclarationOfIRow, | |
112 sym_); | |
113 var symbols = sym_.GetSymbolsInScope(addr); | |
114 | |
115 // first symbol should be "i" | |
116 var s = symbols.First(); | |
117 Assert.AreEqual("i", s.Name); | |
118 var t = sym_.GetSymbolType(s.Key); | |
119 | |
120 Assert.AreEqual("int", t.Name); | |
121 Assert.IsTrue(4 == t.SizeOf); | |
122 Assert.IsFalse(0 == t.Key); | |
123 Assert.IsFalse(t.Key == s.Key); | |
124 } | |
125 | |
126 [TestMethod] | |
127 public void GetSymbolTypeStringTest() { | |
128 var addr = NaClPackageTestUtils.GetAddressForPosition( | |
129 NaClPackageTestUtils.GetLoopCCPath(), | |
130 NaClPackageTestUtils.kDeclarationOfTestStringRow, | |
131 sym_); | |
132 var symbols = sym_.GetSymbolsInScope(addr); | |
133 | |
134 var testStringSymbol = new Symbol { | |
135 Name = null, | |
136 Key = 0 | |
137 }; | |
138 foreach (var symbol in symbols) { | |
139 if ("test_string" == symbol.Name) { | |
140 testStringSymbol = symbol; | |
141 } | |
142 } | |
143 Assert.IsNotNull(testStringSymbol.Name); | |
144 Assert.AreNotEqual(0, testStringSymbol.Key); | |
145 | |
146 Assert.AreEqual("test_string", testStringSymbol.Name); | |
147 var symbolType = sym_.GetSymbolType(testStringSymbol.Key); | |
148 | |
149 Assert.AreEqual("string", symbolType.Name); | |
150 Assert.IsTrue(4 == symbolType.SizeOf); | |
151 Assert.IsFalse(0 == symbolType.Key); | |
152 Assert.IsFalse(symbolType.Key == testStringSymbol.Key); | |
153 } | |
154 | |
155 [TestMethod] | |
156 public void GetSymbolValueTest() { | |
157 // loop.cc(10,0): | |
158 // should have global variable g_gGlobalData, formal | |
159 // parameter "count" and local variable "i" | |
160 var addr = NaClPackageTestUtils.GetAddressForPosition( | |
161 NaClPackageTestUtils.GetLoopCCPath(), | |
162 NaClPackageTestUtils.kPrintLineRow, | |
163 sym_); | |
164 var symbols = sym_.GetSymbolsInScope(addr); | |
165 | |
166 // first symbol should be "i" | |
167 var symbol = symbols.First(); | |
168 | |
169 Assert.AreEqual("i", symbol.Name); | |
170 | |
171 var bytes = BitConverter.GetBytes((Int64) 1234567); | |
172 var arrBytes = new ArraySegment<byte>(bytes); | |
173 var symbolValue = sym_.SymbolValueToString(symbol.Key, arrBytes); | |
174 Assert.AreEqual(symbolValue, "1234567"); | |
175 | |
176 bytes = BitConverter.GetBytes((Int64) (-1234567)); | |
177 arrBytes = new ArraySegment<byte>(bytes); | |
178 symbolValue = sym_.SymbolValueToString(symbol.Key, arrBytes); | |
179 Assert.AreEqual(symbolValue, "-1234567"); | |
180 } | |
181 | |
182 [TestMethod] | |
183 public void GetSymbolCharValueTest() { | |
184 var addr = NaClPackageTestUtils.GetAddressForPosition( | |
185 NaClPackageTestUtils.GetLoopCCPath(), | |
186 NaClPackageTestUtils.kPrintCharTypePrintfRow, | |
187 sym_); | |
188 var symbols = sym_.GetSymbolsInScope(addr); | |
189 // Should have 2 vars in this scope: | |
190 // global variable g_gGlobalData, and local variable "c". | |
191 Assert.AreEqual(2, symbols.Count()); | |
192 | |
193 // First symbol should be for 'char c' | |
194 var s = symbols.First(); | |
195 | |
196 // Make sure we can convert a 1 byte char | |
197 var bytes = new byte[1]; | |
198 var char_value = 'I'; | |
199 bytes[0] = (byte) char_value; // ASCII value for 'I' | |
200 var arrBytes = new ArraySegment<byte>(bytes); | |
201 var str_obj = sym_.SymbolValueToString(s.Key, arrBytes); | |
202 Assert.AreEqual("73", str_obj); | |
203 // NOTE: since the input was a byte value of 73 for 'I' | |
204 // the output of this is a string with that value "73" | |
205 // The VSX debugger env formats this as a 'char' because | |
206 // of the data type of the variable, so we | |
207 // convert the string value to a number (e.g. "73" -> 73) | |
208 // and then check the char value and also format the | |
209 // char value in a string and check that too | |
210 var result_ascii_val = Convert.ToInt16(str_obj); | |
211 var result_char = Convert.ToChar(result_ascii_val); | |
212 Assert.AreEqual('I', result_char); | |
213 Assert.AreEqual( | |
214 "I", | |
215 String.Format( | |
216 "{0:c}", Convert.ToChar(result_char))); | |
217 } | |
218 | |
219 ///<summary> | |
220 /// A test for GetNextLocation | |
221 ///</summary> | |
222 [TestMethod] | |
223 public void GetNextLocationTest() { | |
224 //Assert.Inconclusive("Verify the correctness of this test method."); | |
225 } | |
226 | |
227 ///<summary> | |
228 /// A test for GetFunctionDetails | |
229 ///</summary> | |
230 [TestMethod] | |
231 public void GetFunctionDetailsTest() { | |
232 //Assert.Inconclusive("Verify the correctness of this test method."); | |
233 } | |
234 | |
235 /// <summary> | |
236 /// A test for GetPreviousFrameState | |
237 /// </summary> | |
238 [TestMethod] | |
239 public void GetPreviousFrameStateTest() { | |
240 var currentRegisters = new RegisterSet( | |
241 RegisterSetSchema.DwarfAmd64Integer, null); | |
242 // TODO: Initialize to an appropriate value | |
243 var address = NaClPackageTestUtils.GetAddressForPosition( | |
244 NaClPackageTestUtils.GetLoopCCPath(), | |
245 NaClPackageTestUtils.kPrintLineRow, | |
246 sym_); | |
247 var privates = new PrivateObject(sym_); | |
248 // We have to mock the calls into the symbol database to try to retrieve | |
249 // memory from the debugger. | |
250 var debuggerMock = new NaClDebuggerMock(); | |
251 debuggerMock.RecordCall("GetU64", (ulong) 123464, (ulong) 256100); | |
252 debuggerMock.RecordCall("GetU64", (ulong) 123456, (ulong) 256200); | |
253 privates.SetField("dbg_", debuggerMock); | |
254 | |
255 currentRegisters["RIP"] = address; | |
256 currentRegisters["RBP"] = 123456 + sym_.BaseAddress; | |
257 | |
258 var result = sym_.GetPreviousFrameState(currentRegisters); | |
259 Assert.AreEqual((ulong) 256100, result["RIP"]); | |
260 Assert.AreEqual((ulong) 256200, result["RBP"]); | |
261 Assert.AreEqual((ulong) 51539731024, result["CFA"]); | |
262 // Check the new boundary condition with an RIP value that outside the | |
263 // memory range. | |
264 currentRegisters["RIP"] = 1 + sym_.BaseAddress + sym_.BaseAddress; | |
265 result = sym_.GetPreviousFrameState(currentRegisters); | |
266 Assert.IsNull(result); | |
267 // And with an address that is too low to be in our untrusted memory | |
268 // range. | |
269 currentRegisters["RIP"] = 1; | |
270 result = sym_.GetPreviousFrameState(currentRegisters); | |
271 Assert.IsNull(result); | |
272 } | |
273 | |
274 ///<summary> | |
275 /// A test for FunctionFromAddress | |
276 ///</summary> | |
277 [TestMethod] | |
278 public void FunctionFromAddressTest() { | |
279 var address = NaClPackageTestUtils.GetAddressForPosition( | |
280 NaClPackageTestUtils.GetLoopCCPath(), | |
281 NaClPackageTestUtils.kPrintLineRow, | |
282 sym_); | |
283 var actual = sym_.FunctionFromAddress(address); | |
284 Assert.AreEqual("print_line", actual.Name); | |
285 } | |
286 | |
287 | |
288 ///<summary> | |
289 /// A test for NaClSymbolProvider Constructor | |
290 ///</summary> | |
291 [TestMethod] | |
292 public void NaClSymbolProviderConstructorTest() { | |
293 //Assert.Inconclusive("TODO: Implement code to verify target"); | |
294 } | |
295 | |
296 #region Private Implementation | |
297 | |
298 private NaClSymbolProvider sym_; | |
299 | |
300 #endregion | |
301 | |
302 #region Private Implementation | |
303 | |
304 private void TestForSymbolsInScopeAt( | |
305 DocumentPosition position, | |
306 IEnumerable<string> expectedSymbols) { | |
307 var addresses = sym_.AddressesFromPosition(position); | |
308 var address = addresses.First(); | |
309 | |
310 var symbols = sym_.GetSymbolsInScope(address); | |
311 Assert.AreEqual(expectedSymbols.Count(), symbols.Count()); | |
312 | |
313 foreach (var symbol in symbols) { | |
314 Assert.IsTrue(expectedSymbols.Contains(symbol.Name)); | |
315 } | |
316 } | |
317 | |
318 #endregion | |
319 } | |
320 } | |
OLD | NEW |