| Index: visual_studio/NativeClientVSAddIn/UnitTests/TestUtilities.cs
|
| diff --git a/visual_studio/NativeClientVSAddIn/UnitTests/TestUtilities.cs b/visual_studio/NativeClientVSAddIn/UnitTests/TestUtilities.cs
|
| index 788a7a0223bedc38141d95f1ed76c550b82f3b9e..20a78dd9da396881864155f00e467f26a632d3db 100644
|
| --- a/visual_studio/NativeClientVSAddIn/UnitTests/TestUtilities.cs
|
| +++ b/visual_studio/NativeClientVSAddIn/UnitTests/TestUtilities.cs
|
| @@ -1,463 +1,463 @@
|
| -// 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.Collections.Generic;
|
| - using System.IO;
|
| - using System.Linq;
|
| - using System.Management;
|
| -
|
| - using EnvDTE;
|
| - using EnvDTE80;
|
| - using Microsoft.VisualStudio.TestTools.UnitTesting;
|
| - using Microsoft.VisualStudio.VCProjectEngine;
|
| -
|
| - /// <summary>
|
| - /// This class contains utilities for running tests.
|
| - /// </summary>
|
| - public static class TestUtilities
|
| - {
|
| - /// <summary>
|
| - /// Name of the NaCl project in BlankValidSolution.
|
| - /// </summary>
|
| - public const string BlankNaClProjectName = @"NaClProject";
|
| -
|
| - /// <summary>
|
| - /// Uniquename of the NaCl project in BlankValidSolution.
|
| - /// </summary>
|
| - public const string BlankNaClProjectUniqueName = @"NaClProject\NaClProject.vcxproj";
|
| -
|
| - /// <summary>
|
| - /// Uniquename of the non-NaCl project in BlankValidSolution.
|
| - /// </summary>
|
| - public const string NotNaClProjectUniqueName = @"NotNaCl\NotNaCl.csproj";
|
| -
|
| - /// <summary>
|
| - /// A generic boolean statement to be used with RetryWithTimeout.
|
| - /// </summary>
|
| - /// <returns>True if the statement is true, false if false.</returns>
|
| - public delegate bool RetryStatement();
|
| -
|
| - /// <summary>
|
| - /// This starts an instance of Visual Studio and get its DTE object.
|
| - /// </summary>
|
| - /// <returns>DTE of the started instance.</returns>
|
| - public static DTE2 StartVisualStudioInstance()
|
| - {
|
| - // Set up filter to handle threading events and automatically retry calls
|
| - // to dte which fail because dte is busy.
|
| - ComMessageFilter.Register();
|
| -
|
| - Type visualStudioType = Type.GetTypeFromProgID("VisualStudio.DTE.10.0");
|
| - DTE2 visualStudio = Activator.CreateInstance(visualStudioType) as DTE2;
|
| - if (visualStudio == null)
|
| - {
|
| - throw new Exception("Visual Studio failed to start");
|
| - }
|
| -
|
| - visualStudio.MainWindow.Visible = true;
|
| - return visualStudio;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// This properly cleans up after StartVisualStudioInstance().
|
| - /// </summary>
|
| - /// <param name="dte">Dte instance returned by StartVisualStudioInstance().</param>
|
| - public static void CleanUpVisualStudioInstance(DTE2 dte)
|
| - {
|
| - if (dte != null)
|
| - {
|
| - if (dte.Solution != null)
|
| - {
|
| - dte.Solution.Close();
|
| - }
|
| -
|
| - dte.Quit();
|
| - }
|
| -
|
| - // Stop the message filter.
|
| - ComMessageFilter.Revoke();
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Creates a blank valid NaCl project with up-to-date settings. The path to the new solution
|
| - /// is returned.
|
| - /// </summary>
|
| - /// <param name="dte">Interface to an open Visual Studio instance to use.</param>
|
| - /// <param name="name">Name to give newly created solution.</param>
|
| - /// <param name="pepperCopyFrom">Platform name to copy existing settings from to pepper.</param>
|
| - /// <param name="naclCopyFrom">Platform name to copy existing settings from to NaCl.</param>
|
| - /// <param name="testContext">Test context used for finding deployment directory.</param>
|
| - /// <returns>Path to the newly created solution.</returns>
|
| - public static string CreateBlankValidNaClSolution(
|
| - DTE2 dte, string name, string pepperCopyFrom, string naclCopyFrom, TestContext testContext)
|
| - {
|
| - const string BlankSolution = "BlankValidSolution";
|
| - string newSolutionDir = Path.Combine(testContext.DeploymentDirectory, name);
|
| - string newSolution = Path.Combine(newSolutionDir, BlankSolution + ".sln");
|
| - CopyDirectory(Path.Combine(testContext.DeploymentDirectory, BlankSolution), newSolutionDir);
|
| -
|
| - try
|
| - {
|
| - dte.Solution.Open(newSolution);
|
| - Project proj = dte.Solution.Projects.Item(BlankNaClProjectUniqueName);
|
| -
|
| - // Order matters if copying from the other Native Client type.
|
| - if (pepperCopyFrom.Equals(NativeClientVSAddIn.Strings.NaClPlatformName))
|
| - {
|
| - proj.ConfigurationManager.AddPlatform(
|
| - NativeClientVSAddIn.Strings.NaClPlatformName, naclCopyFrom, true);
|
| - proj.ConfigurationManager.AddPlatform(
|
| - NativeClientVSAddIn.Strings.PepperPlatformName, pepperCopyFrom, true);
|
| - }
|
| - else
|
| - {
|
| - proj.ConfigurationManager.AddPlatform(
|
| - NativeClientVSAddIn.Strings.PepperPlatformName, pepperCopyFrom, true);
|
| - proj.ConfigurationManager.AddPlatform(
|
| - NativeClientVSAddIn.Strings.NaClPlatformName, naclCopyFrom, true);
|
| - }
|
| -
|
| - // Set the active solution configuration to Debug|NaCl.
|
| - SetSolutionConfiguration(
|
| - dte, BlankNaClProjectUniqueName, "Debug", NativeClientVSAddIn.Strings.NaClPlatformName);
|
| -
|
| - proj.Save();
|
| - dte.Solution.SaveAs(newSolution);
|
| - }
|
| - finally
|
| - {
|
| - if (dte.Solution != null)
|
| - {
|
| - dte.Solution.Close();
|
| - }
|
| - }
|
| -
|
| - return newSolution;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// This returns the text contained in the given output window pane.
|
| - /// </summary>
|
| - /// <param name="pane">Pane to get text from.</param>
|
| - /// <returns>Text in the window.</returns>
|
| - public static string GetPaneText(OutputWindowPane pane)
|
| - {
|
| - TextSelection selection = pane.TextDocument.Selection;
|
| - selection.StartOfDocument(false);
|
| - selection.EndOfDocument(true);
|
| - return selection.Text;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// This starts a python process that just sleeps waiting to be killed.
|
| - /// It can be used with DoesProcessExist() to verify that a process started/exited.
|
| - /// </summary>
|
| - /// <param name="identifierString">
|
| - /// A unique string to identify the process via its command line arguments.
|
| - /// </param>
|
| - /// <param name="timeout">Time in seconds to wait before process exits on its own.</param>
|
| - /// <returns>The process object that was started.</returns>
|
| - public static System.Diagnostics.Process StartProcessForKilling(
|
| - string identifierString, int timeout)
|
| - {
|
| - string args = string.Format(
|
| - "-c \"import time; time.sleep({0}); print '{1}'\"",
|
| - timeout,
|
| - identifierString);
|
| - System.Diagnostics.Process proc = new System.Diagnostics.Process();
|
| - proc.StartInfo.CreateNoWindow = true;
|
| - proc.StartInfo.UseShellExecute = false;
|
| - proc.StartInfo.FileName = "python.exe";
|
| - proc.StartInfo.Arguments = args;
|
| - proc.Start();
|
| - return proc;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// This returns true if there is a running process that has command line arguments
|
| - /// containing the given Strings. The search is case-insensitive.
|
| - /// </summary>
|
| - /// <param name="processName">Name of the process executable.</param>
|
| - /// <param name="commandLineIdentifiers">Strings to check for.</param>
|
| - /// <returns>True if some process has the Strings in its command line arguments.</returns>
|
| - public static bool DoesProcessExist(string processName, params string[] commandLineIdentifiers)
|
| - {
|
| - List<string> results = new List<string>();
|
| - string query =
|
| - string.Format("select CommandLine from Win32_Process where Name='{0}'", processName);
|
| - using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
|
| - {
|
| - using (ManagementObjectCollection result = searcher.Get())
|
| - {
|
| - foreach (ManagementObject process in result)
|
| - {
|
| - string commandLine = process["CommandLine"] as string;
|
| - if (string.IsNullOrEmpty(commandLine))
|
| - {
|
| - break;
|
| - }
|
| -
|
| - // Check if the command line contains each of the required identifiers.
|
| - if (commandLineIdentifiers.All(i => commandLine.Contains(i)))
|
| - {
|
| - return true;
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - return false;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Sets the active configuration for the solution by specifying the configuration name
|
| - /// and platform name. A solution configuration containing a project configuration that has
|
| - /// the config and platform names specified for the specified project is selected.
|
| - /// </summary>
|
| - /// <param name="dte">The main visual studio object.</param>
|
| - /// <param name="projectUniqueName">UniqueName of the project to match.</param>
|
| - /// <param name="configurationName">Ex: "Debug" or "Release".</param>
|
| - /// <param name="platformName">Ex: "Win32" or "NaCl" or "PPAPI".</param>
|
| - public static void SetSolutionConfiguration(
|
| - DTE2 dte,
|
| - string projectUniqueName,
|
| - string configurationName,
|
| - string platformName)
|
| - {
|
| - foreach (EnvDTE.SolutionConfiguration config in
|
| - dte.Solution.SolutionBuild.SolutionConfigurations)
|
| - {
|
| - EnvDTE.SolutionContext context = null;
|
| - try
|
| - {
|
| - context = config.SolutionContexts.Item(projectUniqueName);
|
| - }
|
| - catch (ArgumentException)
|
| - {
|
| - throw new Exception(
|
| - string.Format("Project unique name not found in solution: {0}", projectUniqueName));
|
| - }
|
| -
|
| - if (context == null)
|
| - {
|
| - throw new Exception("Failed to get solution context");
|
| - }
|
| -
|
| - if (context.PlatformName == platformName && context.ConfigurationName == configurationName)
|
| - {
|
| - config.Activate();
|
| - return;
|
| - }
|
| - }
|
| -
|
| - throw new Exception(string.Format(
|
| - "Matching configuration not found for {0}: {1}|{2}",
|
| - projectUniqueName,
|
| - platformName,
|
| - configurationName));
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Returns a VCConfiguration object with a matching configuration name and platform type.
|
| - /// </summary>
|
| - /// <param name="project">Project to get the configuration from.</param>
|
| - /// <param name="name">Name of configuration (e.g. 'Debug').</param>
|
| - /// <param name="platform">Name of the platform (e.g. 'NaCl').</param>
|
| - /// <returns>A matching VCConfiguration object.</returns>
|
| - public static VCConfiguration GetVCConfiguration(Project project, string name, string platform)
|
| - {
|
| - VCProject vcproj = (VCProject)project.Object;
|
| - IVCCollection configs = vcproj.Configurations;
|
| -
|
| - foreach (VCConfiguration config in configs)
|
| - {
|
| - if (config.ConfigurationName == name && config.Platform.Name == platform)
|
| - {
|
| - return config;
|
| - }
|
| - }
|
| -
|
| - throw new Exception(
|
| - string.Format("Project does not have configuration: {0}|{1}", platform, name));
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Tests that a given property has a specific value in a certain VCConfiguration
|
| - /// </summary>
|
| - /// <param name="configuration">Gives the platform and configuration type</param>
|
| - /// <param name="pageName">Property page name where property resides.</param>
|
| - /// <param name="propertyName">Name of the property to check.</param>
|
| - /// <param name="expectedValue">Expected value of the property.</param>
|
| - /// <param name="ignoreCase">Ignore case when comparing the expected and actual values.</param>
|
| - public static void AssertPropertyEquals(
|
| - VCConfiguration configuration,
|
| - string pageName,
|
| - string propertyName,
|
| - string expectedValue,
|
| - bool ignoreCase)
|
| - {
|
| - IVCRulePropertyStorage rule = configuration.Rules.Item(pageName);
|
| - string callInfo = string.Format(
|
| - "Page: {0}, Property: {1}, Configuration: {2}",
|
| - pageName,
|
| - propertyName,
|
| - configuration.ConfigurationName);
|
| -
|
| - Assert.AreEqual(
|
| - expectedValue,
|
| - rule.GetUnevaluatedPropertyValue(propertyName),
|
| - ignoreCase,
|
| - callInfo);
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Tests that a given property contains a specific string in a certain VCConfiguration
|
| - /// </summary>
|
| - /// <param name="configuration">Gives the platform and configuration type</param>
|
| - /// <param name="pageName">Property page name where property resides.</param>
|
| - /// <param name="propertyName">Name of the property to check.</param>
|
| - /// <param name="expectedValue">Expected string to contain.</param>
|
| - /// <param name="ignoreCase">Ignore case when comparing the expected and actual values.</param>
|
| - public static void AssertPropertyContains(
|
| - VCConfiguration configuration,
|
| - string pageName,
|
| - string propertyName,
|
| - string expectedValue,
|
| - bool ignoreCase)
|
| - {
|
| - StringComparison caseSensitive = ignoreCase ?
|
| - StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
|
| -
|
| - IVCRulePropertyStorage rule = configuration.Rules.Item(pageName);
|
| - string propertyValue = rule.GetUnevaluatedPropertyValue(propertyName);
|
| -
|
| - string message = string.Format(
|
| - "{0} should be contained in {1}. Page: {2}, Property: {3}, Configuration: {4}",
|
| - expectedValue,
|
| - propertyValue,
|
| - pageName,
|
| - propertyName,
|
| - configuration.ConfigurationName);
|
| -
|
| - Assert.IsTrue(propertyValue.Contains(expectedValue, caseSensitive), message);
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Tests that a given property is not null or empty.
|
| - /// </summary>
|
| - /// <param name="configuration">Gives the platform and configuration type</param>
|
| - /// <param name="pageName">Property page name where property resides.</param>
|
| - /// <param name="propertyName">Name of the property to check.</param>
|
| - public static void AssertPropertyIsNotNullOrEmpty(
|
| - VCConfiguration configuration,
|
| - string pageName,
|
| - string propertyName)
|
| - {
|
| - IVCRulePropertyStorage rule = configuration.Rules.Item(pageName);
|
| - string propertyValue = rule.GetUnevaluatedPropertyValue(propertyName);
|
| -
|
| - string message = string.Format(
|
| - "{0} was null or empty. Page: {1}, Configuration: {2}",
|
| - propertyName,
|
| - pageName,
|
| - configuration.ConfigurationName);
|
| -
|
| - Assert.IsFalse(string.IsNullOrEmpty(propertyValue), message);
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Ensures that the add-in is configured to load on start. If it isn't then some tests may
|
| - /// unexpectedly fail, this check helps catch that problem early.
|
| - /// </summary>
|
| - /// <param name="dte">The main Visual Studio interface.</param>
|
| - /// <param name="addInName">The name of the add-in to check if loaded.</param>
|
| - public static void AssertAddinLoaded(DTE2 dte, string addInName)
|
| - {
|
| - bool found = false;
|
| - foreach (AddIn addin in dte.AddIns)
|
| - {
|
| - if (addin.Connected && addInName.Equals(addin.Name))
|
| - {
|
| - found = true;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - Assert.IsTrue(found, "Add-in is not configured to load on start.");
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Will retry the given statement up to maxRetry times while pausing between each try for
|
| - /// the given interval.
|
| - /// </summary>
|
| - /// <param name="test">Generic boolean statement.</param>
|
| - /// <param name="interval">Amount of time to wait between each retry.</param>
|
| - /// <param name="maxRetry">Maximum number of retries.</param>
|
| - /// <param name="message">Message to print on failure.</param>
|
| - public static void AssertTrueWithTimeout(
|
| - RetryStatement test, TimeSpan interval, int maxRetry, string message)
|
| - {
|
| - for (int tryCount = 0; tryCount <= maxRetry; tryCount++)
|
| - {
|
| - if (test.Invoke())
|
| - {
|
| - return;
|
| - }
|
| -
|
| - System.Threading.Thread.Sleep(interval);
|
| - }
|
| -
|
| - throw new Exception(string.Format("Statement timed out. {0}", message));
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Extends the string class to allow checking if a string contains another string
|
| - /// allowing a comparison type (such as case-insensitivity).
|
| - /// </summary>
|
| - /// <param name="source">Base string to search.</param>
|
| - /// <param name="toCheck">String to check if contained within base string.</param>
|
| - /// <param name="comparison">Comparison type.</param>
|
| - /// <returns>True if toCheck is contained in source.</returns>
|
| - public static bool Contains(this string source, string toCheck, StringComparison comparison)
|
| - {
|
| - return source.IndexOf(toCheck, comparison) != -1;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Copies the entire contents of a directory and sub directories.
|
| - /// </summary>
|
| - /// <param name="source">Directory to copy from.</param>
|
| - /// <param name="dest">Directory to copy to.</param>
|
| - public static void CopyDirectory(string source, string dest)
|
| - {
|
| - DirectoryInfo dir = new DirectoryInfo(source);
|
| -
|
| - if (!dir.Exists)
|
| - {
|
| - throw new DirectoryNotFoundException(source);
|
| - }
|
| -
|
| - if (!Directory.Exists(dest))
|
| - {
|
| - Directory.CreateDirectory(dest);
|
| - }
|
| -
|
| - FileInfo[] files = dir.GetFiles();
|
| - foreach (FileInfo file in files)
|
| - {
|
| - string path = Path.Combine(dest, file.Name);
|
| - file.CopyTo(path, false);
|
| - }
|
| -
|
| - foreach (DirectoryInfo subdir in dir.GetDirectories())
|
| - {
|
| - string path = Path.Combine(dest, subdir.Name);
|
| - CopyDirectory(subdir.FullName, path);
|
| - }
|
| - }
|
| - }
|
| -}
|
| +// 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.Collections.Generic;
|
| + using System.IO;
|
| + using System.Linq;
|
| + using System.Management;
|
| +
|
| + using EnvDTE;
|
| + using EnvDTE80;
|
| + using Microsoft.VisualStudio.TestTools.UnitTesting;
|
| + using Microsoft.VisualStudio.VCProjectEngine;
|
| +
|
| + /// <summary>
|
| + /// This class contains utilities for running tests.
|
| + /// </summary>
|
| + public static class TestUtilities
|
| + {
|
| + /// <summary>
|
| + /// Name of the NaCl project in BlankValidSolution.
|
| + /// </summary>
|
| + public const string BlankNaClProjectName = @"NaClProject";
|
| +
|
| + /// <summary>
|
| + /// Uniquename of the NaCl project in BlankValidSolution.
|
| + /// </summary>
|
| + public const string BlankNaClProjectUniqueName = @"NaClProject\NaClProject.vcxproj";
|
| +
|
| + /// <summary>
|
| + /// Uniquename of the non-NaCl project in BlankValidSolution.
|
| + /// </summary>
|
| + public const string NotNaClProjectUniqueName = @"NotNaCl\NotNaCl.csproj";
|
| +
|
| + /// <summary>
|
| + /// A generic boolean statement to be used with RetryWithTimeout.
|
| + /// </summary>
|
| + /// <returns>True if the statement is true, false if false.</returns>
|
| + public delegate bool RetryStatement();
|
| +
|
| + /// <summary>
|
| + /// This starts an instance of Visual Studio and get its DTE object.
|
| + /// </summary>
|
| + /// <returns>DTE of the started instance.</returns>
|
| + public static DTE2 StartVisualStudioInstance()
|
| + {
|
| + // Set up filter to handle threading events and automatically retry calls
|
| + // to dte which fail because dte is busy.
|
| + ComMessageFilter.Register();
|
| +
|
| + Type visualStudioType = Type.GetTypeFromProgID("VisualStudio.DTE.10.0");
|
| + DTE2 visualStudio = Activator.CreateInstance(visualStudioType) as DTE2;
|
| + if (visualStudio == null)
|
| + {
|
| + throw new Exception("Visual Studio failed to start");
|
| + }
|
| +
|
| + visualStudio.MainWindow.Visible = true;
|
| + return visualStudio;
|
| + }
|
| +
|
| + /// <summary>
|
| + /// This properly cleans up after StartVisualStudioInstance().
|
| + /// </summary>
|
| + /// <param name="dte">Dte instance returned by StartVisualStudioInstance().</param>
|
| + public static void CleanUpVisualStudioInstance(DTE2 dte)
|
| + {
|
| + if (dte != null)
|
| + {
|
| + if (dte.Solution != null)
|
| + {
|
| + dte.Solution.Close();
|
| + }
|
| +
|
| + dte.Quit();
|
| + }
|
| +
|
| + // Stop the message filter.
|
| + ComMessageFilter.Revoke();
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Creates a blank valid NaCl project with up-to-date settings. The path to the new solution
|
| + /// is returned.
|
| + /// </summary>
|
| + /// <param name="dte">Interface to an open Visual Studio instance to use.</param>
|
| + /// <param name="name">Name to give newly created solution.</param>
|
| + /// <param name="pepperCopyFrom">Platform name to copy existing settings from to pepper.</param>
|
| + /// <param name="naclCopyFrom">Platform name to copy existing settings from to NaCl.</param>
|
| + /// <param name="testContext">Test context used for finding deployment directory.</param>
|
| + /// <returns>Path to the newly created solution.</returns>
|
| + public static string CreateBlankValidNaClSolution(
|
| + DTE2 dte, string name, string pepperCopyFrom, string naclCopyFrom, TestContext testContext)
|
| + {
|
| + const string BlankSolution = "BlankValidSolution";
|
| + string newSolutionDir = Path.Combine(testContext.DeploymentDirectory, name);
|
| + string newSolution = Path.Combine(newSolutionDir, BlankSolution + ".sln");
|
| + CopyDirectory(Path.Combine(testContext.DeploymentDirectory, BlankSolution), newSolutionDir);
|
| +
|
| + try
|
| + {
|
| + dte.Solution.Open(newSolution);
|
| + Project proj = dte.Solution.Projects.Item(BlankNaClProjectUniqueName);
|
| +
|
| + // Order matters if copying from the other Native Client type.
|
| + if (pepperCopyFrom.Equals(NativeClientVSAddIn.Strings.NaClPlatformName))
|
| + {
|
| + proj.ConfigurationManager.AddPlatform(
|
| + NativeClientVSAddIn.Strings.NaClPlatformName, naclCopyFrom, true);
|
| + proj.ConfigurationManager.AddPlatform(
|
| + NativeClientVSAddIn.Strings.PepperPlatformName, pepperCopyFrom, true);
|
| + }
|
| + else
|
| + {
|
| + proj.ConfigurationManager.AddPlatform(
|
| + NativeClientVSAddIn.Strings.PepperPlatformName, pepperCopyFrom, true);
|
| + proj.ConfigurationManager.AddPlatform(
|
| + NativeClientVSAddIn.Strings.NaClPlatformName, naclCopyFrom, true);
|
| + }
|
| +
|
| + // Set the active solution configuration to Debug|NaCl.
|
| + SetSolutionConfiguration(
|
| + dte, BlankNaClProjectUniqueName, "Debug", NativeClientVSAddIn.Strings.NaClPlatformName);
|
| +
|
| + proj.Save();
|
| + dte.Solution.SaveAs(newSolution);
|
| + }
|
| + finally
|
| + {
|
| + if (dte.Solution != null)
|
| + {
|
| + dte.Solution.Close();
|
| + }
|
| + }
|
| +
|
| + return newSolution;
|
| + }
|
| +
|
| + /// <summary>
|
| + /// This returns the text contained in the given output window pane.
|
| + /// </summary>
|
| + /// <param name="pane">Pane to get text from.</param>
|
| + /// <returns>Text in the window.</returns>
|
| + public static string GetPaneText(OutputWindowPane pane)
|
| + {
|
| + TextSelection selection = pane.TextDocument.Selection;
|
| + selection.StartOfDocument(false);
|
| + selection.EndOfDocument(true);
|
| + return selection.Text;
|
| + }
|
| +
|
| + /// <summary>
|
| + /// This starts a python process that just sleeps waiting to be killed.
|
| + /// It can be used with DoesProcessExist() to verify that a process started/exited.
|
| + /// </summary>
|
| + /// <param name="identifierString">
|
| + /// A unique string to identify the process via its command line arguments.
|
| + /// </param>
|
| + /// <param name="timeout">Time in seconds to wait before process exits on its own.</param>
|
| + /// <returns>The process object that was started.</returns>
|
| + public static System.Diagnostics.Process StartProcessForKilling(
|
| + string identifierString, int timeout)
|
| + {
|
| + string args = string.Format(
|
| + "-c \"import time; time.sleep({0}); print '{1}'\"",
|
| + timeout,
|
| + identifierString);
|
| + System.Diagnostics.Process proc = new System.Diagnostics.Process();
|
| + proc.StartInfo.CreateNoWindow = true;
|
| + proc.StartInfo.UseShellExecute = false;
|
| + proc.StartInfo.FileName = "python.exe";
|
| + proc.StartInfo.Arguments = args;
|
| + proc.Start();
|
| + return proc;
|
| + }
|
| +
|
| + /// <summary>
|
| + /// This returns true if there is a running process that has command line arguments
|
| + /// containing the given Strings. The search is case-insensitive.
|
| + /// </summary>
|
| + /// <param name="processName">Name of the process executable.</param>
|
| + /// <param name="commandLineIdentifiers">Strings to check for.</param>
|
| + /// <returns>True if some process has the Strings in its command line arguments.</returns>
|
| + public static bool DoesProcessExist(string processName, params string[] commandLineIdentifiers)
|
| + {
|
| + List<string> results = new List<string>();
|
| + string query =
|
| + string.Format("select CommandLine from Win32_Process where Name='{0}'", processName);
|
| + using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
|
| + {
|
| + using (ManagementObjectCollection result = searcher.Get())
|
| + {
|
| + foreach (ManagementObject process in result)
|
| + {
|
| + string commandLine = process["CommandLine"] as string;
|
| + if (string.IsNullOrEmpty(commandLine))
|
| + {
|
| + break;
|
| + }
|
| +
|
| + // Check if the command line contains each of the required identifiers.
|
| + if (commandLineIdentifiers.All(i => commandLine.Contains(i)))
|
| + {
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + return false;
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Sets the active configuration for the solution by specifying the configuration name
|
| + /// and platform name. A solution configuration containing a project configuration that has
|
| + /// the config and platform names specified for the specified project is selected.
|
| + /// </summary>
|
| + /// <param name="dte">The main visual studio object.</param>
|
| + /// <param name="projectUniqueName">UniqueName of the project to match.</param>
|
| + /// <param name="configurationName">Ex: "Debug" or "Release".</param>
|
| + /// <param name="platformName">Ex: "Win32" or "NaCl" or "PPAPI".</param>
|
| + public static void SetSolutionConfiguration(
|
| + DTE2 dte,
|
| + string projectUniqueName,
|
| + string configurationName,
|
| + string platformName)
|
| + {
|
| + foreach (EnvDTE.SolutionConfiguration config in
|
| + dte.Solution.SolutionBuild.SolutionConfigurations)
|
| + {
|
| + EnvDTE.SolutionContext context = null;
|
| + try
|
| + {
|
| + context = config.SolutionContexts.Item(projectUniqueName);
|
| + }
|
| + catch (ArgumentException)
|
| + {
|
| + throw new Exception(
|
| + string.Format("Project unique name not found in solution: {0}", projectUniqueName));
|
| + }
|
| +
|
| + if (context == null)
|
| + {
|
| + throw new Exception("Failed to get solution context");
|
| + }
|
| +
|
| + if (context.PlatformName == platformName && context.ConfigurationName == configurationName)
|
| + {
|
| + config.Activate();
|
| + return;
|
| + }
|
| + }
|
| +
|
| + throw new Exception(string.Format(
|
| + "Matching configuration not found for {0}: {1}|{2}",
|
| + projectUniqueName,
|
| + platformName,
|
| + configurationName));
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Returns a VCConfiguration object with a matching configuration name and platform type.
|
| + /// </summary>
|
| + /// <param name="project">Project to get the configuration from.</param>
|
| + /// <param name="name">Name of configuration (e.g. 'Debug').</param>
|
| + /// <param name="platform">Name of the platform (e.g. 'NaCl').</param>
|
| + /// <returns>A matching VCConfiguration object.</returns>
|
| + public static VCConfiguration GetVCConfiguration(Project project, string name, string platform)
|
| + {
|
| + VCProject vcproj = (VCProject)project.Object;
|
| + IVCCollection configs = vcproj.Configurations;
|
| +
|
| + foreach (VCConfiguration config in configs)
|
| + {
|
| + if (config.ConfigurationName == name && config.Platform.Name == platform)
|
| + {
|
| + return config;
|
| + }
|
| + }
|
| +
|
| + throw new Exception(
|
| + string.Format("Project does not have configuration: {0}|{1}", platform, name));
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Tests that a given property has a specific value in a certain VCConfiguration
|
| + /// </summary>
|
| + /// <param name="configuration">Gives the platform and configuration type</param>
|
| + /// <param name="pageName">Property page name where property resides.</param>
|
| + /// <param name="propertyName">Name of the property to check.</param>
|
| + /// <param name="expectedValue">Expected value of the property.</param>
|
| + /// <param name="ignoreCase">Ignore case when comparing the expected and actual values.</param>
|
| + public static void AssertPropertyEquals(
|
| + VCConfiguration configuration,
|
| + string pageName,
|
| + string propertyName,
|
| + string expectedValue,
|
| + bool ignoreCase)
|
| + {
|
| + IVCRulePropertyStorage rule = configuration.Rules.Item(pageName);
|
| + string callInfo = string.Format(
|
| + "Page: {0}, Property: {1}, Configuration: {2}",
|
| + pageName,
|
| + propertyName,
|
| + configuration.ConfigurationName);
|
| +
|
| + Assert.AreEqual(
|
| + expectedValue,
|
| + rule.GetUnevaluatedPropertyValue(propertyName),
|
| + ignoreCase,
|
| + callInfo);
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Tests that a given property contains a specific string in a certain VCConfiguration
|
| + /// </summary>
|
| + /// <param name="configuration">Gives the platform and configuration type</param>
|
| + /// <param name="pageName">Property page name where property resides.</param>
|
| + /// <param name="propertyName">Name of the property to check.</param>
|
| + /// <param name="expectedValue">Expected string to contain.</param>
|
| + /// <param name="ignoreCase">Ignore case when comparing the expected and actual values.</param>
|
| + public static void AssertPropertyContains(
|
| + VCConfiguration configuration,
|
| + string pageName,
|
| + string propertyName,
|
| + string expectedValue,
|
| + bool ignoreCase)
|
| + {
|
| + StringComparison caseSensitive = ignoreCase ?
|
| + StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
|
| +
|
| + IVCRulePropertyStorage rule = configuration.Rules.Item(pageName);
|
| + string propertyValue = rule.GetUnevaluatedPropertyValue(propertyName);
|
| +
|
| + string message = string.Format(
|
| + "{0} should be contained in {1}. Page: {2}, Property: {3}, Configuration: {4}",
|
| + expectedValue,
|
| + propertyValue,
|
| + pageName,
|
| + propertyName,
|
| + configuration.ConfigurationName);
|
| +
|
| + Assert.IsTrue(propertyValue.Contains(expectedValue, caseSensitive), message);
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Tests that a given property is not null or empty.
|
| + /// </summary>
|
| + /// <param name="configuration">Gives the platform and configuration type</param>
|
| + /// <param name="pageName">Property page name where property resides.</param>
|
| + /// <param name="propertyName">Name of the property to check.</param>
|
| + public static void AssertPropertyIsNotNullOrEmpty(
|
| + VCConfiguration configuration,
|
| + string pageName,
|
| + string propertyName)
|
| + {
|
| + IVCRulePropertyStorage rule = configuration.Rules.Item(pageName);
|
| + string propertyValue = rule.GetUnevaluatedPropertyValue(propertyName);
|
| +
|
| + string message = string.Format(
|
| + "{0} was null or empty. Page: {1}, Configuration: {2}",
|
| + propertyName,
|
| + pageName,
|
| + configuration.ConfigurationName);
|
| +
|
| + Assert.IsFalse(string.IsNullOrEmpty(propertyValue), message);
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Ensures that the add-in is configured to load on start. If it isn't then some tests may
|
| + /// unexpectedly fail, this check helps catch that problem early.
|
| + /// </summary>
|
| + /// <param name="dte">The main Visual Studio interface.</param>
|
| + /// <param name="addInName">The name of the add-in to check if loaded.</param>
|
| + public static void AssertAddinLoaded(DTE2 dte, string addInName)
|
| + {
|
| + bool found = false;
|
| + foreach (AddIn addin in dte.AddIns)
|
| + {
|
| + if (addin.Connected && addInName.Equals(addin.Name))
|
| + {
|
| + found = true;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + Assert.IsTrue(found, "Add-in is not configured to load on start.");
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Will retry the given statement up to maxRetry times while pausing between each try for
|
| + /// the given interval.
|
| + /// </summary>
|
| + /// <param name="test">Generic boolean statement.</param>
|
| + /// <param name="interval">Amount of time to wait between each retry.</param>
|
| + /// <param name="maxRetry">Maximum number of retries.</param>
|
| + /// <param name="message">Message to print on failure.</param>
|
| + public static void AssertTrueWithTimeout(
|
| + RetryStatement test, TimeSpan interval, int maxRetry, string message)
|
| + {
|
| + for (int tryCount = 0; tryCount <= maxRetry; tryCount++)
|
| + {
|
| + if (test.Invoke())
|
| + {
|
| + return;
|
| + }
|
| +
|
| + System.Threading.Thread.Sleep(interval);
|
| + }
|
| +
|
| + throw new Exception(string.Format("Statement timed out. {0}", message));
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Extends the string class to allow checking if a string contains another string
|
| + /// allowing a comparison type (such as case-insensitivity).
|
| + /// </summary>
|
| + /// <param name="source">Base string to search.</param>
|
| + /// <param name="toCheck">String to check if contained within base string.</param>
|
| + /// <param name="comparison">Comparison type.</param>
|
| + /// <returns>True if toCheck is contained in source.</returns>
|
| + public static bool Contains(this string source, string toCheck, StringComparison comparison)
|
| + {
|
| + return source.IndexOf(toCheck, comparison) != -1;
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Copies the entire contents of a directory and sub directories.
|
| + /// </summary>
|
| + /// <param name="source">Directory to copy from.</param>
|
| + /// <param name="dest">Directory to copy to.</param>
|
| + public static void CopyDirectory(string source, string dest)
|
| + {
|
| + DirectoryInfo dir = new DirectoryInfo(source);
|
| +
|
| + if (!dir.Exists)
|
| + {
|
| + throw new DirectoryNotFoundException(source);
|
| + }
|
| +
|
| + if (!Directory.Exists(dest))
|
| + {
|
| + Directory.CreateDirectory(dest);
|
| + }
|
| +
|
| + FileInfo[] files = dir.GetFiles();
|
| + foreach (FileInfo file in files)
|
| + {
|
| + string path = Path.Combine(dest, file.Name);
|
| + file.CopyTo(path, false);
|
| + }
|
| +
|
| + foreach (DirectoryInfo subdir in dir.GetDirectories())
|
| + {
|
| + string path = Path.Combine(dest, subdir.Name);
|
| + CopyDirectory(subdir.FullName, path);
|
| + }
|
| + }
|
| + }
|
| +}
|
|
|