Index: visual_studio/NativeClientVSAddIn/UnitTests/PluginDebuggerVSTest.cs |
diff --git a/visual_studio/NativeClientVSAddIn/UnitTests/PluginDebuggerVSTest.cs b/visual_studio/NativeClientVSAddIn/UnitTests/PluginDebuggerVSTest.cs |
new file mode 100644 |
index 0000000000000000000000000000000000000000..dd37310367ff681666bdbc2ce088b62ba3673819 |
--- /dev/null |
+++ b/visual_studio/NativeClientVSAddIn/UnitTests/PluginDebuggerVSTest.cs |
@@ -0,0 +1,286 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+namespace UnitTests |
+{ |
+ using System; |
+ using System.Reflection; |
+ |
+ using EnvDTE80; |
+ using Microsoft.VisualStudio.TestTools.UnitTesting; |
+ |
+ using NativeClientVSAddIn; |
+ |
+ /// <summary> |
+ /// This is a test class for PluginDebuggerVSTest and is intended |
+ /// to contain all PluginDebuggerVS Unit Tests |
+ /// </summary> |
+ [TestClass] |
+ public class PluginDebuggerVSTest |
+ { |
+ /// <summary> |
+ /// The main visual studio object. |
+ /// </summary> |
+ private DTE2 dte_; |
+ |
+ /// <summary> |
+ /// Holds the default properties from property pages to use during tests. |
+ /// </summary> |
+ private MockPropertyManager properties_; |
+ |
+ /// <summary> |
+ /// Gets or sets the test context which provides information about, |
+ /// and functionality for the current test run. |
+ /// </summary> |
+ public TestContext TestContext { get; set; } |
+ |
+ /// <summary> |
+ /// This is run before each test to create test resources. |
+ /// </summary> |
+ [TestInitialize] |
+ public void TestSetup() |
+ { |
+ dte_ = TestUtilities.StartVisualStudioInstance(); |
+ try |
+ { |
+ TestUtilities.AssertAddinLoaded(dte_, NativeClientVSAddIn.Strings.AddInName); |
+ } |
+ catch |
+ { |
+ TestUtilities.CleanUpVisualStudioInstance(dte_); |
+ throw; |
+ } |
+ |
+ // Set up mock property manager to return the desired property values. |
+ properties_ = new MockPropertyManager( |
+ PropertyManager.ProjectPlatformType.Pepper, |
+ delegate(string page, string name) |
+ { |
+ switch (page) |
+ { |
+ case "ConfigurationGeneral": |
+ switch (name) |
+ { |
+ case "VSNaClSDKRoot": return System.Environment.GetEnvironmentVariable( |
+ NativeClientVSAddIn.Strings.SDKPathEnvironmentVariable); |
+ } |
+ |
+ break; |
+ case "Property": |
+ switch (name) |
+ { |
+ case "ProjectDirectory": return TestContext.DeploymentDirectory; |
+ case "PluginAssembly": return @"fake\Assembly\String"; |
+ } |
+ |
+ break; |
+ } |
+ |
+ return null; |
+ }, |
+ null); |
+ } |
+ |
+ /// <summary> |
+ /// This is run after each test to clean up things created in TestSetup(). |
+ /// </summary> |
+ [TestCleanup] |
+ public void TestCleanup() |
+ { |
+ TestUtilities.CleanUpVisualStudioInstance(dte_); |
+ } |
+ |
+ /// <summary> |
+ /// A test for the constructor. |
+ /// </summary> |
+ [TestMethod] |
+ public void PluginDebuggerVSConstructorTest() |
+ { |
+ // Check that a null dte fails. |
+ try |
+ { |
+ PluginDebuggerBase nullDte = new PluginDebuggerVS(null, properties_); |
+ Assert.Fail("Using null DTE instance did not throw exception"); |
+ } |
+ catch (ArgumentNullException) |
+ { |
+ // This is expected for a correct implementation. |
+ } |
+ catch |
+ { |
+ Assert.Fail("Using null DTE instance threw something other than ArgumentNullException"); |
+ } |
+ |
+ // Check that a null PropertyManager fails. |
+ try |
+ { |
+ PluginDebuggerBase nullDte = new PluginDebuggerVS(dte_, null); |
+ Assert.Fail("Using null property manager did not throw exception"); |
+ } |
+ catch (ArgumentNullException) |
+ { |
+ // This is expected for a correct implementation. |
+ } |
+ catch |
+ { |
+ Assert.Fail("Using null property manager threw something other than ArgumentNullException"); |
+ } |
+ } |
+ |
+ /// <summary> |
+ /// A test for FindAndAttachToPlugin. |
+ /// </summary> |
+ [TestMethod] |
+ [DeploymentItem("NativeClientVSAddIn.dll")] |
+ public void FindAndAttachToPepperPluginTest() |
+ { |
+ MockProcessSearcher processResults = new MockProcessSearcher(); |
+ |
+ using (PluginDebuggerVS target = new PluginDebuggerVS(dte_, properties_)) |
+ { |
+ PluginDebuggerBase_Accessor targetBase = new PluginDebuggerBase_Accessor( |
+ new PrivateObject(target, new PrivateType(typeof(PluginDebuggerBase)))); |
+ targetBase.debuggedChromeMainProcess_ = System.Diagnostics.Process.GetCurrentProcess(); |
+ uint currentProcId = (uint)targetBase.debuggedChromeMainProcess_.Id; |
+ |
+ string pluginLoadFlag = string.Format( |
+ Strings.PepperProcessPluginFlagFormat, properties_.PluginAssembly); |
+ string pepperCommandLine = string.Concat( |
+ pluginLoadFlag, " ", Strings.ChromeRendererFlag); |
+ |
+ // Fake the list of processes on the system. |
+ processResults.ProcessList.Add( |
+ new ProcessInfo( |
+ currentProcId, |
+ currentProcId, |
+ string.Empty, |
+ Strings.NaClDebugFlag, |
+ Strings.ChromeProcessName)); |
+ processResults.ProcessList.Add( |
+ new ProcessInfo(1, currentProcId, string.Empty, string.Empty, "MyParentProcess")); |
+ processResults.ProcessList.Add( |
+ new ProcessInfo(10, 1, string.Empty, pepperCommandLine, Strings.ChromeProcessName)); |
+ |
+ // This is missing some relevant command line args, and should not be attached to. |
+ processResults.ProcessList.Add( |
+ new ProcessInfo(12, 1, string.Empty, pluginLoadFlag, Strings.ChromeProcessName)); |
+ |
+ // This doesn't have this process as its parent, and should not be attached to. |
+ processResults.ProcessList.Add( |
+ new ProcessInfo(14, 14, string.Empty, pepperCommandLine, Strings.ChromeProcessName)); |
+ |
+ // Set the private value to the mock object (can't use accessor since no valid cast). |
+ FieldInfo processSearcherField = typeof(PluginDebuggerBase).GetField( |
+ "processSearcher_", |
+ BindingFlags.NonPublic | BindingFlags.Instance); |
+ processSearcherField.SetValue(targetBase.Target, processResults); |
+ |
+ // Test that the correct processes are attached to. |
+ bool goodPepper = false; |
+ var handler = new EventHandler<NativeClientVSAddIn.PluginDebuggerBase.PluginFoundEventArgs>( |
+ delegate(object unused, NativeClientVSAddIn.PluginDebuggerBase.PluginFoundEventArgs args) |
+ { |
+ switch (args.ProcessID) |
+ { |
+ case 10: |
+ if (goodPepper) |
+ { |
+ Assert.Fail("Should not attach twice to same pepper process"); |
+ } |
+ |
+ goodPepper = true; |
+ break; |
+ case 12: |
+ Assert.Fail("Should not attach to pepper process with bad args"); |
+ break; |
+ case 14: |
+ Assert.Fail("Should not attach to pepper process that is not " |
+ + "descendant of Visual Studio"); |
+ break; |
+ default: |
+ Assert.Fail("Should not attach to non-pepper/non-nacl process"); |
+ break; |
+ } |
+ }); |
+ |
+ target.PluginFoundEvent += handler; |
+ target.FindAndAttachToPlugin(null, null); |
+ target.PluginFoundEvent -= handler; |
+ |
+ Assert.IsTrue(goodPepper, "Failed to attach to pepper process"); |
+ } |
+ } |
+ |
+ /// <summary> |
+ /// Checks that VS properly attaches debugger. |
+ /// </summary> |
+ [TestMethod] |
+ [DeploymentItem("NativeClientVSAddIn.dll")] |
+ public void AttachVSDebuggerTest() |
+ { |
+ using (System.Diagnostics.Process dummyProc = TestUtilities.StartProcessForKilling( |
+ "DummyProc", 20)) |
+ { |
+ try |
+ { |
+ PluginDebuggerVS_Accessor target = new PluginDebuggerVS_Accessor(dte_, properties_); |
+ |
+ var pluginFoundArgs = new NativeClientVSAddIn.PluginDebuggerBase.PluginFoundEventArgs( |
+ (uint)dummyProc.Id); |
+ target.Attach(null, pluginFoundArgs); |
+ |
+ bool isBeingDebugged = false; |
+ foreach (EnvDTE.Process proc in dte_.Debugger.DebuggedProcesses) |
+ { |
+ if (proc.ProcessID == dummyProc.Id) |
+ { |
+ isBeingDebugged = true; |
+ } |
+ } |
+ |
+ Assert.IsTrue(isBeingDebugged, "Visual Studio debugger did not attach"); |
+ } |
+ finally |
+ { |
+ if (dummyProc != null && !dummyProc.HasExited) |
+ { |
+ dummyProc.Kill(); |
+ dummyProc.Dispose(); |
+ } |
+ } |
+ } |
+ } |
+ |
+ /// <summary> |
+ /// A test for IsPluginProcess. |
+ /// </summary> |
+ [TestMethod] |
+ [DeploymentItem("NativeClientVSAddIn.dll")] |
+ public void IsPepperPluginProcessTest() |
+ { |
+ PluginDebuggerVS_Accessor target = new PluginDebuggerVS_Accessor(dte_, properties_); |
+ |
+ string identifierFlagTarget = |
+ string.Format(Strings.PepperProcessPluginFlagFormat, target.pluginAssembly_); |
+ string goodFlags = string.Concat(Strings.ChromeRendererFlag, ' ', identifierFlagTarget); |
+ |
+ ProcessInfo badProc1 = new ProcessInfo( |
+ 1, 1, string.Empty, goodFlags, Strings.NaClProcessName); |
+ ProcessInfo badProc2 = new ProcessInfo( |
+ 1, 1, string.Empty, Strings.NaClLoaderFlag, Strings.ChromeProcessName); |
+ ProcessInfo badProc3 = new ProcessInfo( |
+ 1, 1, string.Empty, Strings.ChromeRendererFlag, Strings.ChromeProcessName); |
+ ProcessInfo badProc4 = new ProcessInfo( |
+ 1, 1, string.Empty, identifierFlagTarget, Strings.ChromeProcessName); |
+ ProcessInfo goodProc = new ProcessInfo( |
+ 1, 1, string.Empty, goodFlags, Strings.ChromeProcessName); |
+ |
+ Assert.IsTrue(target.IsPluginProcess(goodProc, string.Empty)); |
+ Assert.IsFalse(target.IsPluginProcess(badProc1, string.Empty)); |
+ Assert.IsFalse(target.IsPluginProcess(badProc2, string.Empty)); |
+ Assert.IsFalse(target.IsPluginProcess(badProc3, string.Empty)); |
+ Assert.IsFalse(target.IsPluginProcess(badProc4, string.Empty)); |
+ } |
+ } |
+} |