diff --git a/Nuget.config b/Nuget.config index 57644a2b47..c9e46028f9 100644 --- a/Nuget.config +++ b/Nuget.config @@ -7,7 +7,7 @@ - + diff --git a/TestFx.sln b/TestFx.sln index b3650f547f..efe419e3a9 100644 --- a/TestFx.sln +++ b/TestFx.sln @@ -182,10 +182,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataRowTestProject", "test\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TimeoutTestProject", "test\E2ETests\TestAssets\TimeoutTestProject\TimeoutTestProject.csproj", "{4F0B2ACF-1341-42AF-918C-669A6D5CEA2B}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeploymentTestProjectNetCore", "test\E2ETests\TestAssets\DeploymentTestProjectNetCore\DeploymentTestProjectNetCore.csproj", "{26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\TestFramework\Extension.Shared\Extension.Shared.projitems*{272ca5e1-8e81-4825-9e47-86cce02f700d}*SharedItemsImports = 13 - src\TestFramework\Extension.Shared\Extension.Shared.projitems*{6c9fe494-8315-4667-b3f6-75dc62a62319}*SharedItemsImports = 4 src\TestFramework\Extension.Shared\Extension.Shared.projitems*{df131865-84ee-4540-8112-e88acebdea09}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1091,6 +1092,30 @@ Global {4F0B2ACF-1341-42AF-918C-669A6D5CEA2B}.Release|x64.Build.0 = Release|Any CPU {4F0B2ACF-1341-42AF-918C-669A6D5CEA2B}.Release|x86.ActiveCfg = Release|Any CPU {4F0B2ACF-1341-42AF-918C-669A6D5CEA2B}.Release|x86.Build.0 = Release|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Code Analysis Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Code Analysis Debug|Any CPU.Build.0 = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Code Analysis Debug|ARM.ActiveCfg = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Code Analysis Debug|ARM.Build.0 = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Code Analysis Debug|x64.ActiveCfg = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Code Analysis Debug|x64.Build.0 = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Code Analysis Debug|x86.ActiveCfg = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Code Analysis Debug|x86.Build.0 = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Debug|ARM.ActiveCfg = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Debug|ARM.Build.0 = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Debug|x64.ActiveCfg = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Debug|x64.Build.0 = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Debug|x86.ActiveCfg = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Debug|x86.Build.0 = Debug|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Release|Any CPU.Build.0 = Release|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Release|ARM.ActiveCfg = Release|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Release|ARM.Build.0 = Release|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Release|x64.ActiveCfg = Release|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Release|x64.Build.0 = Release|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Release|x86.ActiveCfg = Release|Any CPU + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1152,6 +1177,7 @@ Global {0B057B99-DCDD-417A-BC19-3E63DDD86F24} = {1899187D-8B9C-40C2-9F04-9E9A76C9A919} {7FB80AAB-7123-4416-B6CD-8D3D69AA83F1} = {D53BD452-F69F-4FB3-8B98-386EDA28A4C8} {4F0B2ACF-1341-42AF-918C-669A6D5CEA2B} = {D53BD452-F69F-4FB3-8B98-386EDA28A4C8} + {26F0B8EF-92D4-4A23-ACB4-D1B662F0EEBE} = {D53BD452-F69F-4FB3-8B98-386EDA28A4C8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {31E0F4D5-975A-41CC-933E-545B2201FAF9} diff --git a/scripts/build/TestFx.Loc.targets b/scripts/build/TestFx.Loc.targets index 00f80d1036..bd2481f37d 100644 --- a/scripts/build/TestFx.Loc.targets +++ b/scripts/build/TestFx.Loc.targets @@ -9,6 +9,7 @@ $(ProjectDir)Resources + $(ProjectDir)..\PlatformServices.Shared\netstandard1.3\Resources @@ -20,11 +21,14 @@ - + - + + + @@ -33,6 +37,16 @@ + + + + + + + + + + @@ -42,6 +56,17 @@ + + + + + + + + + + + diff --git a/scripts/build/stylecop.ruleset b/scripts/build/stylecop.ruleset index 3d7b8ef6a5..467b822851 100644 --- a/scripts/build/stylecop.ruleset +++ b/scripts/build/stylecop.ruleset @@ -1,4 +1,4 @@ - + @@ -6,6 +6,7 @@ + diff --git a/scripts/build/stylecop.test.ruleset b/scripts/build/stylecop.test.ruleset index c409cd73f9..91f196256f 100644 --- a/scripts/build/stylecop.test.ruleset +++ b/scripts/build/stylecop.test.ruleset @@ -1,4 +1,4 @@ - + @@ -12,5 +12,6 @@ + - + \ No newline at end of file diff --git a/src/Adapter/PlatformServices.Desktop/Deployment/TestRunDirectories.cs b/src/Adapter/PlatformServices.Desktop/Deployment/DesktopTestRunDirectories.cs similarity index 94% rename from src/Adapter/PlatformServices.Desktop/Deployment/TestRunDirectories.cs rename to src/Adapter/PlatformServices.Desktop/Deployment/DesktopTestRunDirectories.cs index 1643fc8527..69d217aae1 100644 --- a/src/Adapter/PlatformServices.Desktop/Deployment/TestRunDirectories.cs +++ b/src/Adapter/PlatformServices.Desktop/Deployment/DesktopTestRunDirectories.cs @@ -11,7 +11,9 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Dep /// The test run directories. /// [Serializable] +#pragma warning disable SA1649 // File name must match first type name public class TestRunDirectories +#pragma warning restore SA1649 // File name must match first type name { /// /// The default deployment root directory. We do not want to localize it. diff --git a/src/Adapter/PlatformServices.Desktop/PlatformServices.Desktop.csproj b/src/Adapter/PlatformServices.Desktop/PlatformServices.Desktop.csproj index 4496d6a4b8..4d2d5cce3e 100644 --- a/src/Adapter/PlatformServices.Desktop/PlatformServices.Desktop.csproj +++ b/src/Adapter/PlatformServices.Desktop/PlatformServices.Desktop.csproj @@ -11,6 +11,7 @@ Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices v4.5 + true true @@ -44,6 +45,45 @@ + + ns10RecursiveDirectoryPath.cs + + + Services\ns10MSTestSettingsProvider.cs + + + Services\ns10TestContextPropertyStrings.cs + + + Utilities\ns10Validate.cs + + + Extensions\ns13ExceptionExtensions.cs + + + Deployment\ns13DeploymentItem.cs + + + Resources\Resource.Designer.cs + True + True + Resource.resx + + + Services\ns13MSTestAdapterSettings.cs + + + Services\ns13TestDeployment.cs + + + Utilities\ns13DeploymentItemUtility.cs + + + Utilities\ns13DeploymentUtilityBase.cs + + + Utilities\ns13FileUtility.cs + @@ -55,19 +95,11 @@ - - - + - - - True - True - Resource.resx - Services\ns13TraceListener.cs @@ -78,23 +110,17 @@ - - - - - - - + + - - + @@ -119,12 +145,14 @@ - + + Resources\Resource.resx ResXFileCodeGenerator Resource.Designer.cs Designer Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices + \ No newline at end of file diff --git a/src/Adapter/PlatformServices.Desktop/Services/DesktopFileOperations.cs b/src/Adapter/PlatformServices.Desktop/Services/DesktopFileOperations.cs index 07a3110c11..e437b850ce 100644 --- a/src/Adapter/PlatformServices.Desktop/Services/DesktopFileOperations.cs +++ b/src/Adapter/PlatformServices.Desktop/Services/DesktopFileOperations.cs @@ -11,8 +11,6 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.ObjectModel; -#pragma warning disable SA1649 // SA1649FileNameMustMatchTypeName - /// /// This service is responsible for any file based operations. /// diff --git a/src/Adapter/PlatformServices.Desktop/Services/DesktopReflectionOperations.cs b/src/Adapter/PlatformServices.Desktop/Services/DesktopReflectionOperations.cs index b8ce5c2ec5..08af6a077e 100644 --- a/src/Adapter/PlatformServices.Desktop/Services/DesktopReflectionOperations.cs +++ b/src/Adapter/PlatformServices.Desktop/Services/DesktopReflectionOperations.cs @@ -9,8 +9,6 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; -#pragma warning disable SA1649 // SA1649FileNameMustMatchTypeName - /// /// This service is responsible for platform specific reflection operations. /// diff --git a/src/Adapter/PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs b/src/Adapter/PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs index a7373ba5b4..dda8ac309d 100644 --- a/src/Adapter/PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs +++ b/src/Adapter/PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs @@ -19,8 +19,6 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel; using UTF = Microsoft.VisualStudio.TestTools.UnitTesting; -#pragma warning disable SA1649 // File name must match first type name - /// /// Internal implementation of TestContext exposed to the user. /// The virtual string properties of the TestContext are retreived from the property dictionary @@ -464,26 +462,4 @@ private void InitializeProperties() this.properties[TestContextPropertyStrings.TestName] = this.testMethod.Name; } } - -#pragma warning restore SA1649 // SA1649FileNameMustMatchTypeName -#pragma warning disable SA1402 // File may only contain a single class - - /// - /// Test Context Property Names. - /// - internal static class TestContextPropertyStrings -#pragma warning restore SA1402 // File may only contain a single class - { - public static readonly string TestRunDirectory = "TestRunDirectory"; - public static readonly string DeploymentDirectory = "DeploymentDirectory"; - public static readonly string ResultsDirectory = "ResultsDirectory"; - public static readonly string TestRunResultsDirectory = "TestRunResultsDirectory"; - public static readonly string TestResultsDirectory = "TestResultsDirectory"; - public static readonly string TestDir = "TestDir"; - public static readonly string TestDeploymentDir = "TestDeploymentDir"; - public static readonly string TestLogsDir = "TestLogsDir"; - - public static readonly string FullyQualifiedTestClassName = "FullyQualifiedTestClassName"; - public static readonly string TestName = "TestName"; - } } diff --git a/src/Adapter/PlatformServices.Desktop/Services/DesktopTestSourceHost.cs b/src/Adapter/PlatformServices.Desktop/Services/DesktopTestSourceHost.cs index 91aa97f6bc..205955f374 100644 --- a/src/Adapter/PlatformServices.Desktop/Services/DesktopTestSourceHost.cs +++ b/src/Adapter/PlatformServices.Desktop/Services/DesktopTestSourceHost.cs @@ -14,8 +14,6 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; -#pragma warning disable SA1649 // SA1649FileNameMustMatchTypeName - /// /// A host that loads the test source.This can be in isolation for desktop using an AppDomain or just loading the source in the current context. /// diff --git a/src/Adapter/PlatformServices.Desktop/Utilities/AssemblyUtility.cs b/src/Adapter/PlatformServices.Desktop/Utilities/DesktopAssemblyUtility.cs similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Utilities/AssemblyUtility.cs rename to src/Adapter/PlatformServices.Desktop/Utilities/DesktopAssemblyUtility.cs diff --git a/src/Adapter/PlatformServices.Desktop/Utilities/DesktopDeploymentUtility.cs b/src/Adapter/PlatformServices.Desktop/Utilities/DesktopDeploymentUtility.cs new file mode 100644 index 0000000000..593974700b --- /dev/null +++ b/src/Adapter/PlatformServices.Desktop/Utilities/DesktopDeploymentUtility.cs @@ -0,0 +1,253 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Reflection; + using System.Security; + + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; + + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; + + internal class DeploymentUtility : DeploymentUtilityBase + { + public DeploymentUtility() + : base() + { + } + + public DeploymentUtility(DeploymentItemUtility deploymentItemUtility, AssemblyUtility assemblyUtility, FileUtility fileUtility) + : base(deploymentItemUtility, assemblyUtility, fileUtility) + { + } + + public override void AddDeploymentItemsBasedOnMsTestSetting(string testSource, IList deploymentItems, List warnings) + { + if (MSTestSettingsProvider.Settings.DeployTestSourceDependencies) + { + EqtTrace.Info("Adding the references and satellite assemblies to the deploymentitems list"); + + // Get the referenced assemblies. + this.ProcessNewStorage(testSource, deploymentItems, warnings); + + // Get the satellite assemblies + var satelliteItems = this.GetSatellites(deploymentItems, testSource, warnings); + foreach (var satelliteItem in satelliteItems) + { + this.DeploymentItemUtility.AddDeploymentItem(deploymentItems, satelliteItem); + } + } + else + { + EqtTrace.Info("Adding the test source directory to the deploymentitems list"); + this.DeploymentItemUtility.AddDeploymentItem(deploymentItems, new DeploymentItem(Path.GetDirectoryName(testSource))); + } + } + + /// + /// Get root deployment directory + /// + /// The base directory. + /// Root deployment directory. + public override string GetRootDeploymentDirectory(string baseDirectory) + { + string dateTimeSufix = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo); + string directoryName = string.Format(CultureInfo.CurrentCulture, Resource.TestRunName, DeploymentFolderPrefix, Environment.UserName, dateTimeSufix); + directoryName = this.FileUtility.ReplaceInvalidFileNameCharacters(directoryName); + + return this.FileUtility.GetNextIterationDirectoryName(baseDirectory, directoryName); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] + protected void ProcessNewStorage(string testSource, IList deploymentItems, IList warnings) + { + // Add deployment items and process .config files only for storages we have not processed before. + string errorMessage; + if (!this.DeploymentItemUtility.IsValidDeploymentItem(testSource, string.Empty, out errorMessage)) + { + warnings.Add(errorMessage); + return; + } + + this.DeploymentItemUtility.AddDeploymentItem(deploymentItems, new DeploymentItem(testSource, string.Empty, DeploymentItemOriginType.TestStorage)); + + // Deploy .config file if exists, only for assemlbies, i.e. DLL and EXE. + // First check .config, then if not found check for App.Config + // and deploy AppConfig to .config. + if (this.AssemblyUtility.IsAssemblyExtension(Path.GetExtension(testSource))) + { + var configFile = this.AddTestSourceConfigFileIfExists(testSource, deploymentItems); + + // Deal with test dependencies: update dependencyDeploymentItems and missingDependentAssemblies. + try + { + // We look for dependent assemblies only for DLL and EXE's. + this.AddDependencies(testSource, configFile, deploymentItems, warnings); + } + catch (Exception e) + { + string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorFailedToDeployDependencies, testSource, e); + warnings.Add(warning); + } + } + } + + protected override void AddDependenciesOfDeploymentItem(string deploymentItemFile, IList filesToDeploy, IList warnings) + { + var dependencies = new List(); + + this.AddDependencies(deploymentItemFile, null, dependencies, warnings); + + foreach (var dependencyItem in dependencies) + { + Debug.Assert(Path.IsPathRooted(dependencyItem.SourcePath), "Path of the dependency " + dependencyItem.SourcePath + " is not rooted."); + + // Add dependencies to filesToDeploy. + filesToDeploy.Add(dependencyItem.SourcePath); + } + } + + protected IEnumerable GetSatellites(IEnumerable deploymentItems, string testSource, IList warnings) + { + List satellites = new List(); + foreach (DeploymentItem item in deploymentItems) + { + // We do not care about deployment items which are directories because in that case we deploy all files underneath anyway. + string path = null; + try + { + path = this.GetFullPathToDeploymentItemSource(item.SourcePath, testSource); + path = Path.GetFullPath(path); + + if (string.IsNullOrEmpty(path) || !this.AssemblyUtility.IsAssemblyExtension(Path.GetExtension(path)) + || !this.FileUtility.DoesFileExist(path) || !this.AssemblyUtility.IsAssembly(path)) + { + continue; + } + } + catch (ArgumentException ex) + { + EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); + } + catch (SecurityException ex) + { + EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); + } + catch (IOException ex) + { + // This covers PathTooLongException. + EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); + } + catch (NotSupportedException ex) + { + EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); + } + + // Note: now Path operations with itemPath should not result in any exceptions. + // path is already canonicalized. + + // If we cannot access satellite due to security, etc, we report warning. + try + { + string itemDir = Path.GetDirectoryName(path).TrimEnd( + new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); + List itemSatellites = this.AssemblyUtility.GetSatelliteAssemblies(path); + foreach (string satellite in itemSatellites) + { + Debug.Assert(!string.IsNullOrEmpty(satellite), "DeploymentManager.DoDeployment: got empty satellite!"); + Debug.Assert( + satellite.IndexOf(itemDir, StringComparison.OrdinalIgnoreCase) == 0, + "DeploymentManager.DoDeployment: Got satellite that does not start with original item path"); + + string satelliteDir = Path.GetDirectoryName(satellite).TrimEnd( + new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); + + Debug.Assert(!string.IsNullOrEmpty(satelliteDir), "DeploymentManager.DoDeployment: got empty satellite dir!"); + Debug.Assert(satelliteDir.Length > itemDir.Length + 1, "DeploymentManager.DoDeployment: wrong satellite dir lenght!"); + + string localeDir = satelliteDir.Substring(itemDir.Length + 1); + Debug.Assert(!string.IsNullOrEmpty(localeDir), "DeploymentManager.DoDeployment: got empty dir name for satellite dir!"); + + string relativeOutputDir = Path.Combine(item.RelativeOutputDirectory, localeDir); + + // Now finally add the item! + DeploymentItem satelliteItem = new DeploymentItem(satellite, relativeOutputDir, DeploymentItemOriginType.Satellite); + this.DeploymentItemUtility.AddDeploymentItem(satellites, satelliteItem); + } + } + catch (ArgumentException ex) + { + EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); + string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorGettingSatellite, item, ex.GetType(), ex.GetExceptionMessage()); + warnings.Add(warning); + } + catch (SecurityException ex) + { + EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); + string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorGettingSatellite, item, ex.GetType(), ex.GetExceptionMessage()); + warnings.Add(warning); + } + catch (IOException ex) + { + // This covers PathTooLongException. + EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); + string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorGettingSatellite, item, ex.GetType(), ex.GetExceptionMessage()); + warnings.Add(warning); + } + } + + return satellites; + } + + /// + /// Process test storage and add dependant assemblies to dependencyDeploymentItems. + /// + /// The test source. + /// The config file. + /// Deployment items. + /// Warnigns. + private void AddDependencies(string testSource, string configFile, IList deploymentItems, IList warnings) + { + Debug.Assert(!string.IsNullOrEmpty(testSource), "testSource should not be null or empty."); + + // config file can be null. + Debug.Assert(deploymentItems != null, "deploymentItems should not be null."); + Debug.Assert(Path.IsPathRooted(testSource), "path should be rooted."); + + // Note: if this is not an assembly we simply return empty array, also: + // we do recursive search and report missing. + IList warningList; + string[] references = this.AssemblyUtility.GetFullPathToDependentAssemblies(testSource, configFile, out warningList); + if (warningList != null && warningList.Count > 0) + { + warnings = warnings.Concat(warningList).ToList(); + } + + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("DeploymentManager: Source:{0} has following references", testSource); + } + + foreach (string reference in references) + { + DeploymentItem deploymentItem = new DeploymentItem(reference, string.Empty, DeploymentItemOriginType.Dependency); + this.DeploymentItemUtility.AddDeploymentItem(deploymentItems, deploymentItem); + + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("DeploymentManager: Reference:{0} ", reference); + } + } + } + } +} diff --git a/src/Adapter/PlatformServices.Desktop/Utilities/ReflectionUtility.cs b/src/Adapter/PlatformServices.Desktop/Utilities/DesktopReflectionUtility.cs similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Utilities/ReflectionUtility.cs rename to src/Adapter/PlatformServices.Desktop/Utilities/DesktopReflectionUtility.cs diff --git a/src/Adapter/PlatformServices.NetCore/Deployment/NetCoreTestRunDirectories.cs b/src/Adapter/PlatformServices.NetCore/Deployment/NetCoreTestRunDirectories.cs new file mode 100644 index 0000000000..2967db5859 --- /dev/null +++ b/src/Adapter/PlatformServices.NetCore/Deployment/NetCoreTestRunDirectories.cs @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment +{ + using System; + using System.Diagnostics; + using System.IO; + + /// + /// The test run directories. + /// + [Serializable] + public class TestRunDirectories + { + /// + /// The default deployment root directory. We do not want to localize it. + /// + internal const string DefaultDeploymentRootDirectory = "TestResults"; + + /// + /// The deployment in directory suffix. + /// + internal const string DeploymentInDirectorySuffix = "In"; + + public TestRunDirectories(string rootDirectory) + { + Debug.Assert(!string.IsNullOrEmpty(rootDirectory), "rootDirectory"); + + this.RootDeploymentDirectory = rootDirectory; + } + + /// + /// Gets or sets the root deployment directory + /// + public string RootDeploymentDirectory { get; set; } + + /// + /// Gets the In directory + /// + public string InDirectory + { + get + { + return Path.Combine(this.RootDeploymentDirectory, DeploymentInDirectorySuffix); + } + } + + /// + /// Gets the Out directory + /// + public string OutDirectory + { + get + { + return Directory.GetCurrentDirectory(); + } + } + + /// + /// Gets In\MachineName directory + /// + public string InMachineNameDirectory + { + get + { + return Path.Combine(Path.Combine(this.RootDeploymentDirectory, DeploymentInDirectorySuffix), Environment.MachineName); + } + } + } +} diff --git a/src/Adapter/PlatformServices.NetCore/Friends.cs b/src/Adapter/PlatformServices.NetCore/Friends.cs index a1a19f0530..0878c09cbf 100644 --- a/src/Adapter/PlatformServices.NetCore/Friends.cs +++ b/src/Adapter/PlatformServices.NetCore/Friends.cs @@ -5,3 +5,4 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("MSTestAdapter.PlatformServices.NetCore.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] \ No newline at end of file diff --git a/src/Adapter/PlatformServices.NetCore/PlatformServices.NetCore.csproj b/src/Adapter/PlatformServices.NetCore/PlatformServices.NetCore.csproj index 87bde00062..6e8d04964a 100644 --- a/src/Adapter/PlatformServices.NetCore/PlatformServices.NetCore.csproj +++ b/src/Adapter/PlatformServices.NetCore/PlatformServices.NetCore.csproj @@ -10,39 +10,70 @@ netstandard1.5 $(PackageTargetFallback);portable-net45+win8+wpa81+wp8 false + true + false + + + - - - - + + + + + + + + + + + + + + + + Resources\Resource.Designer.cs + True + True + Resource.resx + - + + Resources\Resource.resx + ResXFileCodeGenerator + Resource.Designer.cs + Designer + Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices + + + + + - + - + \ No newline at end of file diff --git a/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs b/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs new file mode 100644 index 0000000000..62aaa28ceb --- /dev/null +++ b/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs @@ -0,0 +1,378 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.IO; + + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel; + + using UTF = Microsoft.VisualStudio.TestTools.UnitTesting; + + /// + /// Internal implementation of TestContext exposed to the user. + /// + /// + /// The virtual string properties of the TestContext are retreived from the property dictionary + /// like GetProperty<string>("TestName") or GetProperty<string>("FullyQualifiedTestClassName"); + /// + public class TestContextImplementation : UTF.TestContext, ITestContext + { + private static readonly string FullyQualifiedTestClassNameLabel = "FullyQualifiedTestClassName"; + private static readonly string TestNameLabel = "TestName"; + + /// + /// List of result files associated with the test + /// + private IList testResultFiles; + + /// + /// Properties + /// + private IDictionary properties; + + /// + /// Unit test outcome + /// + private UTF.UnitTestOutcome outcome; + + /// + /// Test Method + /// + private ITestMethod testMethod; + + private StringWriter stringWriter; + private bool stringWriterDisposed; + + /// + /// Initializes a new instance of the class. + /// + /// The test method. + /// A writer for logging. + /// The properties. + public TestContextImplementation(ITestMethod testMethod, StringWriter writer, IDictionary properties) + { + Debug.Assert(testMethod != null, "TestMethod is not null"); + Debug.Assert(properties != null, "properties is not null"); + + this.testMethod = testMethod; + this.properties = new Dictionary(properties); + this.stringWriter = writer; + this.InitializeProperties(); + this.testResultFiles = new List(); + } + + #region TestContext impl + + // Summary: + // You can use this property in a TestCleanup method to determine the outcome + // of a test that has run. + // + // Returns: + // A Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome that states + // the outcome of a test that has run. + public override UTF.UnitTestOutcome CurrentTestOutcome + { + get + { + return this.outcome; + } + } + + /// + public override string TestRunDirectory + { + get + { + return this.GetStringPropertyValue(TestContextPropertyStrings.TestRunDirectory); + } + } + + /// + public override string DeploymentDirectory + { + get + { + return this.GetStringPropertyValue(TestContextPropertyStrings.DeploymentDirectory); + } + } + + /// + public override string ResultsDirectory + { + get + { + return this.GetStringPropertyValue(TestContextPropertyStrings.ResultsDirectory); + } + } + + /// + public override string TestRunResultsDirectory + { + get + { + return this.GetStringPropertyValue(TestContextPropertyStrings.TestRunResultsDirectory); + } + } + + /// + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", Justification = "TestResultsDirectory is what we need.")] + public override string TestResultsDirectory + { + get + { + // In MSTest, it is actually "In\697105f7-004f-42e8-bccf-eb024870d3e9\User1", but + // we are setting it to "In" only because MSTest does not create this directory. + return this.GetStringPropertyValue(TestContextPropertyStrings.TestResultsDirectory); + } + } + + /// + public override string TestDir + { + get + { + return this.GetStringPropertyValue(TestContextPropertyStrings.TestDir); + } + } + + /// + public override string TestDeploymentDir + { + get + { + return this.GetStringPropertyValue(TestContextPropertyStrings.TestDeploymentDir); + } + } + + /// + public override string TestLogsDir + { + get + { + return this.GetStringPropertyValue(TestContextPropertyStrings.TestLogsDir); + } + } + + /// + /// Gets fully-qualified name of the class containing the test method currently being executed + /// + /// + /// This property can be useful in attributes derived from ExpectedExceptionBaseAttribute. + /// Those attributes have access to the test context, and provide messages that are included + /// in the test results. Users can benefit from messages that include the fully-qualified + /// class name in addition to the name of the test method currently being executed. + /// + public override string FullyQualifiedTestClassName + { + get + { + return this.GetPropertyValue(FullyQualifiedTestClassNameLabel) as string; + } + } + + /// + /// Gets name of the test method currently being executed + /// + public override string TestName + { + get + { + return this.GetPropertyValue(TestNameLabel) as string; + } + } + + /// + /// Gets the test properties when overridden in a derived class. + /// + /// + /// An System.Collections.IDictionary object that contains key/value pairs that + /// represent the test properties. + /// + public override IDictionary Properties + { + get + { + return this.properties as IDictionary; + } + } + + public UTF.TestContext Context + { + get + { + return this as UTF.TestContext; + } + } + + /// + /// Set the unit-test outcome + /// + /// The test outcome. + public void SetOutcome(UTF.UnitTestOutcome outcome) + { + this.outcome = outcome; + } + + /// + /// Returns whether property with parameter name is present or not + /// + /// The property name. + /// Property value. + /// True if property with parameter name is present. + public bool TryGetPropertyValue(string propertyName, out object propertyValue) + { + if (this.properties == null) + { + propertyValue = null; + return false; + } + + return this.properties.TryGetValue(propertyName, out propertyValue); + } + + /// + /// Adds the parameter name/value pair to property bag + /// + /// The property name. + /// Property value. + public void AddProperty(string propertyName, string propertyValue) + { + if (this.properties == null) + { + this.properties = new Dictionary(); + } + + this.properties.Add(propertyName, propertyValue); + } + + /// + /// Returning null as this feature is not supported in ASP .net and UWP + /// + /// List of result files. Null presently. + public IList GetResultFiles() + { + return null; + } + + /// + /// When overridden in a derived class, used to write trace messages while the + /// test is running. + /// + /// The formatted string that contains the trace message. + public override void WriteLine(string message) + { + if (this.stringWriterDisposed) + { + return; + } + + try + { + var msg = message?.Replace("\0", "\\0"); + this.stringWriter.WriteLine(msg); + } + catch (ObjectDisposedException) + { + this.stringWriterDisposed = true; + } + } + + /// + /// When overridden in a derived class, used to write trace messages while the + /// test is running. + /// + /// The string that contains the trace message. + /// Arguments to add to the trace message. + public override void WriteLine(string format, params object[] args) + { + if (this.stringWriterDisposed) + { + return; + } + + try + { + string message = string.Format(CultureInfo.CurrentCulture, format?.Replace("\0", "\\0"), args); + this.stringWriter.WriteLine(message); + } + catch (ObjectDisposedException) + { + this.stringWriterDisposed = true; + } + } + + /// + /// Gets messages from the testContext writeLines + /// + /// The test context messages added so far. + public string GetDiagnosticMessages() + { + return this.stringWriter.ToString(); + } + + /// + /// Clears the previous testContext writeline messages. + /// + public void ClearDiagnosticMessages() + { + var sb = this.stringWriter.GetStringBuilder(); + sb.Remove(0, sb.Length); + } + + public void SetDataRow(object dataRow) + { + // Do nothing. + } + + public void SetDataConnection(object dbConnection) + { + // Do nothing. + } + + #endregion + + /// + /// Helper to safely fetch a property value. + /// + /// Property Name + /// Property value + private object GetPropertyValue(string propertyName) + { + object propertyValue = null; + this.properties.TryGetValue(propertyName, out propertyValue); + + return propertyValue; + } + + /// + /// Helper to safely fetch a property value. + /// + /// Property Name + /// Property value + private string GetStringPropertyValue(string propertyName) + { + object propertyValue = null; + this.properties.TryGetValue(propertyName, out propertyValue); + return propertyValue as string; + } + + /// + /// Helper to initialize the properties. + /// + private void InitializeProperties() + { + this.properties[FullyQualifiedTestClassNameLabel] = this.testMethod.FullClassName; + this.properties[TestNameLabel] = this.testMethod.Name; + } + } + +#pragma warning restore SA1649 // SA1649FileNameMustMatchTypeName +} diff --git a/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestSourceHost.cs b/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestSourceHost.cs new file mode 100644 index 0000000000..bde6958a33 --- /dev/null +++ b/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestSourceHost.cs @@ -0,0 +1,122 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices +{ + using System; + using System.IO; + + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; + + /// + /// A host that loads the test source + /// + public class TestSourceHost : ITestSourceHost + { + private string sourceFileName; + private string currentDirectory = null; + + /// + /// Initializes a new instance of the class. + /// + /// The source file name. + /// The run-settings provided for this session. + /// The handle to the test platform. + public TestSourceHost(string sourceFileName, IRunSettings runSettings, IFrameworkHandle frameworkHandle) + { + this.sourceFileName = sourceFileName; + + // Set the environment context. + this.SetContext(sourceFileName); + } + + /// + /// Setup the isolation host. + /// + public void SetupHost() + { + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + this.ResetContext(); + } + + /// + /// Creates an instance of a given type in the test source host. + /// + /// The type that needs to be created in the host. + /// The arguments to pass to the constructor. + /// This array of arguments must match in number, order, and type the parameters of the constructor to invoke. + /// Pass in null for a constructor with no arguments. + /// + /// An instance of the type created in the host. + /// . + /// + public object CreateInstanceForType(Type type, object[] args) + { + return Activator.CreateInstance(type, args); + } + + /// + /// Updates child-domain's appbase to point to test source location + /// + public void UpdateAppBaseToTestSourceLocation() + { + // Do nothing. + } + + /// + /// Sets context required for running tests. + /// + /// + /// source parameter used for setting context + /// + private void SetContext(string source) + { + if (string.IsNullOrEmpty(source)) + { + return; + } + + Exception setWorkingDirectoryException = null; + this.currentDirectory = Directory.GetCurrentDirectory(); + try + { + Directory.SetCurrentDirectory(Path.GetDirectoryName(source)); + } + catch (IOException ex) + { + setWorkingDirectoryException = ex; + } + catch (System.Security.SecurityException ex) + { + setWorkingDirectoryException = ex; + } + + if (setWorkingDirectoryException != null) + { + EqtTrace.Error("MSTestExecutor.SetWorkingDirectory: Failed to set the working directory to '{0}'. {1}", Path.GetDirectoryName(source), setWorkingDirectoryException); + } + } + + /// + /// Resets the context as it was before calling SetContext() + /// + private void ResetContext() + { + if (!string.IsNullOrEmpty(this.currentDirectory)) + { + Directory.SetCurrentDirectory(this.currentDirectory); + } + } + } + +#pragma warning restore SA1649 // SA1649FileNameMustMatchTypeName +} diff --git a/src/Adapter/PlatformServices.NetCore/Utilities/NetCoreAssemblyUtility.cs b/src/Adapter/PlatformServices.NetCore/Utilities/NetCoreAssemblyUtility.cs new file mode 100644 index 0000000000..923d005162 --- /dev/null +++ b/src/Adapter/PlatformServices.NetCore/Utilities/NetCoreAssemblyUtility.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Globalization; + using System.IO; + using System.Reflection; + + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + + /// + /// Utility for assembly specific functionality. + /// + internal class AssemblyUtility + { + private readonly string[] assemblyExtensions = new string[] { ".dll", ".exe" }; + + /// + /// Whether file extension is an assembly file extension. + /// Returns true for .exe and .dll, otherwise false. + /// + /// Extension containing leading dot, e.g. ".exe". + /// Path.GetExtension() returns extension with leading dot. + /// True if this is an assembly extension. + internal bool IsAssemblyExtension(string extensionWithLeadingDot) + { + foreach (var realExtension in this.assemblyExtensions) + { + if (string.Equals(extensionWithLeadingDot, realExtension, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } + } +} diff --git a/src/Adapter/PlatformServices.NetCore/Utilities/NetCoreDeploymentUtility.cs b/src/Adapter/PlatformServices.NetCore/Utilities/NetCoreDeploymentUtility.cs new file mode 100644 index 0000000000..073eadf299 --- /dev/null +++ b/src/Adapter/PlatformServices.NetCore/Utilities/NetCoreDeploymentUtility.cs @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Reflection; + using System.Security; + + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; + + internal class DeploymentUtility : DeploymentUtilityBase + { + public DeploymentUtility() + : base() + { + } + + public DeploymentUtility(DeploymentItemUtility deploymentItemUtility, AssemblyUtility assemblyUtility, FileUtility fileUtility) + : base(deploymentItemUtility, assemblyUtility, fileUtility) + { + } + + /// + /// add deployment items based on MSTestSettingsProvider.Settings.DeployTestSourceDependencies. This property is ignored in net core. + /// + /// The test source. + /// Deployment Items. + /// Warnings. + public override void AddDeploymentItemsBasedOnMsTestSetting(string testSource, IList deploymentItems, List warnings) + { + // It should add items from bin\debug but since deployment items in netcore are run from bin\debug only, so no need to implement it + } + + /// + /// Get root deployment directory + /// + /// The base directory. + /// Root deployment directory. + public override string GetRootDeploymentDirectory(string baseDirectory) + { + string dateTimeSufix = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo); + string directoryName = string.Format(CultureInfo.CurrentCulture, Resource.TestRunName, DeploymentFolderPrefix, Environment.GetEnvironmentVariable("USERNAME") ?? Environment.GetEnvironmentVariable("USER"), dateTimeSufix); + directoryName = this.FileUtility.ReplaceInvalidFileNameCharacters(directoryName); + + return this.FileUtility.GetNextIterationDirectoryName(baseDirectory, directoryName); + } + + /// + /// Find dependencies of test deployment items + /// + /// Deployment Item File + /// Files to Deploy + /// Warnings + protected override void AddDependenciesOfDeploymentItem(string deploymentItemFile, IList filesToDeploy, IList warnings) + { + // Its implemented only in full framework project as dependent files are not fetched in netcore. + } + } +} diff --git a/src/Adapter/PlatformServices.NetCore/Utilities/NetCoreReflectionUtility.cs b/src/Adapter/PlatformServices.NetCore/Utilities/NetCoreReflectionUtility.cs new file mode 100644 index 0000000000..ad5255660a --- /dev/null +++ b/src/Adapter/PlatformServices.NetCore/Utilities/NetCoreReflectionUtility.cs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Diagnostics; + using System.IO; + using System.Linq; + using System.Reflection; + + /// + /// Utility for reflection API's + /// + internal class ReflectionUtility + { + internal virtual object[] GetCustomAttributes(MemberInfo attributeProvider, Type type) + { + return this.GetCustomAttributes(attributeProvider, type, true); + } + + /// + /// Gets all the custom attributes adorned on a member. + /// + /// The member. + /// True to inspect the ancestors of element; otherwise, false. + /// The list of attributes on the member. Empty list if none found. + internal object[] GetCustomAttributes(MemberInfo memberInfo, bool inherit) + { + return this.GetCustomAttributes(memberInfo, type: null, inherit: inherit); + } + + internal object[] GetCustomAttributes(MemberInfo memberInfo, Type type, bool inherit) + { + if (memberInfo == null) + { + return null; + } + + if (type == null) + { + return memberInfo.GetCustomAttributes(inherit).ToArray(); + } + else + { + return memberInfo.GetCustomAttributes(type, inherit).ToArray(); + } + } + } +} diff --git a/src/Adapter/PlatformServices.Portable/PlatformServices.Portable.csproj b/src/Adapter/PlatformServices.Portable/PlatformServices.Portable.csproj index 4f75ec8f54..9e1e3c98f7 100644 --- a/src/Adapter/PlatformServices.Portable/PlatformServices.Portable.csproj +++ b/src/Adapter/PlatformServices.Portable/PlatformServices.Portable.csproj @@ -40,11 +40,11 @@ SerializableAttribute.cs + + Services\ns10DiaSessionOperations.cs + Services\ns10FileOperations.cs - - - Services\ns10DiaSessionOperations.cs Services\ns10ReflectionOperations.cs diff --git a/src/Adapter/PlatformServices.Shared/netstandard1.0/Constants.cs b/src/Adapter/PlatformServices.Shared/netstandard1.0/Constants.cs index b7c31b98b9..0f69f4fd48 100644 --- a/src/Adapter/PlatformServices.Shared/netstandard1.0/Constants.cs +++ b/src/Adapter/PlatformServices.Shared/netstandard1.0/Constants.cs @@ -3,13 +3,20 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices { + using System.Collections.Generic; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + #pragma warning disable SA1649 // SA1649FileNameMustMatchTypeName internal class Constants { + public static readonly TestProperty DeploymentItemsProperty = TestProperty.Register("MSTestDiscoverer.DeploymentItems", DeploymentItemsLabel, typeof(KeyValuePair[]), TestPropertyAttributes.Hidden, typeof(TestCase)); + internal const string DllExtension = ".dll"; internal const string ExeExtension = ".exe"; internal const string AppxPackageExtension = ".appx"; + + private const string DeploymentItemsLabel = "DeploymentItems"; } #pragma warning restore SA1649 // SA1649FileNameMustMatchTypeName diff --git a/src/Adapter/PlatformServices.Desktop/Services/MSTestSettingsProvider.cs b/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10MSTestSettingsProvider.cs similarity index 99% rename from src/Adapter/PlatformServices.Desktop/Services/MSTestSettingsProvider.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10MSTestSettingsProvider.cs index e35849e700..54dbc51203 100644 --- a/src/Adapter/PlatformServices.Desktop/Services/MSTestSettingsProvider.cs +++ b/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10MSTestSettingsProvider.cs @@ -6,7 +6,6 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices using System.Collections.Generic; using System.Xml; using Microsoft.VisualStudio.TestPlatform.ObjectModel; - using ISettingsProvider = Interface.ISettingsProvider; /// diff --git a/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextPropertyStrings.cs b/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextPropertyStrings.cs new file mode 100644 index 0000000000..1a17f1759a --- /dev/null +++ b/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextPropertyStrings.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices +{ + /// + /// Test Context Property Names. + /// + internal static class TestContextPropertyStrings + { + public static readonly string TestRunDirectory = "TestRunDirectory"; + public static readonly string DeploymentDirectory = "DeploymentDirectory"; + public static readonly string ResultsDirectory = "ResultsDirectory"; + public static readonly string TestRunResultsDirectory = "TestRunResultsDirectory"; + public static readonly string TestResultsDirectory = "TestResultsDirectory"; + public static readonly string TestDir = "TestDir"; + public static readonly string TestDeploymentDir = "TestDeploymentDir"; + public static readonly string TestLogsDir = "TestLogsDir"; + + public static readonly string FullyQualifiedTestClassName = "FullyQualifiedTestClassName"; + public static readonly string TestName = "TestName"; + } +} diff --git a/src/Adapter/PlatformServices.Desktop/Utilities/Validate.cs b/src/Adapter/PlatformServices.Shared/netstandard1.0/Utilities/ns10Validate.cs similarity index 94% rename from src/Adapter/PlatformServices.Desktop/Utilities/Validate.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.0/Utilities/ns10Validate.cs index c7602e7f1f..b6d29d2749 100644 --- a/src/Adapter/PlatformServices.Desktop/Utilities/Validate.cs +++ b/src/Adapter/PlatformServices.Shared/netstandard1.0/Utilities/ns10Validate.cs @@ -5,6 +5,8 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Uti { using System; + #pragma warning disable SA1649 // File name must match first type name + internal class Validate { /// diff --git a/src/Adapter/PlatformServices.Desktop/RecursiveDirectoryPath.cs b/src/Adapter/PlatformServices.Shared/netstandard1.0/ns10RecursiveDirectoryPath.cs similarity index 81% rename from src/Adapter/PlatformServices.Desktop/RecursiveDirectoryPath.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.0/ns10RecursiveDirectoryPath.cs index 0046980b87..1671dcec8f 100644 --- a/src/Adapter/PlatformServices.Desktop/RecursiveDirectoryPath.cs +++ b/src/Adapter/PlatformServices.Shared/netstandard1.0/ns10RecursiveDirectoryPath.cs @@ -5,6 +5,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices { using System; using System.Diagnostics.CodeAnalysis; + using System.Security; /// /// Mstest settings in runsettings look like this @@ -20,6 +21,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices /// [Serializable] [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1603:DocumentationMustContainValidXml", Justification = "Reviewed. Suppression is OK here.")] +#pragma warning disable SA1649 // File name must match first type name public class RecursiveDirectoryPath : MarshalByRefObject { /// @@ -44,5 +46,17 @@ public RecursiveDirectoryPath(string dirPath, bool includeSubDirectories) /// Gets a value indicating whether to include sub directories. /// public bool IncludeSubDirectories { get; private set; } + + /// + /// Returns object to be used for controlling lifetime, null means infinite lifetime. + /// + /// + /// The . + /// + [SecurityCritical] + public override object InitializeLifetimeService() + { + return null; + } } } diff --git a/src/Adapter/PlatformServices.Desktop/Extensions/ExceptionExtensions.cs b/src/Adapter/PlatformServices.Shared/netstandard1.3/Extensions/ns13ExceptionExtensions.cs similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Extensions/ExceptionExtensions.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Extensions/ns13ExceptionExtensions.cs diff --git a/src/Adapter/PlatformServices.Desktop/Resources/Resource.Designer.cs b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/Resource.Designer.cs similarity index 98% rename from src/Adapter/PlatformServices.Desktop/Resources/Resource.Designer.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/Resource.Designer.cs index d02be0ed02..faa1361b99 100644 --- a/src/Adapter/PlatformServices.Desktop/Resources/Resource.Designer.cs +++ b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/Resource.Designer.cs @@ -10,8 +10,9 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices { using System; - - + using System.Reflection; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,7 +20,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resource { @@ -40,7 +41,7 @@ internal Resource() { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Resources.Reso" + - "urce", typeof(Resource).Assembly); + "urce", typeof(Resource).GetTypeInfo().Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Adapter/PlatformServices.Desktop/Resources/Resource.resx b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/Resource.resx similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/Resource.resx rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/Resource.resx diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.cs.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.cs.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.cs.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.cs.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.de.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.de.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.de.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.de.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.es.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.es.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.es.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.es.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.fr.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.fr.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.fr.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.fr.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.it.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.it.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.it.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.it.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.ja.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.ja.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.ja.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.ja.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.ko.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.ko.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.ko.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.ko.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.pl.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.pl.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.pl.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.pl.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.pt-BR.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.pt-BR.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.pt-BR.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.pt-BR.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.ru.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.ru.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.ru.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.ru.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.tr.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.tr.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.tr.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.tr.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.zh-Hans.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.zh-Hans.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.zh-Hans.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.zh-Hans.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.zh-Hant.xlf b/src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.zh-Hant.xlf similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Resources/xlf/Resource.zh-Hant.xlf rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Resources/xlf/Resource.zh-Hant.xlf diff --git a/src/Adapter/PlatformServices.Desktop/Services/MSTestAdapterSettings.cs b/src/Adapter/PlatformServices.Shared/netstandard1.3/Services/ns13MSTestAdapterSettings.cs similarity index 99% rename from src/Adapter/PlatformServices.Desktop/Services/MSTestAdapterSettings.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Services/ns13MSTestAdapterSettings.cs index 77977c7a36..a622a4dcb7 100644 --- a/src/Adapter/PlatformServices.Desktop/Services/MSTestAdapterSettings.cs +++ b/src/Adapter/PlatformServices.Shared/netstandard1.3/Services/ns13MSTestAdapterSettings.cs @@ -8,6 +8,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices using System.Globalization; using System.IO; using System.Xml; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; diff --git a/src/Adapter/PlatformServices.Desktop/Services/DesktopTestDeployment.cs b/src/Adapter/PlatformServices.Shared/netstandard1.3/Services/ns13TestDeployment.cs similarity index 96% rename from src/Adapter/PlatformServices.Desktop/Services/DesktopTestDeployment.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Services/ns13TestDeployment.cs index 85aa229103..d3dcbb3c3d 100644 --- a/src/Adapter/PlatformServices.Desktop/Services/DesktopTestDeployment.cs +++ b/src/Adapter/PlatformServices.Shared/netstandard1.3/Services/ns13TestDeployment.cs @@ -17,8 +17,6 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; -#pragma warning disable SA1649 // SA1649FileNameMustMatchTypeName - /// /// The test deployment. /// @@ -140,12 +138,15 @@ public bool Deploy(IEnumerable tests, IRunContext runContext, IFramewo return false; } + // Object model currently does not have support for SuspendCodeCoverage. We can remove this once support is added +#if !NETSTANDARD1_5 using (new SuspendCodeCoverage()) +#endif { // Group the tests by source var testsBySource = from test in tests - group test by test.Source into testGroup - select new { Source = testGroup.Key, Tests = testGroup }; + group test by test.Source into testGroup + select new { Source = testGroup.Key, Tests = testGroup }; var runDirectories = RunDirectories; foreach (var group in testsBySource) diff --git a/src/Adapter/PlatformServices.Desktop/Utilities/DeploymentItemUtility.cs b/src/Adapter/PlatformServices.Shared/netstandard1.3/Utilities/ns13DeploymentItemUtility.cs similarity index 99% rename from src/Adapter/PlatformServices.Desktop/Utilities/DeploymentItemUtility.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Utilities/ns13DeploymentItemUtility.cs index aee1ec0dde..ad06769007 100644 --- a/src/Adapter/PlatformServices.Desktop/Utilities/DeploymentItemUtility.cs +++ b/src/Adapter/PlatformServices.Shared/netstandard1.3/Utilities/ns13DeploymentItemUtility.cs @@ -10,7 +10,6 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Uti using System.IO; using System.Linq; using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/PlatformServices.Desktop/Utilities/DeploymentUtility.cs b/src/Adapter/PlatformServices.Shared/netstandard1.3/Utilities/ns13DeploymentUtilityBase.cs similarity index 57% rename from src/Adapter/PlatformServices.Desktop/Utilities/DeploymentUtility.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Utilities/ns13DeploymentUtilityBase.cs index c5338cc829..006d44bfe4 100644 --- a/src/Adapter/PlatformServices.Desktop/Utilities/DeploymentUtility.cs +++ b/src/Adapter/PlatformServices.Shared/netstandard1.3/Utilities/ns13DeploymentUtilityBase.cs @@ -14,39 +14,42 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Uti using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; - internal class DeploymentUtility + internal abstract class DeploymentUtilityBase { - private const string TestAssemblyConfigFileExtension = ".config"; - private const string NetAppConfigFile = "App.Config"; + protected const string TestAssemblyConfigFileExtension = ".config"; + protected const string NetAppConfigFile = "App.Config"; /// /// Prefix for deployment folder to avoid confusions with other folders (like trx attachments). /// - private const string DeploymentFolderPrefix = "Deploy"; - - private DeploymentItemUtility deploymentItemUtility; - private FileUtility fileUtility; - private AssemblyUtility assemblyUtility; + protected const string DeploymentFolderPrefix = "Deploy"; - public DeploymentUtility() + public DeploymentUtilityBase() : this(new DeploymentItemUtility(new ReflectionUtility()), new AssemblyUtility(), new FileUtility()) { } - public DeploymentUtility(DeploymentItemUtility deploymentItemUtility, AssemblyUtility assemblyUtility, FileUtility fileUtility) + public DeploymentUtilityBase(DeploymentItemUtility deploymentItemUtility, AssemblyUtility assemblyUtility, FileUtility fileUtility) { - this.deploymentItemUtility = deploymentItemUtility; - this.assemblyUtility = assemblyUtility; - this.fileUtility = fileUtility; + this.DeploymentItemUtility = deploymentItemUtility; + this.AssemblyUtility = assemblyUtility; + this.FileUtility = fileUtility; } + protected FileUtility FileUtility { get; set; } + + protected DeploymentItemUtility DeploymentItemUtility { get; set; } + + protected AssemblyUtility AssemblyUtility { get; set; } + public bool Deploy(IEnumerable tests, string source, IRunContext runContext, ITestExecutionRecorder testExecutionRecorder, TestRunDirectories runDirectories) { - IList deploymentItems = this.deploymentItemUtility.GetDeploymentItems(tests); + IList deploymentItems = this.DeploymentItemUtility.GetDeploymentItems(tests); // we just deploy source if there are no deployment items for current source but there are deployment items for other sources return this.Deploy(source, runContext, testExecutionRecorder, deploymentItems, runDirectories); @@ -67,75 +70,67 @@ public TestRunDirectories CreateDeploymentDirectories(IRunContext runContext) var outDirectory = result.OutDirectory; var inMachineDirectory = result.InMachineNameDirectory; - this.fileUtility.CreateDirectoryIfNotExists(rootDeploymentDirectory); - this.fileUtility.CreateDirectoryIfNotExists(inDirectory); - this.fileUtility.CreateDirectoryIfNotExists(outDirectory); - this.fileUtility.CreateDirectoryIfNotExists(inMachineDirectory); + this.FileUtility.CreateDirectoryIfNotExists(rootDeploymentDirectory); + this.FileUtility.CreateDirectoryIfNotExists(inDirectory); + this.FileUtility.CreateDirectoryIfNotExists(outDirectory); + this.FileUtility.CreateDirectoryIfNotExists(inMachineDirectory); return result; } - internal string GetConfigFile(string testSource) + /// + /// add deployment items based on MSTestSettingsProvider.Settings.DeployTestSourceDependencies. This property is ignored in net core. + /// + /// The test source. + /// Deployment Items. + /// Warnings. + public abstract void AddDeploymentItemsBasedOnMsTestSetting(string testSource, IList deploymentItems, List warnings); + + /// + /// Get the parent test results directory where deployment will be done. + /// + /// The run context. + /// The test results directory. + public string GetTestResultsDirectory(IRunContext runContext) { - string configFile = null; + var resultsDirectory = (!string.IsNullOrEmpty(runContext?.TestRunDirectory)) ? + runContext.TestRunDirectory : null; - if (this.fileUtility.DoesFileExist(testSource + TestAssemblyConfigFileExtension)) - { - // Path to config file cannot be bad: storage is already checked, and extension is valid. - configFile = testSource + TestAssemblyConfigFileExtension; - } - else + if (string.IsNullOrEmpty(resultsDirectory)) { - var netAppConfigFile = Path.Combine(Path.GetDirectoryName(testSource), NetAppConfigFile); - if (this.fileUtility.DoesFileExist(netAppConfigFile)) - { - configFile = netAppConfigFile; - } + resultsDirectory = Path.GetFullPath(Path.Combine(Path.GetTempPath(), TestRunDirectories.DefaultDeploymentRootDirectory)); } - return configFile; + return resultsDirectory; } /// - /// Log the parameter warnings on the parameter logger + /// Get root deployment directory /// - /// Execution recorder. - /// Warnings. - private static void LogWarnings(ITestExecutionRecorder testExecutionRecorder, IEnumerable warnings) - { - if (warnings == null) - { - return; - } + /// The base directory. + /// Root deployment directory. + public abstract string GetRootDeploymentDirectory(string baseDirectory); - Debug.Assert(testExecutionRecorder != null, "Logger should not be null"); + internal string GetConfigFile(string testSource) + { + string configFile = null; - // log the warnings - foreach (string warning in warnings) + var assemblyConfigFile = testSource + TestAssemblyConfigFileExtension; + if (this.FileUtility.DoesFileExist(assemblyConfigFile)) { - testExecutionRecorder.SendMessage(TestMessageLevel.Warning, warning); + // Path to config file cannot be bad: storage is already checked, and extension is valid. + configFile = testSource + TestAssemblyConfigFileExtension; } - } - - private bool Deploy(string source, IRunContext runContext, ITestExecutionRecorder testExecutionRecorder, IList deploymentItems, TestRunDirectories runDirectories) - { - ValidateArg.NotNull(runDirectories, "runDirectories"); - if (EqtTrace.IsInfoEnabled) + else { - EqtTrace.Info("MSTestExecutor: Found that deployment items for source {0} are: ", source); - foreach (var item in deploymentItems) + var netAppConfigFile = Path.Combine(Path.GetDirectoryName(testSource), NetAppConfigFile); + if (this.FileUtility.DoesFileExist(netAppConfigFile)) { - EqtTrace.Info("MSTestExecutor: SourcePath: - {0}", item.SourcePath); + configFile = netAppConfigFile; } } - // Do the deployment. - EqtTrace.InfoIf(EqtTrace.IsInfoEnabled, "MSTestExecutor: Using deployment directory {0} for source {1}.", runDirectories.OutDirectory, source); - var warnings = this.Deploy(new List(deploymentItems), source, runDirectories.OutDirectory, this.GetTestResultsDirectory(runContext)); - - // Log warnings - LogWarnings(testExecutionRecorder, warnings); - return deploymentItems != null && deploymentItems.Count > 0; + return configFile; } /// @@ -146,36 +141,17 @@ private bool Deploy(string source, IRunContext runContext, ITestExecutionRecorde /// The deployment directory. /// Root results directory /// Returns a list of deployment warnings - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] - private IEnumerable Deploy(IList deploymentItems, string testSource, string deploymentDirectory, string resultsDirectory) + protected IEnumerable Deploy(IList deploymentItems, string testSource, string deploymentDirectory, string resultsDirectory) { Validate.IsFalse(string.IsNullOrWhiteSpace(deploymentDirectory), "Deployment directory is null or empty"); - Validate.IsTrue(this.fileUtility.DoesDirectoryExist(deploymentDirectory), $"Deployment directory {deploymentDirectory} does not exist"); + Validate.IsTrue(this.FileUtility.DoesDirectoryExist(deploymentDirectory), $"Deployment directory {deploymentDirectory} does not exist"); Validate.IsFalse(string.IsNullOrWhiteSpace(testSource), "TestSource directory is null/empty"); - Validate.IsTrue(this.fileUtility.DoesFileExist(testSource), $"TestSource {testSource} does not exist."); + Validate.IsTrue(this.FileUtility.DoesFileExist(testSource), $"TestSource {testSource} does not exist."); testSource = Path.GetFullPath(testSource); var warnings = new List(); - if (MSTestSettingsProvider.Settings.DeployTestSourceDependencies) - { - EqtTrace.Info("Adding the references and satellite assemblies to the deploymentitems list"); - - // Get the referenced assemblies. - this.ProcessNewStorage(testSource, deploymentItems, warnings); - - // Get the satellite assemblies - var satelliteItems = this.GetSatellites(deploymentItems, testSource, warnings); - foreach (var satelliteItem in satelliteItems) - { - this.deploymentItemUtility.AddDeploymentItem(deploymentItems, satelliteItem); - } - } - else - { - EqtTrace.Info("Adding the test source directory to the deploymentitems list"); - this.deploymentItemUtility.AddDeploymentItem(deploymentItems, new DeploymentItem(Path.GetDirectoryName(testSource))); - } + this.AddDeploymentItemsBasedOnMsTestSetting(testSource, deploymentItems, warnings); // Maps relative to Out dir destination -> source and used to determine if there are conflicted items. var destToSource = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -211,7 +187,7 @@ private IEnumerable Deploy(IList deploymentItems, string // Find dependencies of test deployment items and deploy them at the same time as master file. if (deploymentItem.OriginType == DeploymentItemOriginType.PerTestDeployment && - this.assemblyUtility.IsAssemblyExtension(Path.GetExtension(deploymentItemFile))) + this.AssemblyUtility.IsAssemblyExtension(Path.GetExtension(deploymentItemFile))) { this.AddDependenciesOfDeploymentItem(deploymentItemFile, filesToDeploy, warnings); } @@ -222,7 +198,7 @@ private IEnumerable Deploy(IList deploymentItems, string // Ignore the test platform files. var tempFile = Path.GetFileName(fileToDeploy); - var assemblyName = Path.GetFileName(Assembly.GetExecutingAssembly().Location); + var assemblyName = Path.GetFileName(this.GetType().GetTypeInfo().Assembly.Location); if (tempFile.Equals(assemblyName, StringComparison.OrdinalIgnoreCase)) { continue; @@ -233,7 +209,7 @@ private IEnumerable Deploy(IList deploymentItems, string { // Deploy into subdirectory of deployment (Out) dir. Debug.Assert(fileToDeploy.StartsWith(fullPathToDeploymentItemSource, StringComparison.Ordinal), "Somehow source is outside original dir."); - relativeDestination = this.fileUtility.TryConvertPathToRelative(fileToDeploy, fullPathToDeploymentItemSource); + relativeDestination = this.FileUtility.TryConvertPathToRelative(fileToDeploy, fullPathToDeploymentItemSource); } else { @@ -260,7 +236,7 @@ private IEnumerable Deploy(IList deploymentItems, string destToSource.Add(relativeDestination, fileToDeploy); // Now, finally we can copy the file... - destination = this.fileUtility.CopyFileOverwrite(fileToDeploy, destination, out string warning); + destination = this.FileUtility.CopyFileOverwrite(fileToDeploy, destination, out string warning); if (!string.IsNullOrEmpty(warning)) { warnings.Add(warning); @@ -272,10 +248,10 @@ private IEnumerable Deploy(IList deploymentItems, string } // We clear the attributes so that e.g. you can write to the copies of files originally under SCC. - this.fileUtility.SetAttributes(destination, FileAttributes.Normal); + this.FileUtility.SetAttributes(destination, FileAttributes.Normal); // Deploy PDB for line number info in stack trace. - this.fileUtility.FindAndDeployPdb(destination, relativeDestination, fileToDeploy, destToSource); + this.FileUtility.FindAndDeployPdb(destination, relativeDestination, fileToDeploy, destToSource); } else if ( !string.Equals( @@ -296,61 +272,8 @@ private IEnumerable Deploy(IList deploymentItems, string return warnings; } - private void AddDependenciesOfDeploymentItem(string deploymentItemFile, IList filesToDeploy, IList warnings) - { - var dependencies = new List(); - - this.AddDependencies(deploymentItemFile, null, dependencies, warnings); - - foreach (var dependencyItem in dependencies) - { - Debug.Assert(Path.IsPathRooted(dependencyItem.SourcePath), "Path of the dependency " + dependencyItem.SourcePath + " is not rooted."); - - // Add dependencies to filesToDeploy. - filesToDeploy.Add(dependencyItem.SourcePath); - } - } - - /// - /// Process test storage and add dependant assemblies to dependencyDeploymentItems. - /// - /// The test source. - /// The config file. - /// Deployment items. - /// Warnigns. - private void AddDependencies(string testSource, string configFile, IList deploymentItems, IList warnings) - { - Debug.Assert(!string.IsNullOrEmpty(testSource), "testSource should not be null or empty."); - - // config file can be null. - Debug.Assert(deploymentItems != null, "deploymentItems should not be null."); - Debug.Assert(Path.IsPathRooted(testSource), "path should be rooted."); - - // Note: if this is not an assembly we simply return empty array, also: - // we do recursive search and report missing. - IList warningList; - string[] references = this.assemblyUtility.GetFullPathToDependentAssemblies(testSource, configFile, out warningList); - if (warningList != null && warningList.Count > 0) - { - warnings = warnings.Concat(warningList).ToList(); - } - - if (EqtTrace.IsInfoEnabled) - { - EqtTrace.Info("DeploymentManager: Source:{0} has following references", testSource); - } - - foreach (string reference in references) - { - DeploymentItem deploymentItem = new DeploymentItem(reference, string.Empty, DeploymentItemOriginType.Dependency); - this.deploymentItemUtility.AddDeploymentItem(deploymentItems, deploymentItem); - - if (EqtTrace.IsInfoEnabled) - { - EqtTrace.Info("DeploymentManager: Reference:{0} ", reference); - } - } - } + // Find dependencies of test deployment items + protected abstract void AddDependenciesOfDeploymentItem(string deploymentItemFile, IList filesToDeploy, IList warnings); /// /// Get files corresponding to parameter deployment item. @@ -362,7 +285,7 @@ private void AddDependencies(string testSource, string configFile, IListIs this a directory. /// Paths to items to deploy. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] - private string[] GetFullPathToFilesCorrespondingToDeploymentItem(DeploymentItem deploymentItem, string testSource, string resultsDirectory, IList warnings, out bool isDirectory) + protected string[] GetFullPathToFilesCorrespondingToDeploymentItem(DeploymentItem deploymentItem, string testSource, string resultsDirectory, IList warnings, out bool isDirectory) { Debug.Assert(deploymentItem != null, "deploymentItem should not be null."); Debug.Assert(!string.IsNullOrEmpty(testSource), "testsource should not be null or empty."); @@ -372,7 +295,7 @@ private string[] GetFullPathToFilesCorrespondingToDeploymentItem(DeploymentItem isDirectory = this.IsDeploymentItemSourceADirectory(deploymentItem, testSource, out string directory); if (isDirectory) { - return this.fileUtility.AddFilesFromDirectory( + return this.FileUtility.AddFilesFromDirectory( directory, (deployDirectory) => string.Equals(deployDirectory, resultsDirectory, StringComparison.OrdinalIgnoreCase), false).ToArray(); } @@ -402,122 +325,7 @@ private string[] GetFullPathToFilesCorrespondingToDeploymentItem(DeploymentItem return null; } - private bool IsDeploymentItemSourceAFile(string deploymentItemSourcePath, string testSource, out string file) - { - file = this.GetFullPathToDeploymentItemSource(deploymentItemSourcePath, testSource); - - return this.fileUtility.DoesFileExist(file); - } - - private bool IsDeploymentItemSourceADirectory(DeploymentItem deploymentItem, string testSource, out string resultDirectory) - { - resultDirectory = null; - - string directory = this.GetFullPathToDeploymentItemSource(deploymentItem.SourcePath, testSource); - directory = directory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); - - if (this.fileUtility.DoesDirectoryExist(directory)) - { - resultDirectory = directory; - return true; - } - - return false; - } - - private IEnumerable GetSatellites(IEnumerable deploymentItems, string testSource, IList warnings) - { - List satellites = new List(); - foreach (DeploymentItem item in deploymentItems) - { - // We do not care about deployment items which are directories because in that case we deploy all files underneath anyway. - string path = null; - try - { - path = this.GetFullPathToDeploymentItemSource(item.SourcePath, testSource); - path = Path.GetFullPath(path); - - if (string.IsNullOrEmpty(path) || !this.assemblyUtility.IsAssemblyExtension(Path.GetExtension(path)) - || !this.fileUtility.DoesFileExist(path) || !this.assemblyUtility.IsAssembly(path)) - { - continue; - } - } - catch (ArgumentException ex) - { - EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); - } - catch (SecurityException ex) - { - EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); - } - catch (IOException ex) - { - // This covers PathTooLongException. - EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); - } - catch (NotSupportedException ex) - { - EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); - } - - // Note: now Path operations with itemPath should not result in any exceptions. - // path is already canonicalized. - - // If we cannot access satellite due to security, etc, we report warning. - try - { - string itemDir = Path.GetDirectoryName(path).TrimEnd( - new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); - List itemSatellites = this.assemblyUtility.GetSatelliteAssemblies(path); - foreach (string satellite in itemSatellites) - { - Debug.Assert(!string.IsNullOrEmpty(satellite), "DeploymentManager.DoDeployment: got empty satellite!"); - Debug.Assert( - satellite.IndexOf(itemDir, StringComparison.OrdinalIgnoreCase) == 0, - "DeploymentManager.DoDeployment: Got satellite that does not start with original item path"); - - string satelliteDir = Path.GetDirectoryName(satellite).TrimEnd( - new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); - - Debug.Assert(!string.IsNullOrEmpty(satelliteDir), "DeploymentManager.DoDeployment: got empty satellite dir!"); - Debug.Assert(satelliteDir.Length > itemDir.Length + 1, "DeploymentManager.DoDeployment: wrong satellite dir lenght!"); - - string localeDir = satelliteDir.Substring(itemDir.Length + 1); - Debug.Assert(!string.IsNullOrEmpty(localeDir), "DeploymentManager.DoDeployment: got empty dir name for satellite dir!"); - - string relativeOutputDir = Path.Combine(item.RelativeOutputDirectory, localeDir); - - // Now finally add the item! - DeploymentItem satelliteItem = new DeploymentItem(satellite, relativeOutputDir, DeploymentItemOriginType.Satellite); - this.deploymentItemUtility.AddDeploymentItem(satellites, satelliteItem); - } - } - catch (ArgumentException ex) - { - EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); - string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorGettingSatellite, item, ex.GetType(), ex.GetExceptionMessage()); - warnings.Add(warning); - } - catch (SecurityException ex) - { - EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); - string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorGettingSatellite, item, ex.GetType(), ex.GetExceptionMessage()); - warnings.Add(warning); - } - catch (IOException ex) - { - // This covers PathTooLongException. - EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex); - string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorGettingSatellite, item, ex.GetType(), ex.GetExceptionMessage()); - warnings.Add(warning); - } - } - - return satellites; - } - - private string GetFullPathToDeploymentItemSource(string deploymentItemSourcePath, string testSource) + protected string GetFullPathToDeploymentItemSource(string deploymentItemSourcePath, string testSource) { if (Path.IsPathRooted(deploymentItemSourcePath)) { @@ -535,7 +343,7 @@ private string GetFullPathToDeploymentItemSource(string deploymentItemSourcePath /// Warnings. /// True if valid. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] - private bool IsOutputDirectoryValid(DeploymentItem deploymentItem, string deploymentDirectory, IList warnings) + protected bool IsOutputDirectoryValid(DeploymentItem deploymentItem, string deploymentDirectory, IList warnings) { Debug.Assert(deploymentItem != null, "deploymentItem should not be null."); Debug.Assert(!string.IsNullOrEmpty(deploymentDirectory), "deploymentDirectory should not be null or empty."); @@ -580,82 +388,81 @@ private bool IsOutputDirectoryValid(DeploymentItem deploymentItem, string deploy return true; } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] - private void ProcessNewStorage(string testSource, IList deploymentItems, IList warnings) + protected string AddTestSourceConfigFileIfExists(string testSource, IList deploymentItems) { - // Add deployment items and process .config files only for storages we have not processed before. - string errorMessage; - if (!this.deploymentItemUtility.IsValidDeploymentItem(testSource, string.Empty, out errorMessage)) + string configFile = this.GetConfigFile(testSource); + + if (string.IsNullOrEmpty(configFile) == false) { - warnings.Add(errorMessage); - return; + this.DeploymentItemUtility.AddDeploymentItem(deploymentItems, new DeploymentItem(configFile)); } - this.deploymentItemUtility.AddDeploymentItem(deploymentItems, new DeploymentItem(testSource, string.Empty, DeploymentItemOriginType.TestStorage)); + return configFile; + } - // Deploy .config file if exists, only for assemlbies, i.e. DLL and EXE. - // First check .config, then if not found check for App.Config - // and deploy AppConfig to .config. - if (this.assemblyUtility.IsAssemblyExtension(Path.GetExtension(testSource))) + /// + /// Log the parameter warnings on the parameter logger + /// + /// Execution recorder. + /// Warnings. + private static void LogWarnings(ITestExecutionRecorder testExecutionRecorder, IEnumerable warnings) + { + if (warnings == null) { - var configFile = this.AddTestSourceConfigFileIfExists(testSource, deploymentItems); + return; + } - // Deal with test dependencies: update dependencyDeploymentItems and missingDependentAssemblies. - try - { - // We look for dependent assemblies only for DLL and EXE's. - this.AddDependencies(testSource, configFile, deploymentItems, warnings); - } - catch (Exception e) - { - string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorFailedToDeployDependencies, testSource, e); - warnings.Add(warning); - } + Debug.Assert(testExecutionRecorder != null, "Logger should not be null"); + + // log the warnings + foreach (string warning in warnings) + { + testExecutionRecorder.SendMessage(TestMessageLevel.Warning, warning); } } - /// - /// Get the parent test results directory where deployment will be done. - /// - /// The run context. - /// The test results directory. - private string GetTestResultsDirectory(IRunContext runContext) + private bool Deploy(string source, IRunContext runContext, ITestExecutionRecorder testExecutionRecorder, IList deploymentItems, TestRunDirectories runDirectories) { - var resultsDirectory = (!string.IsNullOrEmpty(runContext?.TestRunDirectory)) ? - runContext.TestRunDirectory : null; - - if (string.IsNullOrEmpty(resultsDirectory)) + ValidateArg.NotNull(runDirectories, "runDirectories"); + if (EqtTrace.IsInfoEnabled) { - resultsDirectory = Path.GetFullPath(Path.Combine(Path.GetTempPath(), TestRunDirectories.DefaultDeploymentRootDirectory)); + EqtTrace.Info("MSTestExecutor: Found that deployment items for source {0} are: ", source); + foreach (var item in deploymentItems) + { + EqtTrace.Info("MSTestExecutor: SourcePath: - {0}", item.SourcePath); + } } - return resultsDirectory; + // Do the deployment. + EqtTrace.InfoIf(EqtTrace.IsInfoEnabled, "MSTestExecutor: Using deployment directory {0} for source {1}.", runDirectories.OutDirectory, source); + var warnings = this.Deploy(new List(deploymentItems), source, runDirectories.OutDirectory, this.GetTestResultsDirectory(runContext)); + + // Log warnings + LogWarnings(testExecutionRecorder, warnings); + return deploymentItems != null && deploymentItems.Count > 0; } - /// - /// Get root deployment directory - /// - /// The base directory. - /// Root deployment directory. - private string GetRootDeploymentDirectory(string baseDirectory) + private bool IsDeploymentItemSourceAFile(string deploymentItemSourcePath, string testSource, out string file) { - string dateTimeSufix = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo); - string directoryName = string.Format(CultureInfo.CurrentCulture, Resource.TestRunName, DeploymentFolderPrefix, Environment.UserName, dateTimeSufix); - directoryName = this.fileUtility.ReplaceInvalidFileNameCharacters(directoryName); + file = this.GetFullPathToDeploymentItemSource(deploymentItemSourcePath, testSource); - return this.fileUtility.GetNextIterationDirectoryName(baseDirectory, directoryName); + return this.FileUtility.DoesFileExist(file); } - private string AddTestSourceConfigFileIfExists(string testSource, IList deploymentItems) + private bool IsDeploymentItemSourceADirectory(DeploymentItem deploymentItem, string testSource, out string resultDirectory) { - string configFile = this.GetConfigFile(testSource); + resultDirectory = null; - if (string.IsNullOrEmpty(configFile) == false) + string directory = this.GetFullPathToDeploymentItemSource(deploymentItem.SourcePath, testSource); + directory = directory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + + if (this.FileUtility.DoesDirectoryExist(directory)) { - this.deploymentItemUtility.AddDeploymentItem(deploymentItems, new DeploymentItem(configFile)); + resultDirectory = directory; + return true; } - return configFile; + return false; } } } diff --git a/src/Adapter/PlatformServices.Desktop/Utilities/FileUtility.cs b/src/Adapter/PlatformServices.Shared/netstandard1.3/Utilities/ns13FileUtility.cs similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Utilities/FileUtility.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.3/Utilities/ns13FileUtility.cs diff --git a/src/Adapter/PlatformServices.Desktop/Deployment/DeploymentItem.cs b/src/Adapter/PlatformServices.Shared/netstandard1.3/ns13DeploymentItem.cs similarity index 100% rename from src/Adapter/PlatformServices.Desktop/Deployment/DeploymentItem.cs rename to src/Adapter/PlatformServices.Shared/netstandard1.3/ns13DeploymentItem.cs diff --git a/src/Package/MSTest.TestAdapter.nuspec b/src/Package/MSTest.TestAdapter.nuspec index 8ef68ec7f8..d67b9b24a8 100644 --- a/src/Package/MSTest.TestAdapter.nuspec +++ b/src/Package/MSTest.TestAdapter.nuspec @@ -79,6 +79,20 @@ + + diff --git a/src/TestFramework/Extension.Core/Attributes/DeploymentItemAttribute.cs b/src/TestFramework/Extension.Core/Attributes/DeploymentItemAttribute.cs index c84260967f..8a7308d248 100644 --- a/src/TestFramework/Extension.Core/Attributes/DeploymentItemAttribute.cs +++ b/src/TestFramework/Extension.Core/Attributes/DeploymentItemAttribute.cs @@ -16,9 +16,6 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting /// [DeploymentItem("file2.xml", "DataFiles")] /// [DeploymentItem("bin\Debug")] /// - /// - /// DeploymentItemAttribute is currently not supported in .Net Core. This is just a placehodler for support in the future. - /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)] public sealed class DeploymentItemAttribute : Attribute { diff --git a/src/TestFramework/Extension.Core/Extension.Core.csproj b/src/TestFramework/Extension.Core/Extension.Core.csproj index a71634a810..1fc52d1a70 100644 --- a/src/TestFramework/Extension.Core/Extension.Core.csproj +++ b/src/TestFramework/Extension.Core/Extension.Core.csproj @@ -37,6 +37,7 @@ + @@ -48,6 +49,5 @@ - \ No newline at end of file diff --git a/src/TestFramework/Extension.Core/NetCoreTestContext.cs b/src/TestFramework/Extension.Core/NetCoreTestContext.cs new file mode 100644 index 0000000000..644d75ce01 --- /dev/null +++ b/src/TestFramework/Extension.Core/NetCoreTestContext.cs @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestTools.UnitTesting +{ + using System; + using System.Collections; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Threading; + + /// + /// Used to store information that is provided to unit tests. + /// + public abstract class TestContext + { + /// + /// Gets test properties for a test. + /// + public abstract IDictionary Properties { get; } + + #region Test run deployment directories + + /// + /// Gets or sets the cancellation token source. This token source is cancelled when test timesout. Also when explicitly cancelled the test will be aborted + /// + public virtual CancellationTokenSource CancellationTokenSource { get; protected set; } + + /// + /// Gets base directory for the test run, under which deployed files and result files are stored. + /// + public virtual string TestRunDirectory => this.GetProperty("TestRunDirectory"); + + /// + /// Gets directory for files deployed for the test run. Typically a subdirectory of . + /// + public virtual string DeploymentDirectory => this.GetProperty("DeploymentDirectory"); + + /// + /// Gets base directory for results from the test run. Typically a subdirectory of . + /// + public virtual string ResultsDirectory => this.GetProperty("ResultsDirectory"); + + /// + /// Gets directory for test run result files. Typically a subdirectory of . + /// + public virtual string TestRunResultsDirectory => this.GetProperty("TestRunResultsDirectory"); + + /// + /// Gets directory for test result files. + /// + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", Justification = "Compat")] + public virtual string TestResultsDirectory => this.GetProperty("TestResultsDirectory"); + + #region Old names, for backwards compatibility + + /// + /// Gets base directory for the test run, under which deployed files and result files are stored. + /// Same as . Use that property instead. + /// + public virtual string TestDir => this.GetProperty("TestDir"); + + /// + /// Gets directory for files deployed for the test run. Typically a subdirectory of . + /// Same as . Use that property instead. + /// + public virtual string TestDeploymentDir => this.GetProperty("TestDeploymentDir"); + + /// + /// Gets directory for test run result files. Typically a subdirectory of . + /// Same as . Use that property for test run result files, or + /// for test-specific result files instead. + /// + public virtual string TestLogsDir => this.GetProperty("TestLogsDir"); + + #endregion + + #endregion + + // This property can be useful in attributes derived from ExpectedExceptionBaseAttribute. + // Those attributes have access to the test context, and provide messages that are included + // in the test results. Users can benefit from messages that include the fully-qualified + // class name in addition to the name of the test method currently being executed. + + /// + /// Gets the Fully-qualified name of the class containing the test method currently being executed + /// + public virtual string FullyQualifiedTestClassName => this.GetProperty("FullyQualifiedTestClassName"); + + /// + /// Gets the name of the test method currently being executed + /// + public virtual string TestName => this.GetProperty("TestName"); + + /// + /// Gets the current test outcome. + /// + public virtual UnitTestOutcome CurrentTestOutcome => UnitTestOutcome.Unknown; + + /// + /// Used to write trace messages while the test is running + /// + /// formatted message string + public abstract void WriteLine(string message); + + /// + /// Used to write trace messages while the test is running + /// + /// format string + /// the arguments + public abstract void WriteLine(string format, params object[] args); + + private T GetProperty(string name) + where T : class + { + object o = this.Properties[name]; + + // If o has a value, but it's not the right type + if (o != null && !(o is T)) + { + throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, FrameworkMessages.InvalidPropertyType, name, o.GetType(), typeof(T))); + } + + return (T)o; + } + } +} diff --git a/src/TestFramework/Extension.Desktop/TestContext.cs b/src/TestFramework/Extension.Desktop/DesktopTestContext.cs similarity index 100% rename from src/TestFramework/Extension.Desktop/TestContext.cs rename to src/TestFramework/Extension.Desktop/DesktopTestContext.cs diff --git a/src/TestFramework/Extension.Desktop/Extension.Desktop.csproj b/src/TestFramework/Extension.Desktop/Extension.Desktop.csproj index 57aa0f5048..078cd59ccb 100644 --- a/src/TestFramework/Extension.Desktop/Extension.Desktop.csproj +++ b/src/TestFramework/Extension.Desktop/Extension.Desktop.csproj @@ -64,7 +64,7 @@ - + \ No newline at end of file diff --git a/test/E2ETests/Automation.CLI/Automation.CLI.csproj b/test/E2ETests/Automation.CLI/Automation.CLI.csproj index 6d74c16b8d..f72792ac61 100644 --- a/test/E2ETests/Automation.CLI/Automation.CLI.csproj +++ b/test/E2ETests/Automation.CLI/Automation.CLI.csproj @@ -97,17 +97,23 @@ $(TargetDir)..\ $(TargetDir)..\..\TestAssets - xcopy /Y /I "$(SourcePath)MSTest.CoreAdapter\Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.dll" "$(DestinationPath)" - xcopy /Y /I "$(SourcePath)MSTest.CoreAdapter\Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.pdb" "$(DestinationPath)" - xcopy /Y /I "$(SourcePath)PlatformServices.Desktop\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll" "$(DestinationPath)" - xcopy /Y /I "$(SourcePath)PlatformServices.Desktop\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.pdb" "$(DestinationPath)" - xcopy /Y /I "$(SourcePath)PlatformServices.Interface\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.dll" "$(DestinationPath)" - xcopy /Y /I "$(SourcePath)PlatformServices.Interface\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.pdb" "$(DestinationPath)" - xcopy /Y /I "$(SourcePath)MSTest.Core\Microsoft.VisualStudio.TestPlatform.TestFramework.dll" "$(DestinationPath)" - xcopy /Y /I "$(SourcePath)MSTest.Core\Microsoft.VisualStudio.TestPlatform.TestFramework.pdb" "$(DestinationPath)" - xcopy /Y /I "$(SourcePath)Extension.Desktop\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll" "$(DestinationPath)" - xcopy /Y /I "$(SourcePath)Extension.Desktop\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.pdb" "$(DestinationPath)" - + xcopy /Y /I "$(SourcePath)MSTest.CoreAdapter\Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.dll" "$(DestinationPath)" + xcopy /Y /I "$(SourcePath)MSTest.CoreAdapter\Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.pdb" "$(DestinationPath)" + xcopy /Y /I "$(SourcePath)PlatformServices.Desktop\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll" "$(DestinationPath)" + xcopy /Y /I "$(SourcePath)PlatformServices.Desktop\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.pdb" "$(DestinationPath)" + xcopy /Y /I "$(SourcePath)MSTest.CoreAdapter\Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.dll" "$(DestinationPath)\netcoreapp1.1\" + xcopy /Y /I "$(SourcePath)MSTest.CoreAdapter\Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.pdb" "$(DestinationPath)\netcoreapp1.1\" + xcopy /Y /I "$(SourcePath)PlatformServices.NetCore\netstandard1.5\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll" "$(DestinationPath)\netcoreapp1.1\" + xcopy /Y /I "$(SourcePath)PlatformServices.NetCore\netstandard1.5\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.pdb" "$(DestinationPath)\netcoreapp1.1\" + xcopy /Y /I "$(SourcePath)PlatformServices.NetCore\netstandard1.5\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.dll" "$(DestinationPath)\netcoreapp1.1\" + xcopy /Y /I "$(SourcePath)PlatformServices.NetCore\netstandard1.5\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.pdb" "$(DestinationPath)\netcoreapp1.1\" + xcopy /Y /I "$(SourcePath)PlatformServices.Interface\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.dll" "$(DestinationPath)" + xcopy /Y /I "$(SourcePath)PlatformServices.Interface\Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.pdb" "$(DestinationPath)" + xcopy /Y /I "$(SourcePath)MSTest.Core\Microsoft.VisualStudio.TestPlatform.TestFramework.dll" "$(DestinationPath)" + xcopy /Y /I "$(SourcePath)MSTest.Core\Microsoft.VisualStudio.TestPlatform.TestFramework.pdb" "$(DestinationPath)" + xcopy /Y /I "$(SourcePath)Extension.Desktop\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll" "$(DestinationPath)" + xcopy /Y /I "$(SourcePath)Extension.Desktop\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.pdb" "$(DestinationPath)" + + + + + + + diff --git a/test/E2ETests/TestAssets/DeploymentTestProjectNetCore/EmptyDataFile.xml b/test/E2ETests/TestAssets/DeploymentTestProjectNetCore/EmptyDataFile.xml new file mode 100644 index 0000000000..968bef4f20 --- /dev/null +++ b/test/E2ETests/TestAssets/DeploymentTestProjectNetCore/EmptyDataFile.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/test/E2ETests/TestAssets/DeploymentTestProjectNetCore/TestCaseDeploymentFile.xml b/test/E2ETests/TestAssets/DeploymentTestProjectNetCore/TestCaseDeploymentFile.xml new file mode 100644 index 0000000000..968bef4f20 --- /dev/null +++ b/test/E2ETests/TestAssets/DeploymentTestProjectNetCore/TestCaseDeploymentFile.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/test/UnitTests/MSTest.CoreAdapter.TestUtilities/ActionUtility.cs b/test/UnitTests/MSTest.CoreAdapter.TestUtilities/ActionUtility.cs index 00021fdc50..c971d622f9 100644 --- a/test/UnitTests/MSTest.CoreAdapter.TestUtilities/ActionUtility.cs +++ b/test/UnitTests/MSTest.CoreAdapter.TestUtilities/ActionUtility.cs @@ -3,7 +3,7 @@ namespace MSTestAdapter.TestUtilities { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 using TestFramework = Microsoft.VisualStudio.TestTools.UnitTesting; #else extern alias FrameworkV1; diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/PlatformServices.Desktop.Unit.Tests.csproj b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/PlatformServices.Desktop.Unit.Tests.csproj index a650c183c6..cb0fca9577 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/PlatformServices.Desktop.Unit.Tests.csproj +++ b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/PlatformServices.Desktop.Unit.Tests.csproj @@ -55,33 +55,56 @@ + + Deployment\ns10DeploymentItemTests.cs + + + Deployment\ns10TestRunDirectoriesTests.cs + + + Extensions\ns10ExceptionExtensionsTests.cs + + + Services\ns10MSTestAdapterSettingsTests.cs + + + Utilities\ns10DeploymentUtilityTests.cs + + + Utilities\ns10FileUtilityTests.cs + Services\ns13TraceListenerManagerTests.cs Services\ns13TraceListenerTests.cs + + Services\ns13MSTestSettingsProviderTests.cs + + + Services\ns13TestDeploymentTests.cs + + + Utilities\ns13DeploymentItemUtilityTests.cs + + + Utilities\ns13ReflectionUtilityTests.cs + - - - - - - - - - + + @@ -109,7 +132,7 @@ {a7ea583b-a2b0-47da-a058-458f247c7575} Extension.Desktop - FrameworkV2DesktopExtension + FrameworkV2Extension {7252d9e3-267d-442c-96bc-c73aef3241d6} diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestDataSourceTests.cs b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestDataSourceTests.cs index d1abc9444c..e69e75cbf2 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestDataSourceTests.cs +++ b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestDataSourceTests.cs @@ -5,7 +5,7 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Services { extern alias FrameworkV1; extern alias FrameworkV2; - extern alias FrameworkV2DesktopExtension; + extern alias FrameworkV2Extension; using System.Collections.Generic; using System.Data; @@ -14,7 +14,7 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Services using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel; using Moq; using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; - using DesktopTestFrameworkV2 = FrameworkV2DesktopExtension::Microsoft.VisualStudio.TestTools.UnitTesting; + using DesktopTestFrameworkV2 = FrameworkV2Extension::Microsoft.VisualStudio.TestTools.UnitTesting; using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; using TestFrameworkV2 = FrameworkV2::Microsoft.VisualStudio.TestTools.UnitTesting; using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestDeploymentTests.cs b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestDeploymentTests.cs index 4449b5568c..75f7fbadb2 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestDeploymentTests.cs +++ b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestDeploymentTests.cs @@ -5,7 +5,7 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Services { extern alias FrameworkV1; extern alias FrameworkV2; - extern alias FrameworkV2DesktopExtension; + extern alias FrameworkV2Extension; using System.Collections.Generic; using System.IO; @@ -20,13 +20,13 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Services using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; using Moq; - using Utilities; + using MSTestAdapter.PlatformServices.Tests.Utilities; using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; using CollectionAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert; using Ignore = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.IgnoreAttribute; using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; - using TestFrameworkV2Extension = FrameworkV2DesktopExtension::Microsoft.VisualStudio.TestTools.UnitTesting; + using TestFrameworkV2Extension = FrameworkV2Extension::Microsoft.VisualStudio.TestTools.UnitTesting; using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; @@ -52,279 +52,8 @@ public void TestInit() MSTestSettingsProvider.Reset(); } - #region GetDeploymentItems tests. - - [TestMethod] - public void GetDeploymentItemsReturnsNullWhenNoDeploymentItems() - { - var methodInfo = - typeof(DesktopTestDeploymentTests).GetMethod("GetDeploymentItemsReturnsNullWhenNoDeploymentItems"); - - Assert.IsNull(new TestDeployment().GetDeploymentItems(methodInfo, typeof(DesktopTestDeploymentTests), this.warnings)); - } - - [TestMethod] - public void GetDeploymentItemsReturnsDeploymentItems() - { - // Arrange. - var testDeployment = new TestDeployment(new DeploymentItemUtility(this.mockReflectionUtility.Object), null, null); - - // setup mocks - var methodLevelDeploymentItems = new[] - { - new KeyValuePair( - DefaultDeploymentItemPath, - DefaultDeploymentItemOutputDirectory) - }; - var classLevelDeploymentItems = new[] - { - new KeyValuePair( - DefaultDeploymentItemPath + "\\temp2", - DefaultDeploymentItemOutputDirectory) - }; - var memberInfo = - typeof(DesktopTestDeploymentTests).GetMethod( - "GetDeploymentItemsReturnsDeploymentItems"); - this.SetupDeploymentItems(memberInfo, methodLevelDeploymentItems); - this.SetupDeploymentItems(typeof(DesktopTestDeploymentTests), classLevelDeploymentItems); - - // Act. - var deploymentItems = testDeployment.GetDeploymentItems(memberInfo, typeof(DesktopTestDeploymentTests), this.warnings); - - // Assert. - var expectedDeploymentItems = new KeyValuePair[] - { - new KeyValuePair( - DefaultDeploymentItemPath, - DefaultDeploymentItemOutputDirectory), - new KeyValuePair( - DefaultDeploymentItemPath + "\\temp2", - DefaultDeploymentItemOutputDirectory) - }; - - CollectionAssert.AreEqual(expectedDeploymentItems, deploymentItems.ToArray()); - } - - #endregion - - #region Cleanup tests - - [TestMethod] - public void CleanupShouldNotDeleteDirectoriesIfRunDirectoiresIsNull() - { - var testDeployment = new TestDeployment(null, null, this.mockFileUtility.Object); - - testDeployment.Cleanup(); - - this.mockFileUtility.Verify(fu => fu.DeleteDirectories(It.IsAny()), Times.Never); - } - - [TestMethod] - public void CleanupShouldNotDeleteDirectoriesIfRunSettingsSpecifiesSo() - { - string runSettingxml = - @"False"; - StringReader stringReader = new StringReader(runSettingxml); - XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); - MSTestSettingsProvider mstestSettingsProvider = new MSTestSettingsProvider(); - mstestSettingsProvider.Load(reader); - - TestRunDirectories testRunDirectories; - var testCase = this.GetTestCase(Assembly.GetExecutingAssembly().Location); - - // Setup mocks. - var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); - - var mockRunContext = new Mock(); - mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(testRunDirectories.RootDeploymentDirectory); - - Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); - - testDeployment.Cleanup(); - - this.mockFileUtility.Verify(fu => fu.DeleteDirectories(It.IsAny()), Times.Never); - } - - [TestMethod] - public void CleanupShouldDeleteRootDeploymentDirectory() - { - TestRunDirectories testRunDirectories; - var testCase = this.GetTestCase(Assembly.GetExecutingAssembly().Location); - - // Setup mocks. - var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); - - var mockRunContext = new Mock(); - mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(testRunDirectories.RootDeploymentDirectory); - - Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); - - // Act. - testDeployment.Cleanup(); - - this.mockFileUtility.Verify(fu => fu.DeleteDirectories(testRunDirectories.RootDeploymentDirectory), Times.Once); - } - - #endregion - - #region GetDeploymentDirectory tests - - [TestMethod] - public void GetDeploymentDirectoryShouldReturnNullIfDeploymentDirectoryIsNull() - { - Assert.IsNull(new TestDeployment().GetDeploymentDirectory()); - } - - [TestMethod] - public void GetDeploymentDirectoryShouldReturnDeploymentOutputDirectory() - { - TestRunDirectories testRunDirectories; - var testCase = this.GetTestCase(Assembly.GetExecutingAssembly().Location); - - // Setup mocks. - var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); - - var mockRunContext = new Mock(); - mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(testRunDirectories.RootDeploymentDirectory); - - Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); - - // Act. - Assert.AreEqual(testRunDirectories.OutDirectory, testDeployment.GetDeploymentDirectory()); - } - - #endregion - #region Deploy tests - [TestMethod] - public void DeployShouldReturnFalseWhenDeploymentEnabledSetToFalseButHasDeploymentItems() - { - var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), "A"); - var kvparray = new[] - { - new KeyValuePair( - DefaultDeploymentItemPath, - DefaultDeploymentItemOutputDirectory) - }; - testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, kvparray); - - var testDeployment = new TestDeployment( - new DeploymentItemUtility(this.mockReflectionUtility.Object), - new DeploymentUtility(), - this.mockFileUtility.Object); - - string runSettingxml = - @"False"; - StringReader stringReader = new StringReader(runSettingxml); - XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); - MSTestSettingsProvider mstestSettingsProvider = new MSTestSettingsProvider(); - mstestSettingsProvider.Load(reader); - - // Deployment should not happen - Assert.IsFalse(testDeployment.Deploy(new List { testCase }, null, null)); - - // Deplyment directories should not be created - Assert.IsNull(testDeployment.GetDeploymentDirectory()); - } - - [TestMethod] - public void DeployShouldReturnFalseWhenDeploymentEnabledSetToFalseAndHasNoDeploymentItems() - { - var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), "A"); - testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, null); - var testDeployment = new TestDeployment( - new DeploymentItemUtility(this.mockReflectionUtility.Object), - new DeploymentUtility(), - this.mockFileUtility.Object); - - string runSettingxml = - @"False"; - StringReader stringReader = new StringReader(runSettingxml); - XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); - MSTestSettingsProvider mstestSettingsProvider = new MSTestSettingsProvider(); - mstestSettingsProvider.Load(reader); - - // Deployment should not happen - Assert.IsFalse(testDeployment.Deploy(new List { testCase }, null, null)); - - // Deployment directories should get created - Assert.IsNotNull(testDeployment.GetDeploymentDirectory()); - } - - [TestMethod] - public void DeployShouldReturnFalseWhenDeploymentEnabledSetToTrueButHasNoDeploymentItems() - { - var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), "A"); - testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, null); - var testDeployment = new TestDeployment( - new DeploymentItemUtility(this.mockReflectionUtility.Object), - new DeploymentUtility(), - this.mockFileUtility.Object); - - string runSettingxml = - @"True"; - StringReader stringReader = new StringReader(runSettingxml); - XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); - MSTestSettingsProvider mstestSettingsProvider = new MSTestSettingsProvider(); - mstestSettingsProvider.Load(reader); - - // Deployment should not happen - Assert.IsFalse(testDeployment.Deploy(new List { testCase }, null, null)); - - // Deployment directories should get created - Assert.IsNotNull(testDeployment.GetDeploymentDirectory()); - } - - // [Todo] This test has to have mocks. It actually deploys stuff and we cannot assume that all the dependencies get copied over to bin\debug. - [TestMethod] - [Ignore] - public void DeployShouldReturnTrueWhenDeploymentEnabledSetToTrueAndHasDeploymentItems() - { - var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), Assembly.GetExecutingAssembly().Location); - var kvpArray = new[] - { - new KeyValuePair( - DefaultDeploymentItemPath, - DefaultDeploymentItemOutputDirectory) - }; - testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, kvpArray); - var testDeployment = new TestDeployment( - new DeploymentItemUtility(this.mockReflectionUtility.Object), - new DeploymentUtility(), - this.mockFileUtility.Object); - - string runSettingxml = - @"True"; - StringReader stringReader = new StringReader(runSettingxml); - XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); - MSTestSettingsProvider mstestSettingsProvider = new MSTestSettingsProvider(); - mstestSettingsProvider.Load(reader); - - // Deployment should happen - Assert.IsTrue(testDeployment.Deploy(new List { testCase }, null, new Mock().Object)); - - // Deployment directories should get created - Assert.IsNotNull(testDeployment.GetDeploymentDirectory()); - } - - [TestMethod] - public void DeployShouldCreateDeploymentDirectories() - { - TestRunDirectories testRunDirectories; - var testCase = this.GetTestCase(Assembly.GetExecutingAssembly().Location); - - // Setup mocks. - var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); - - var mockRunContext = new Mock(); - mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(testRunDirectories.RootDeploymentDirectory); - - Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); - - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(testRunDirectories.RootDeploymentDirectory), Times.Once); - } - [TestMethod] public void DeployShouldDeployFilesInASourceAndReturnTrue() { @@ -384,125 +113,11 @@ public void DeployShouldDeployFilesInMultipleSourcesAndReturnTrue() Times.Once); } - #endregion - - #region GetDeploymentInformation tests - - [TestMethod] - public void GetDeploymentInformationShouldReturnAppBaseDirectoryIfRunDirectoryIsNull() - { - TestDeployment.Reset(); - var properties = TestDeployment.GetDeploymentInformation(Assembly.GetExecutingAssembly().Location); - - var applicationBaseDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - var expectedProperties = new Dictionary - { - { - TestContextPropertyStrings.TestRunDirectory, - applicationBaseDirectory - }, - { - TestContextPropertyStrings.DeploymentDirectory, - applicationBaseDirectory - }, - { - TestContextPropertyStrings.ResultsDirectory, - applicationBaseDirectory - }, - { - TestContextPropertyStrings - .TestRunResultsDirectory, - applicationBaseDirectory - }, - { - TestContextPropertyStrings - .TestResultsDirectory, - applicationBaseDirectory - }, - { - TestContextPropertyStrings.TestDir, - applicationBaseDirectory - }, - { - TestContextPropertyStrings.TestDeploymentDir, - applicationBaseDirectory - }, - { - TestContextPropertyStrings.TestLogsDir, - applicationBaseDirectory - } - }; - Assert.IsNotNull(properties); - CollectionAssert.AreEqual(expectedProperties.ToList(), properties.ToList()); - } - - [TestMethod] - public void GetDeploymentInformationShouldReturnRunDirectoryInformationIfSourceIsNull() - { - // Arrange. - TestRunDirectories testRunDirectories; - var testCase = this.GetTestCase(Assembly.GetExecutingAssembly().Location); - - // Setup mocks. - var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); - - var mockRunContext = new Mock(); - mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(testRunDirectories.RootDeploymentDirectory); - - Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); - - // Act. - var properties = TestDeployment.GetDeploymentInformation(null); - - // Assert. - var expectedProperties = new Dictionary - { - { - TestContextPropertyStrings.TestRunDirectory, - testRunDirectories.RootDeploymentDirectory - }, - { - TestContextPropertyStrings.DeploymentDirectory, - testRunDirectories.OutDirectory - }, - { - TestContextPropertyStrings.ResultsDirectory, - testRunDirectories.InDirectory - }, - { - TestContextPropertyStrings - .TestRunResultsDirectory, - testRunDirectories.InMachineNameDirectory - }, - { - TestContextPropertyStrings - .TestResultsDirectory, - testRunDirectories.InDirectory - }, - { - TestContextPropertyStrings.TestDir, - testRunDirectories.RootDeploymentDirectory - }, - { - TestContextPropertyStrings.TestDeploymentDir, - testRunDirectories.OutDirectory - }, - { - TestContextPropertyStrings.TestLogsDir, - testRunDirectories.InMachineNameDirectory - } - }; - - Assert.IsNotNull(properties); - CollectionAssert.AreEqual(expectedProperties.ToList(), properties.ToList()); - } - [TestMethod] - public void GetDeploymentInformationShouldReturnRunDirectoryInformationIfSourceIsNotNull() + public void DeployShouldCreateDeploymentDirectories() { - // Arrange. TestRunDirectories testRunDirectories; - var testCase = this.GetTestCase(Assembly.GetExecutingAssembly().Location); + var testCase = this.GetTestCase(typeof(DesktopTestDeploymentTests).GetTypeInfo().Assembly.Location); // Setup mocks. var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); @@ -512,50 +127,8 @@ public void GetDeploymentInformationShouldReturnRunDirectoryInformationIfSourceI Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); - // Act. - var properties = TestDeployment.GetDeploymentInformation(Assembly.GetExecutingAssembly().Location); - - // Assert. - var expectedProperties = new Dictionary - { - { - TestContextPropertyStrings.TestRunDirectory, - testRunDirectories.RootDeploymentDirectory - }, - { - TestContextPropertyStrings.DeploymentDirectory, - testRunDirectories.OutDirectory - }, - { - TestContextPropertyStrings.ResultsDirectory, - testRunDirectories.InDirectory - }, - { - TestContextPropertyStrings - .TestRunResultsDirectory, - testRunDirectories.InMachineNameDirectory - }, - { - TestContextPropertyStrings - .TestResultsDirectory, - testRunDirectories.InDirectory - }, - { - TestContextPropertyStrings.TestDir, - testRunDirectories.RootDeploymentDirectory - }, - { - TestContextPropertyStrings.TestDeploymentDir, - testRunDirectories.OutDirectory - }, - { - TestContextPropertyStrings.TestLogsDir, - testRunDirectories.InMachineNameDirectory - } - }; - - Assert.IsNotNull(properties); - CollectionAssert.AreEqual(expectedProperties.ToList(), properties.ToList()); + // matched twice because root deployment and out directory are same in net core + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(testRunDirectories.RootDeploymentDirectory), Times.Once); } #endregion diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DeploymentUtilityTests.cs b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DesktopDeploymentUtilityTests.cs similarity index 83% rename from test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DeploymentUtilityTests.cs rename to test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DesktopDeploymentUtilityTests.cs index 6e41edd409..c80f7a8d18 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DeploymentUtilityTests.cs +++ b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DesktopDeploymentUtilityTests.cs @@ -10,23 +10,23 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Utilities using System.Collections.Generic; using System.IO; using System.Reflection; - using System.Xml; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; using Moq; - + using MSTestAdapter.PlatformServices.Tests.Utilities; using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; [TestClass] +#pragma warning disable SA1649 // File name must match first type name public class DeploymentUtilityTests +#pragma warning restore SA1649 // File name must match first type name { private const string TestRunDirectory = "C:\\temp\\testRunDirectory"; private const string RootDeploymentDirectory = "C:\\temp\\testRunDirectory\\Deploy"; @@ -62,63 +62,6 @@ public void TestInit() this.mocktestExecutionRecorder = new Mock(); } - #region CreateDeploymentDirectories tests - - [TestMethod] - public void CreateDeploymentDirectoriesShouldCreateDeploymentDirectoryFromRunContext() - { - // Setup mocks - this.mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(TestRunDirectory); - this.mockFileUtility.Setup(fu => fu.GetNextIterationDirectoryName(TestRunDirectory, It.IsAny())) - .Returns(RootDeploymentDirectory); - - // Act. - this.deploymentUtility.CreateDeploymentDirectories(this.mockRunContext.Object); - - // Assert. - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(RootDeploymentDirectory), Times.Once); - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix)), Times.Once); - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentOutDirectorySuffix)), Times.Once); - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix), Environment.MachineName)), Times.Once); - } - - [TestMethod] - public void CreateDeploymentDirectoriesShouldCreateDefaultDeploymentDirectoryIfTestRunDirectoryIsNull() - { - // Setup mocks - this.mockRunContext.Setup(rc => rc.TestRunDirectory).Returns((string)null); - this.mockFileUtility.Setup(fu => fu.GetNextIterationDirectoryName(It.Is(s => s.Contains(TestRunDirectories.DefaultDeploymentRootDirectory)), It.IsAny())) - .Returns(RootDeploymentDirectory); - - // Act. - this.deploymentUtility.CreateDeploymentDirectories(this.mockRunContext.Object); - - // Assert. - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(RootDeploymentDirectory), Times.Once); - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix)), Times.Once); - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentOutDirectorySuffix)), Times.Once); - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix), Environment.MachineName)), Times.Once); - } - - [TestMethod] - public void CreateDeploymentDirectoriesShouldCreateDefaultDeploymentDirectoryIfRunContextIsNull() - { - // Setup mocks - this.mockFileUtility.Setup(fu => fu.GetNextIterationDirectoryName(It.Is(s => s.Contains(TestRunDirectories.DefaultDeploymentRootDirectory)), It.IsAny())) - .Returns(RootDeploymentDirectory); - - // Act. - this.deploymentUtility.CreateDeploymentDirectories(null); - - // Assert. - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(RootDeploymentDirectory), Times.Once); - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix)), Times.Once); - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentOutDirectorySuffix)), Times.Once); - this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix), Environment.MachineName)), Times.Once); - } - - #endregion - #region Deploy tests [TestMethod] diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DesktopReflectionUtilityTests.cs b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DesktopReflectionUtilityTests.cs new file mode 100644 index 0000000000..3986db4ebf --- /dev/null +++ b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DesktopReflectionUtilityTests.cs @@ -0,0 +1,116 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Utilities +{ + extern alias FrameworkV1; + + using System; + using System.Collections.Generic; + using System.Reflection; + + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; + + using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; + using CollectionAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert; + using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; + using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; + + [TestClass] +#pragma warning disable SA1649 // File name must match first type name + public class ReflectionUtilityTests +#pragma warning restore SA1649 // File name must match first type name + { + private ReflectionUtility reflectionUtility; + + public ReflectionUtilityTests() + { + this.reflectionUtility = new ReflectionUtility(); + } + + [TestMethod] + public void GetSpecificCustomAttributesOnAssemblyShouldReturnAllAttributes() + { + var asm = typeof(DummyTestClass).GetTypeInfo().Assembly; + + var attribs = this.reflectionUtility.GetCustomAttributes(asm, typeof(DummyAAttribute)); + + Assert.IsNotNull(attribs); + Assert.AreEqual(2, attribs.Length); + + var expectedAttribs = new string[] { "DummyA : a1", "DummyA : a2" }; + CollectionAssert.AreEqual(expectedAttribs, GetAttributeValuePairs(attribs)); + } + + internal static string[] GetAttributeValuePairs(object[] attributes) + { + var attribValuePairs = new List(); + foreach (var attrib in attributes) + { + if (attrib is DummySingleAAttribute) + { + var a = attrib as DummySingleAAttribute; + attribValuePairs.Add("DummySingleA : " + a.Value); + } + else if (attrib is DummyAAttribute) + { + var a = attrib as DummyAAttribute; + attribValuePairs.Add("DummyA : " + a.Value); + } + } + + return attribValuePairs.ToArray(); + } + + [DummyA("ba")] + public class DummyBaseTestClass + { + [DummyA("base")] + [DummySingleA("base")] + public virtual void DummyVTestMethod1() + { + } + + public void DummyBTestMethod2() + { + } + } + + [DummyA("a")] + public class DummyTestClass : DummyBaseTestClass + { + [DummyA("derived")] + [DummySingleA("derived")] + public override void DummyVTestMethod1() + { + } + + [DummySingleA("derived")] + public void DummyTestMethod2() + { + } + } + + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)] + public sealed class DummyAAttribute : Attribute + { + public DummyAAttribute(string foo) + { + this.Value = foo; + } + + public string Value { get; set; } + } + + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false)] + public class DummySingleAAttribute : Attribute + { + public DummySingleAAttribute(string foo) + { + this.Value = foo; + } + + public string Value { get; set; } + } + } +} diff --git a/test/UnitTests/PlatformServices.NetCore.Unit.Tests/AssemblyAttribute.cs b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/AssemblyAttribute.cs new file mode 100644 index 0000000000..e2e8aa5233 --- /dev/null +++ b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/AssemblyAttribute.cs @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using MSTestAdapter.PlatformServices.Tests.Services; +using MSTestAdapter.PlatformServices.Tests.Utilities; + +[assembly: ReflectionUtilityTests.DummyAAttribute("a1")] +[assembly: ReflectionUtilityTests.DummyAAttribute("a2")] + +[assembly: ReflectionOperationsTests.DummyAAttribute("a1")] +[assembly: ReflectionOperationsTests.DummyAAttribute("a2")] \ No newline at end of file diff --git a/test/UnitTests/PlatformServices.NetCore.Unit.Tests/PlatformServices.NetCore.Unit.Tests.csproj b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/PlatformServices.NetCore.Unit.Tests.csproj index d5d807f123..fd9d5671fc 100644 --- a/test/UnitTests/PlatformServices.NetCore.Unit.Tests/PlatformServices.NetCore.Unit.Tests.csproj +++ b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/PlatformServices.NetCore.Unit.Tests.csproj @@ -8,22 +8,30 @@ MSTestAdapter.PlatformServices.NetCore.UnitTests MSTestAdapter.PlatformServices.NetCore.UnitTests - netcoreapp1.0 + netcoreapp1.1 $(PackageTargetFallback);portable-net45+win8+wpa81+wp8 - + + + - + + + + + + + @@ -33,21 +41,18 @@ - true - true + FrameworkV2Extension - true - true - + diff --git a/test/UnitTests/PlatformServices.NetCore.Unit.Tests/Utilities/NetCoreDeploymentUtilityTests.cs b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/Utilities/NetCoreDeploymentUtilityTests.cs new file mode 100644 index 0000000000..36ab61f84c --- /dev/null +++ b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/Utilities/NetCoreDeploymentUtilityTests.cs @@ -0,0 +1,186 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace MSTestAdapter.PlatformServices.Tests.Utilities +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Reflection; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; + using Moq; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using MSTestAdapter.PlatformServices.Tests.Utilities; + + [TestClass] + public class NetCoreDeploymentUtilityTests + { + private const string TestRunDirectory = "C:\\temp\\testRunDirectory"; + private const string RootDeploymentDirectory = "C:\\temp\\testRunDirectory\\Deploy"; + private const string DefaultDeploymentItemPath = @"c:\temp"; + private const string DefaultDeploymentItemOutputDirectory = "out"; + + private Mock mockReflectionUtility; + private Mock mockFileUtility; + private Mock mockAssemblyUtility; + + private DeploymentUtility deploymentUtility; + + private Mock mockRunContext; + private Mock mocktestExecutionRecorder; + + private IList warnings; + + [TestInitialize] + public void TestInit() + { + this.mockReflectionUtility = new Mock(); + this.mockFileUtility = new Mock(); + this.mockAssemblyUtility = new Mock(); + this.warnings = new List(); + + this.deploymentUtility = new DeploymentUtility( + new DeploymentItemUtility(this.mockReflectionUtility.Object), + this.mockAssemblyUtility.Object, + this.mockFileUtility.Object); + + this.mockRunContext = new Mock(); + this.mocktestExecutionRecorder = new Mock(); + } + + #region Deploy tests + + [TestMethod] + public void DeployShouldReturnFalseWhenNoDeploymentItemsOnTestCase() + { + var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), "A"); + testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, null); + var testRunDirectories = new TestRunDirectories(RootDeploymentDirectory); + + this.mockFileUtility.Setup(fu => fu.DoesDirectoryExist(It.Is(s => !(s.EndsWith(".dll") || s.EndsWith(".config"))))).Returns(true); + this.mockFileUtility.Setup(fu => fu.DoesFileExist(It.IsAny())).Returns(true); + + Assert.IsFalse( + this.deploymentUtility.Deploy( + new List { testCase }, + testCase.Source, + this.mockRunContext.Object, + this.mocktestExecutionRecorder.Object, + testRunDirectories)); + } + + [TestMethod] + public void DeployShouldNotDeployIfOutputDirectoryIsInvalid() + { + TestRunDirectories testRunDirectories; + var assemblyFullPath = Assembly.GetEntryAssembly().Location; + var deploymentItemPath = "C:\\temp\\sample.dll"; + var deploymentItemOutputDirectory = "..\\..\\out"; + + var testCase = this.GetTestCaseAndTestRunDirectories(deploymentItemPath, deploymentItemOutputDirectory, out testRunDirectories); + + // Setup mocks. + this.mockFileUtility.Setup(fu => fu.DoesDirectoryExist(It.Is(s => !(s.EndsWith(".dll") || s.EndsWith(".config"))))).Returns(true); + this.mockFileUtility.Setup(fu => fu.DoesFileExist(It.IsAny())).Returns(true); + + // Act. + Assert.IsTrue( + this.deploymentUtility.Deploy( + new List { testCase }, + testCase.Source, + this.mockRunContext.Object, + this.mocktestExecutionRecorder.Object, + testRunDirectories)); + + // Assert. + string warning; + + this.mockFileUtility.Verify( + fu => + fu.CopyFileOverwrite( + It.Is(s => s.Contains(deploymentItemPath)), + It.IsAny(), + out warning), + Times.Never); + + // Verify the warning. + this.mocktestExecutionRecorder.Verify( + ter => + ter.SendMessage( + TestMessageLevel.Warning, + string.Format( + Resource.DeploymentErrorBadDeploymentItem, + deploymentItemPath, + deploymentItemOutputDirectory)), + Times.Once); + } + + [TestMethod] + public void DeployShouldDeployContentsOfADirectoryIfSpecified() + { + TestRunDirectories testRunDirectories; + var assemblyFullPath = Assembly.GetEntryAssembly().Location; + + var testCase = this.GetTestCaseAndTestRunDirectories(DefaultDeploymentItemPath, DefaultDeploymentItemOutputDirectory, out testRunDirectories); + var content1 = Path.Combine(DefaultDeploymentItemPath, "directoryContents.dll"); + var directoryContentFiles = new List { content1 }; + + // Setup mocks. + this.mockFileUtility.Setup(fu => fu.DoesDirectoryExist(It.Is(s => !(s.EndsWith(".dll") || s.EndsWith(".config"))))).Returns(true); + this.mockFileUtility.Setup(fu => fu.DoesFileExist(It.IsAny())).Returns(true); + this.mockFileUtility.Setup( + fu => fu.AddFilesFromDirectory(DefaultDeploymentItemPath, It.IsAny())).Returns(directoryContentFiles); + this.mockFileUtility.Setup( + fu => fu.AddFilesFromDirectory(DefaultDeploymentItemPath, It.IsAny>(), It.IsAny())).Returns(directoryContentFiles); + + // Act. + Assert.IsTrue( + this.deploymentUtility.Deploy( + new List { testCase }, + testCase.Source, + this.mockRunContext.Object, + this.mocktestExecutionRecorder.Object, + testRunDirectories)); + + // Assert. + string warning; + + this.mockFileUtility.Verify( + fu => + fu.CopyFileOverwrite( + It.Is(s => s.Contains(content1)), + It.IsAny(), + out warning), + Times.Once); + } + + #endregion + + #region private methods + + private TestCase GetTestCaseAndTestRunDirectories(string deploymentItemPath, string defaultDeploymentItemOutputDirectoryout, out TestRunDirectories testRunDirectories) + { + this.GetType(); + var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), typeof(DeploymentUtilityTests).GetTypeInfo().Assembly.Location); + var kvpArray = new[] + { + new KeyValuePair( + deploymentItemPath, + defaultDeploymentItemOutputDirectoryout) + }; + testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, kvpArray); + var currentExecutingFolder = Path.GetDirectoryName(typeof(DeploymentUtilityTests).GetTypeInfo().Assembly.Location); + + testRunDirectories = new TestRunDirectories(currentExecutingFolder); + + return testCase; + } + + #endregion + } +} diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Deployment/DeploymentItemTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Deployment/ns10DeploymentItemTests.cs similarity index 96% rename from test/UnitTests/PlatformServices.Desktop.Unit.Tests/Deployment/DeploymentItemTests.cs rename to test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Deployment/ns10DeploymentItemTests.cs index aa2be3801f..f3e59eba8c 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Deployment/DeploymentItemTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Deployment/ns10DeploymentItemTests.cs @@ -1,16 +1,19 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Deployment +namespace MSTestAdapter.PlatformServices.Tests.Deployment { +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; +#else extern alias FrameworkV1; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; - using Assert = FrameworkV1.Microsoft.VisualStudio.TestTools.UnitTesting.Assert; using TestClass = FrameworkV1.Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; using TestMethod = FrameworkV1.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; +#endif + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; [TestClass] public class DeploymentItemTests diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Deployment/TestRunDirectoriesTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Deployment/ns10TestRunDirectoriesTests.cs similarity index 88% rename from test/UnitTests/PlatformServices.Desktop.Unit.Tests/Deployment/TestRunDirectoriesTests.cs rename to test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Deployment/ns10TestRunDirectoriesTests.cs index fa7eaaac33..cc2f4b6739 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Deployment/TestRunDirectoriesTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Deployment/ns10TestRunDirectoriesTests.cs @@ -1,18 +1,20 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Deployment +namespace MSTestAdapter.PlatformServices.Tests.Deployment { +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; +#else extern alias FrameworkV1; - using System; - using System.IO; - - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; - using Assert = FrameworkV1.Microsoft.VisualStudio.TestTools.UnitTesting.Assert; using TestClass = FrameworkV1.Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; using TestMethod = FrameworkV1.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; +#endif + using System; + using System.IO; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; [TestClass] public class TestRunDirectoriesTests diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Extensions/ExceptionExtensionsTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Extensions/ns10ExceptionExtensionsTests.cs similarity index 91% rename from test/UnitTests/PlatformServices.Desktop.Unit.Tests/Extensions/ExceptionExtensionsTests.cs rename to test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Extensions/ns10ExceptionExtensionsTests.cs index 987ce0053f..088217afaa 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Extensions/ExceptionExtensionsTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Extensions/ns10ExceptionExtensionsTests.cs @@ -1,17 +1,20 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Extensions +namespace MSTestAdapter.PlatformServices.Tests.Extensions { +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; +#else extern alias FrameworkV1; - using System; - - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; - using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; +#endif + using System; + + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; [TestClass] public class ExceptionExtensionsTests diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/MSTestAdapterSettingsTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Services/ns10MSTestAdapterSettingsTests.cs similarity index 96% rename from test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/MSTestAdapterSettingsTests.cs rename to test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Services/ns10MSTestAdapterSettingsTests.cs index e7cd44a483..184f345b82 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/MSTestAdapterSettingsTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Services/ns10MSTestAdapterSettingsTests.cs @@ -3,9 +3,19 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests { +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; +#else extern alias FrameworkV1; extern alias FrameworkV2; + using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; + using CollectionAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert; + using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; + using TestCleanup = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute; + using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; +#endif + using System; using System.Collections.Generic; using System.IO; @@ -16,14 +26,11 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; using TestUtilities; - using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; - using CollectionAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert; - using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; - using TestCleanup = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute; - using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; - [TestClass] +#pragma warning disable SA1649 // File name must match first type name public class MSTestAdapterSettingsTests + +#pragma warning restore SA1649 // File name must match first type name { [TestCleanup] public void Cleanup() @@ -31,7 +38,7 @@ public void Cleanup() MSTestSettingsProvider.Reset(); } - #region ResolveEnvironmentVariableAndReturnFullPathIfExist tests. +#region ResolveEnvironmentVariableAndReturnFullPathIfExist tests. [TestMethod] public void ResolveEnvironmentVariableShouldResolvePathWhenPassedAbsolutePath() @@ -107,7 +114,7 @@ public void ResolveEnvironmentVariableShouldResolvePathWhenPassedRelativePath() // instead of returning "C:\unitTesting\MsTest\Adapter", it will return "(Drive from where test is running):\MsTest\Adapter", // because path is starting with "\" // this is how Path.GetFullPath works - string currentDirectory = Environment.CurrentDirectory; + string currentDirectory = Directory.GetCurrentDirectory(); string currentDrive = currentDirectory.Split('\\').First() + "\\"; string expectedResult = Path.Combine(currentDrive, @"MsTest\Adapter"); @@ -148,9 +155,9 @@ public void ResolveEnvironmentVariableShouldReturnFalseForInvalidPath() Assert.IsNull(result); } - #endregion +#endregion - #region GetDirectoryListWithRecursiveProperty tests. +#region GetDirectoryListWithRecursiveProperty tests. [TestMethod] public void GetDirectoryListWithRecursivePropertyShouldReadRunSettingCorrectly() @@ -176,9 +183,9 @@ public void GetDirectoryListWithRecursivePropertyShouldReadRunSettingCorrectly() } } - #endregion +#endregion - #region ToSettings tests. +#region ToSettings tests. [TestMethod] public void ToSettingsShouldNotThrowExceptionWhenRunSettingsXmlUnderTagMSTestv2IsWrong() @@ -223,9 +230,9 @@ public void ToSettingsShouldThrowExceptionWhenRunSettingsXmlIsWrong() ActionUtility.ActionShouldThrowExceptionOfType(shouldThrowException, typeof(SettingsException)); } - #endregion +#endregion - #region DeploymentEnabled tests. +#region DeploymentEnabled tests. [TestMethod] public void DeploymentEnabledIsByDefaultTrueWhenNotSpecified() @@ -254,9 +261,9 @@ public void DeploymentEnabledShouldBeConsumedFromRunSettingsWhenSpecified() Assert.AreEqual(false, adapterSettings.DeploymentEnabled); } - #endregion +#endregion - #region DeployTestSourceDependencies tests +#region DeployTestSourceDependencies tests [TestMethod] public void DeployTestSourceDependenciesIsEnabledByDefault() @@ -299,7 +306,7 @@ public void DeployTestSourceDependenciesWhenTrue() Assert.AreEqual(true, adapterSettings.DeployTestSourceDependencies); } - #endregion +#endregion } public class TestableMSTestAdapterSettings : MSTestAdapterSettings diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Utilities/ns10DeploymentUtilityTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Utilities/ns10DeploymentUtilityTests.cs new file mode 100644 index 0000000000..8fc03c6c40 --- /dev/null +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Utilities/ns10DeploymentUtilityTests.cs @@ -0,0 +1,126 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace MSTestAdapter.PlatformServices.Tests.Utilities +{ +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; +#else + extern alias FrameworkV1; + extern alias FrameworkV2; + + using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; + using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; + using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; + using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; +#endif + + using System; + using System.Collections.Generic; + using System.IO; + using System.Reflection; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; + using Moq; + + [TestClass] +#pragma warning disable SA1649 // File name must match first type name + public class DeploymentUtilityTests +#pragma warning restore SA1649 // File name must match first type name + { + private const string TestRunDirectory = "C:\\temp\\testRunDirectory"; + private const string RootDeploymentDirectory = "C:\\temp\\testRunDirectory\\Deploy"; + private const string DefaultDeploymentItemPath = @"c:\temp"; + private const string DefaultDeploymentItemOutputDirectory = "out"; + + private Mock mockReflectionUtility; + private Mock mockFileUtility; + + private Mock mockAssemblyUtility; + + private DeploymentUtility deploymentUtility; + + private Mock mockRunContext; + private Mock mocktestExecutionRecorder; + + private IList warnings; + + [TestInitialize] + public void TestInit() + { + this.mockReflectionUtility = new Mock(); + this.mockFileUtility = new Mock(); + this.mockAssemblyUtility = new Mock(); + this.warnings = new List(); + + this.deploymentUtility = new DeploymentUtility( + new DeploymentItemUtility(this.mockReflectionUtility.Object), + this.mockAssemblyUtility.Object, + this.mockFileUtility.Object); + + this.mockRunContext = new Mock(); + this.mocktestExecutionRecorder = new Mock(); + } + +#region CreateDeploymentDirectories tests + + [TestMethod] + public void CreateDeploymentDirectoriesShouldCreateDeploymentDirectoryFromRunContext() + { + // Setup mocks + this.mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(TestRunDirectory); + this.mockFileUtility.Setup(fu => fu.GetNextIterationDirectoryName(TestRunDirectory, It.IsAny())) + .Returns(RootDeploymentDirectory); + + // Act. + this.deploymentUtility.CreateDeploymentDirectories(this.mockRunContext.Object); + + // Assert. + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(RootDeploymentDirectory), Times.Once); + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix)), Times.Once); + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(RootDeploymentDirectory), Times.Once); + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix), Environment.MachineName)), Times.Once); + } + + [TestMethod] + public void CreateDeploymentDirectoriesShouldCreateDefaultDeploymentDirectoryIfTestRunDirectoryIsNull() + { + // Setup mocks + this.mockRunContext.Setup(rc => rc.TestRunDirectory).Returns((string)null); + this.mockFileUtility.Setup(fu => fu.GetNextIterationDirectoryName(It.Is(s => s.Contains(TestRunDirectories.DefaultDeploymentRootDirectory)), It.IsAny())) + .Returns(RootDeploymentDirectory); + + // Act. + this.deploymentUtility.CreateDeploymentDirectories(this.mockRunContext.Object); + + // Assert. + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(RootDeploymentDirectory), Times.Once); + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix)), Times.Once); + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(RootDeploymentDirectory), Times.Once); + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix), Environment.MachineName)), Times.Once); + } + + [TestMethod] + public void CreateDeploymentDirectoriesShouldCreateDefaultDeploymentDirectoryIfRunContextIsNull() + { + // Setup mocks + this.mockFileUtility.Setup(fu => fu.GetNextIterationDirectoryName(It.Is(s => s.Contains(TestRunDirectories.DefaultDeploymentRootDirectory)), It.IsAny())) + .Returns(RootDeploymentDirectory); + + // Act. + this.deploymentUtility.CreateDeploymentDirectories(null); + + // Assert. + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(RootDeploymentDirectory), Times.Once); + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix)), Times.Once); + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(RootDeploymentDirectory), Times.Once); + this.mockFileUtility.Verify(fu => fu.CreateDirectoryIfNotExists(Path.Combine(Path.Combine(RootDeploymentDirectory, TestRunDirectories.DeploymentInDirectorySuffix), Environment.MachineName)), Times.Once); + } + +#endregion + } +} diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/FileUtilityTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Utilities/ns10FileUtilityTests.cs similarity index 97% rename from test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/FileUtilityTests.cs rename to test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Utilities/ns10FileUtilityTests.cs index 45efa6f766..ad9a367823 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/FileUtilityTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/Utilities/ns10FileUtilityTests.cs @@ -1,20 +1,25 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Utilities +namespace MSTestAdapter.PlatformServices.Tests.Utilities { +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; +#else extern alias FrameworkV1; - using System; - using System.IO; - using System.Linq; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; - using Moq; using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; using CollectionAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert; using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; +#endif + + using System; + using System.IO; + using System.Linq; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; + using Moq; [TestClass] public class FileUtilityTests @@ -42,7 +47,7 @@ public void ReplaceInvalidFileNameCharactersShouldReplaceInvalidChars() Assert.AreEqual("galaxy__far_far_away", this.fileUtility.Object.ReplaceInvalidFileNameCharacters(fileName)); } - #region AddFilesFromDirectory tests +#region AddFilesFromDirectory tests [TestMethod] public void AddFilesInADirectoryShouldReturnAllTopLevelFilesInADirectory() @@ -201,6 +206,6 @@ private void SetupMockFileAPIs(string[] files) }); } - #endregion +#endregion } } diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10DiaSessionOperationsTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10DiaSessionOperationsTests.cs index 5c5e1b456c..1721f73a10 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10DiaSessionOperationsTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10DiaSessionOperationsTests.cs @@ -3,7 +3,7 @@ namespace MSTestAdapter.PlatformServices.Tests.Services { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 using Microsoft.VisualStudio.TestTools.UnitTesting; #else extern alias FrameworkV1; diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10FileOperationsTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10FileOperationsTests.cs index 10987342c1..0cd2bb3157 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10FileOperationsTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10FileOperationsTests.cs @@ -3,7 +3,7 @@ namespace MSTestAdapter.PlatformServices.Tests.Services { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 using Microsoft.VisualStudio.TestTools.UnitTesting; #else extern alias FrameworkV1; @@ -18,8 +18,7 @@ namespace MSTestAdapter.PlatformServices.Tests.Services using System.IO; using System.Reflection; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; - using MSTestAdapter.TestUtilities; -#pragma warning disable SA1649 // SA1649FileNameMustMatchTypeName + using MSTestAdapter.TestUtilities; [TestClass] public class FileOperationsTests diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10ReflectionOperationsTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10ReflectionOperationsTests.cs index c6b0422a9b..4c9bdd038c 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10ReflectionOperationsTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10ReflectionOperationsTests.cs @@ -3,7 +3,7 @@ namespace MSTestAdapter.PlatformServices.Tests.Services { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 using Microsoft.VisualStudio.TestTools.UnitTesting; #else extern alias FrameworkV1; @@ -19,8 +19,6 @@ namespace MSTestAdapter.PlatformServices.Tests.Services using System.Reflection; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; -#pragma warning disable SA1649 // SA1649FileNameMustMatchTypeName - [TestClass] public class ReflectionOperationsTests { diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10SettingsProviderTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10SettingsProviderTests.cs index 04704db378..0920ce5412 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10SettingsProviderTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10SettingsProviderTests.cs @@ -16,8 +16,6 @@ namespace MSTestAdapter.PlatformServices.Tests.Services using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Moq; -#pragma warning disable SA1649 // SA1649FileNameMustMatchTypeName - [TestClass] public class SettingsProviderTests { diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs index 6e02a56289..c063c1f42e 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs @@ -3,7 +3,7 @@ namespace MSTestAdapter.PlatformServices.Tests.Services { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 using Microsoft.VisualStudio.TestTools.UnitTesting; #else extern alias FrameworkV1; @@ -26,8 +26,6 @@ namespace MSTestAdapter.PlatformServices.Tests.Services using Moq; using ITestMethod = Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel.ITestMethod; -#pragma warning disable SA1649 // SA1649FileNameMustMatchTypeName - [TestClass] public class TestContextImplementationTests { diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestSourceHostTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestSourceHostTests.cs index e73fec574f..6d8685f1db 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestSourceHostTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestSourceHostTests.cs @@ -3,7 +3,7 @@ namespace MSTestAdapter.PlatformServices.Tests.Services { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 using Microsoft.VisualStudio.TestTools.UnitTesting; #else extern alias FrameworkV1; diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestSourceTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestSourceTests.cs index 6d4ac2882c..66657e8e60 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestSourceTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestSourceTests.cs @@ -3,7 +3,7 @@ namespace MSTestAdapter.PlatformServices.Tests.Services { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 using Microsoft.VisualStudio.TestTools.UnitTesting; #else extern alias FrameworkV1; @@ -20,8 +20,6 @@ namespace MSTestAdapter.PlatformServices.Tests.Services using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; -#pragma warning disable SA1649 // SA1649FileNameMustMatchTypeName - [TestClass] public class TestSourceTests { diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10ThreadOperationsTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10ThreadOperationsTests.cs index 10f9135e75..0dd15d28c7 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10ThreadOperationsTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10ThreadOperationsTests.cs @@ -3,7 +3,7 @@ namespace MSTestAdapter.PlatformServices.Tests.Services { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 using Microsoft.VisualStudio.TestTools.UnitTesting; #else extern alias FrameworkV1; diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopSettingsProviderTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/Services/ns13MSTestSettingsProviderTests.cs similarity index 93% rename from test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopSettingsProviderTests.cs rename to test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/Services/ns13MSTestSettingsProviderTests.cs index a314ae8594..bf7401202f 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopSettingsProviderTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/Services/ns13MSTestSettingsProviderTests.cs @@ -3,9 +3,18 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Services { +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; +#else extern alias FrameworkV1; extern alias FrameworkV2; + using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; + using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; + using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; + using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; +#endif + using System; using System.IO; using System.Xml; @@ -15,13 +24,10 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Services using MSTestAdapter.TestUtilities; - using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; - using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; - using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; - using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; - [TestClass] +#pragma warning disable SA1649 // File name must match first type name public class DesktopSettingsProviderTests +#pragma warning restore SA1649 // File name must match first type name { private MSTestSettingsProvider settingsProvider; diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/Services/ns13TestDeploymentTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/Services/ns13TestDeploymentTests.cs new file mode 100644 index 0000000000..092bebcfd8 --- /dev/null +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/Services/ns13TestDeploymentTests.cs @@ -0,0 +1,552 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace MSTestAdapter.PlatformServices.Tests.Services +{ + extern alias FrameworkV2Extension; +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; +#else + extern alias FrameworkV1; + extern alias FrameworkV2; + + using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; + using CollectionAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert; + using Ignore = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.IgnoreAttribute; + using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; + using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; + using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; +#endif + + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Reflection; + using System.Xml; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + using Moq; + using MSTestAdapter.PlatformServices.Tests.Utilities; + + using TestFrameworkV2Extension = FrameworkV2Extension::Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestDeploymentTests + { + private const string DefaultDeploymentItemPath = @"c:\temp"; + private const string DefaultDeploymentItemOutputDirectory = "out"; + + private Mock mockReflectionUtility; + private Mock mockFileUtility; + + private IList warnings; + + [TestInitialize] + public void TestInit() + { + this.mockReflectionUtility = new Mock(); + this.mockFileUtility = new Mock(); + this.warnings = new List(); + + // Reset adapter settings. + MSTestSettingsProvider.Reset(); + } + +#region GetDeploymentItems tests. + + [TestMethod] + public void GetDeploymentItemsReturnsNullWhenNoDeploymentItems() + { + var methodInfo = + typeof(TestDeploymentTests).GetMethod("GetDeploymentItemsReturnsNullWhenNoDeploymentItems"); + + Assert.IsNull(new TestDeployment().GetDeploymentItems(methodInfo, typeof(TestDeploymentTests), this.warnings)); + } + + [TestMethod] + public void GetDeploymentItemsReturnsDeploymentItems() + { + // Arrange. + var testDeployment = new TestDeployment(new DeploymentItemUtility(this.mockReflectionUtility.Object), null, null); + + // setup mocks + var methodLevelDeploymentItems = new[] + { + new KeyValuePair( + DefaultDeploymentItemPath, + DefaultDeploymentItemOutputDirectory) + }; + var classLevelDeploymentItems = new[] + { + new KeyValuePair( + DefaultDeploymentItemPath + "\\temp2", + DefaultDeploymentItemOutputDirectory) + }; + var memberInfo = + typeof(TestDeploymentTests).GetMethod( + "GetDeploymentItemsReturnsDeploymentItems"); + this.SetupDeploymentItems(memberInfo, methodLevelDeploymentItems); + this.SetupDeploymentItems(typeof(TestDeploymentTests).GetTypeInfo(), classLevelDeploymentItems); + + // Act. + var deploymentItems = testDeployment.GetDeploymentItems(memberInfo, typeof(TestDeploymentTests), this.warnings); + + // Assert. + var expectedDeploymentItems = new KeyValuePair[] + { + new KeyValuePair( + DefaultDeploymentItemPath, + DefaultDeploymentItemOutputDirectory), + new KeyValuePair( + DefaultDeploymentItemPath + "\\temp2", + DefaultDeploymentItemOutputDirectory) + }; + + CollectionAssert.AreEqual(expectedDeploymentItems, deploymentItems.ToArray()); + } + +#endregion + +#region Cleanup tests + + [TestMethod] + public void CleanupShouldNotDeleteDirectoriesIfRunDirectoiresIsNull() + { + var testDeployment = new TestDeployment(null, null, this.mockFileUtility.Object); + + testDeployment.Cleanup(); + + this.mockFileUtility.Verify(fu => fu.DeleteDirectories(It.IsAny()), Times.Never); + } + + [TestMethod] + public void CleanupShouldNotDeleteDirectoriesIfRunSettingsSpecifiesSo() + { + string runSettingxml = + @"False"; + StringReader stringReader = new StringReader(runSettingxml); + XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); + MSTestSettingsProvider mstestSettingsProvider = new MSTestSettingsProvider(); + mstestSettingsProvider.Load(reader); + + TestRunDirectories testRunDirectories; + var testCase = this.GetTestCase(typeof(TestDeploymentTests).GetTypeInfo().Assembly.Location); + + // Setup mocks. + var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); + + var mockRunContext = new Mock(); + mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(testRunDirectories.RootDeploymentDirectory); + + Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); + + testDeployment.Cleanup(); + + this.mockFileUtility.Verify(fu => fu.DeleteDirectories(It.IsAny()), Times.Never); + } + + [TestMethod] + public void CleanupShouldDeleteRootDeploymentDirectory() + { + TestRunDirectories testRunDirectories; + var testCase = this.GetTestCase(typeof(DeploymentUtilityTests).GetTypeInfo().Assembly.Location); + + // Setup mocks. + var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); + + var mockRunContext = new Mock(); + mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(testRunDirectories.RootDeploymentDirectory); + + Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); + + // Act. + testDeployment.Cleanup(); + + this.mockFileUtility.Verify(fu => fu.DeleteDirectories(testRunDirectories.RootDeploymentDirectory), Times.Once); + } + +#endregion + +#region GetDeploymentDirectory tests + + [TestMethod] + public void GetDeploymentDirectoryShouldReturnNullIfDeploymentDirectoryIsNull() + { + Assert.IsNull(new TestDeployment().GetDeploymentDirectory()); + } + + [TestMethod] + public void GetDeploymentDirectoryShouldReturnDeploymentOutputDirectory() + { + TestRunDirectories testRunDirectories; + var testCase = this.GetTestCase(typeof(TestDeploymentTests).GetTypeInfo().Assembly.Location); + + // Setup mocks. + var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); + + var mockRunContext = new Mock(); + mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(testRunDirectories.RootDeploymentDirectory); + + Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); + + // Act. + Assert.AreEqual(testRunDirectories.OutDirectory, testDeployment.GetDeploymentDirectory()); + } + +#endregion + +#region Deploy tests + + [TestMethod] + public void DeployShouldReturnFalseWhenDeploymentEnabledSetToFalseButHasDeploymentItems() + { + var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), "A"); + var kvparray = new[] + { + new KeyValuePair( + DefaultDeploymentItemPath, + DefaultDeploymentItemOutputDirectory) + }; + testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, kvparray); + + var testDeployment = new TestDeployment( + new DeploymentItemUtility(this.mockReflectionUtility.Object), + new DeploymentUtility(), + this.mockFileUtility.Object); + + string runSettingxml = + @"False"; + StringReader stringReader = new StringReader(runSettingxml); + XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); + MSTestSettingsProvider mstestSettingsProvider = new MSTestSettingsProvider(); + mstestSettingsProvider.Load(reader); + + // Deployment should not happen + Assert.IsFalse(testDeployment.Deploy(new List { testCase }, null, null)); + + // Deplyment directories should not be created + Assert.IsNull(testDeployment.GetDeploymentDirectory()); + } + + [TestMethod] + public void DeployShouldReturnFalseWhenDeploymentEnabledSetToFalseAndHasNoDeploymentItems() + { + var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), "A"); + testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, null); + var testDeployment = new TestDeployment( + new DeploymentItemUtility(this.mockReflectionUtility.Object), + new DeploymentUtility(), + this.mockFileUtility.Object); + + string runSettingxml = + @"False"; + StringReader stringReader = new StringReader(runSettingxml); + XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); + MSTestSettingsProvider mstestSettingsProvider = new MSTestSettingsProvider(); + mstestSettingsProvider.Load(reader); + + // Deployment should not happen + Assert.IsFalse(testDeployment.Deploy(new List { testCase }, null, null)); + + // Deployment directories should get created + Assert.IsNotNull(testDeployment.GetDeploymentDirectory()); + } + + [TestMethod] + public void DeployShouldReturnFalseWhenDeploymentEnabledSetToTrueButHasNoDeploymentItems() + { + var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), "A"); + testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, null); + var testDeployment = new TestDeployment( + new DeploymentItemUtility(this.mockReflectionUtility.Object), + new DeploymentUtility(), + this.mockFileUtility.Object); + + string runSettingxml = + @"True"; + StringReader stringReader = new StringReader(runSettingxml); + XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); + MSTestSettingsProvider mstestSettingsProvider = new MSTestSettingsProvider(); + mstestSettingsProvider.Load(reader); + + // Deployment should not happen + Assert.IsFalse(testDeployment.Deploy(new List { testCase }, null, null)); + + // Deployment directories should get created + Assert.IsNotNull(testDeployment.GetDeploymentDirectory()); + } + + // [Todo] This test has to have mocks. It actually deploys stuff and we cannot assume that all the dependencies get copied over to bin\debug. + [TestMethod] + [Ignore] + public void DeployShouldReturnTrueWhenDeploymentEnabledSetToTrueAndHasDeploymentItems() + { + var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), typeof(TestDeploymentTests).GetTypeInfo().Assembly.Location); + var kvpArray = new[] + { + new KeyValuePair( + DefaultDeploymentItemPath, + DefaultDeploymentItemOutputDirectory) + }; + testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, kvpArray); + var testDeployment = new TestDeployment( + new DeploymentItemUtility(this.mockReflectionUtility.Object), + new DeploymentUtility(), + this.mockFileUtility.Object); + + string runSettingxml = + @"True"; + StringReader stringReader = new StringReader(runSettingxml); + XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); + MSTestSettingsProvider mstestSettingsProvider = new MSTestSettingsProvider(); + mstestSettingsProvider.Load(reader); + + // Deployment should happen + Assert.IsTrue(testDeployment.Deploy(new List { testCase }, null, new Mock().Object)); + + // Deployment directories should get created + Assert.IsNotNull(testDeployment.GetDeploymentDirectory()); + } + +#endregion + +#region GetDeploymentInformation tests + + [TestMethod] + public void GetDeploymentInformationShouldReturnAppBaseDirectoryIfRunDirectoryIsNull() + { + TestDeployment.Reset(); + var properties = TestDeployment.GetDeploymentInformation(typeof(TestDeploymentTests).GetTypeInfo().Assembly.Location); + + var applicationBaseDirectory = Path.GetDirectoryName(typeof(TestDeploymentTests).GetTypeInfo().Assembly.Location); + var expectedProperties = new Dictionary + { + { + TestContextPropertyStrings.TestRunDirectory, + applicationBaseDirectory + }, + { + TestContextPropertyStrings.DeploymentDirectory, + applicationBaseDirectory + }, + { + TestContextPropertyStrings.ResultsDirectory, + applicationBaseDirectory + }, + { + TestContextPropertyStrings + .TestRunResultsDirectory, + applicationBaseDirectory + }, + { + TestContextPropertyStrings + .TestResultsDirectory, + applicationBaseDirectory + }, + { + TestContextPropertyStrings.TestDir, + applicationBaseDirectory + }, + { + TestContextPropertyStrings.TestDeploymentDir, + applicationBaseDirectory + }, + { + TestContextPropertyStrings.TestLogsDir, + applicationBaseDirectory + } + }; + Assert.IsNotNull(properties); + CollectionAssert.AreEqual(expectedProperties.ToList(), properties.ToList()); + } + + [TestMethod] + public void GetDeploymentInformationShouldReturnRunDirectoryInformationIfSourceIsNull() + { + // Arrange. + TestRunDirectories testRunDirectories; + var testCase = this.GetTestCase(typeof(TestDeploymentTests).GetTypeInfo().Assembly.Location); + + // Setup mocks. + var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); + + var mockRunContext = new Mock(); + mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(testRunDirectories.RootDeploymentDirectory); + + Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); + + // Act. + var properties = TestDeployment.GetDeploymentInformation(null); + + // Assert. + var expectedProperties = new Dictionary + { + { + TestContextPropertyStrings.TestRunDirectory, + testRunDirectories.RootDeploymentDirectory + }, + { + TestContextPropertyStrings.DeploymentDirectory, + testRunDirectories.OutDirectory + }, + { + TestContextPropertyStrings.ResultsDirectory, + testRunDirectories.InDirectory + }, + { + TestContextPropertyStrings + .TestRunResultsDirectory, + testRunDirectories.InMachineNameDirectory + }, + { + TestContextPropertyStrings + .TestResultsDirectory, + testRunDirectories.InDirectory + }, + { + TestContextPropertyStrings.TestDir, + testRunDirectories.RootDeploymentDirectory + }, + { + TestContextPropertyStrings.TestDeploymentDir, + testRunDirectories.OutDirectory + }, + { + TestContextPropertyStrings.TestLogsDir, + testRunDirectories.InMachineNameDirectory + } + }; + + Assert.IsNotNull(properties); + CollectionAssert.AreEqual(expectedProperties.ToList(), properties.ToList()); + } + + [TestMethod] + public void GetDeploymentInformationShouldReturnRunDirectoryInformationIfSourceIsNotNull() + { + // Arrange. + TestRunDirectories testRunDirectories; + var testCase = this.GetTestCase(typeof(TestDeploymentTests).GetTypeInfo().Assembly.Location); + + // Setup mocks. + var testDeployment = this.CreateAndSetupDeploymentRelatedUtilities(out testRunDirectories); + + var mockRunContext = new Mock(); + mockRunContext.Setup(rc => rc.TestRunDirectory).Returns(testRunDirectories.RootDeploymentDirectory); + + Assert.IsTrue(testDeployment.Deploy(new List { testCase }, mockRunContext.Object, new Mock().Object)); + + // Act. + var properties = TestDeployment.GetDeploymentInformation(typeof(TestDeploymentTests).GetTypeInfo().Assembly.Location); + + // Assert. + var expectedProperties = new Dictionary + { + { + TestContextPropertyStrings.TestRunDirectory, + testRunDirectories.RootDeploymentDirectory + }, + { + TestContextPropertyStrings.DeploymentDirectory, + testRunDirectories.OutDirectory + }, + { + TestContextPropertyStrings.ResultsDirectory, + testRunDirectories.InDirectory + }, + { + TestContextPropertyStrings + .TestRunResultsDirectory, + testRunDirectories.InMachineNameDirectory + }, + { + TestContextPropertyStrings + .TestResultsDirectory, + testRunDirectories.InDirectory + }, + { + TestContextPropertyStrings.TestDir, + testRunDirectories.RootDeploymentDirectory + }, + { + TestContextPropertyStrings.TestDeploymentDir, + testRunDirectories.OutDirectory + }, + { + TestContextPropertyStrings.TestLogsDir, + testRunDirectories.InMachineNameDirectory + } + }; + + Assert.IsNotNull(properties); + CollectionAssert.AreEqual(expectedProperties.ToList(), properties.ToList()); + } + +#endregion + +#region private methods + + private void SetupDeploymentItems(MemberInfo memberInfo, KeyValuePair[] deploymentItems) + { + var deploymentItemAttributes = new List(); + + foreach (var deploymentItem in deploymentItems) + { + deploymentItemAttributes.Add(new TestFrameworkV2Extension.DeploymentItemAttribute(deploymentItem.Key, deploymentItem.Value)); + } + + this.mockReflectionUtility.Setup( + ru => + ru.GetCustomAttributes( + memberInfo, + typeof(TestFrameworkV2Extension.DeploymentItemAttribute))).Returns((object[])deploymentItemAttributes.ToArray()); + } + + private TestCase GetTestCase(string source) + { + var testCase = new TestCase("A.C.M", new System.Uri("executor://testExecutor"), source); + var kvpArray = new[] + { + new KeyValuePair( + DefaultDeploymentItemPath, + DefaultDeploymentItemOutputDirectory) + }; + testCase.SetPropertyValue(DeploymentItemUtilityTests.DeploymentItemsProperty, kvpArray); + + return testCase; + } + + private TestDeployment CreateAndSetupDeploymentRelatedUtilities(out TestRunDirectories testRunDirectories) + { + var currentExecutingFolder = Path.GetDirectoryName(typeof(TestDeploymentTests).GetTypeInfo().Assembly.Location); + + testRunDirectories = new TestRunDirectories(currentExecutingFolder); + + this.mockFileUtility.Setup(fu => fu.DoesDirectoryExist(It.Is(s => !s.EndsWith(".dll")))).Returns(true); + this.mockFileUtility.Setup(fu => fu.DoesFileExist(It.IsAny())).Returns(true); + var mockAssemblyUtility = new Mock(); +#if !NETCOREAPP1_1 + mockAssemblyUtility.Setup( + au => au.GetFullPathToDependentAssemblies(It.IsAny(), It.IsAny(), out this.warnings)) + .Returns(new string[] { }); + mockAssemblyUtility.Setup( + au => au.GetSatelliteAssemblies(It.IsAny())) + .Returns(new List { }); +#endif + this.mockFileUtility.Setup(fu => fu.GetNextIterationDirectoryName(It.IsAny(), It.IsAny())) + .Returns(testRunDirectories.RootDeploymentDirectory); + + var deploymentItemUtility = new DeploymentItemUtility(this.mockReflectionUtility.Object); + + return new TestDeployment( + deploymentItemUtility, + new DeploymentUtility(deploymentItemUtility, mockAssemblyUtility.Object, this.mockFileUtility.Object), + this.mockFileUtility.Object); + } +#endregion + } +} diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DeploymentItemUtilityTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/Utilities/ns13DeploymentItemUtilityTests.cs similarity index 96% rename from test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DeploymentItemUtilityTests.cs rename to test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/Utilities/ns13DeploymentItemUtilityTests.cs index 59bd405eef..83f29aac3f 100644 --- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Utilities/DeploymentItemUtilityTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/Utilities/ns13DeploymentItemUtilityTests.cs @@ -1,11 +1,24 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Utilities +namespace MSTestAdapter.PlatformServices.Tests.Utilities { + extern alias FrameworkV2Extension; + +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; +#else extern alias FrameworkV1; extern alias FrameworkV2; - extern alias FrameworkV2DesktopExtension; + + using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; + using CollectionAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert; + using StringAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert; + using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; + using TestFrameworkV2 = FrameworkV2::Microsoft.VisualStudio.TestTools.UnitTesting; + using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; + using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; +#endif using System.Collections.Generic; using System.Linq; @@ -18,17 +31,12 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Utilities using Moq; - using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; - using CollectionAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert; - using StringAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert; - using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; - using TestFrameworkV2 = FrameworkV2::Microsoft.VisualStudio.TestTools.UnitTesting; - using TestFrameworkV2Extension = FrameworkV2DesktopExtension::Microsoft.VisualStudio.TestTools.UnitTesting; - using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; - using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; + using TestFrameworkV2Extension = FrameworkV2Extension::Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] +#pragma warning disable SA1649 // File name must match first type name public class DeploymentItemUtilityTests +#pragma warning restore SA1649 // File name must match first type name { internal static readonly TestProperty DeploymentItemsProperty = TestProperty.Register( "MSTestDiscoverer.DeploymentItems", @@ -52,7 +60,7 @@ public void TestInit() this.warnings = new List(); } - #region GetClassLevelDeploymentItems tests +#region GetClassLevelDeploymentItems tests [TestMethod] public void GetClassLevelDeploymentItemsShouldReturnEmptyListWhenNoDeploymentItems() @@ -72,7 +80,7 @@ public void GetClassLevelDeploymentItemsShouldReturnADeploymentItem() this.defaultDeploymentItemPath, this.defaultDeploymentItemOutputDirectory) }; - this.SetupDeploymentItems(typeof(DeploymentItemUtilityTests), kvpArray); + this.SetupDeploymentItems(typeof(DeploymentItemUtilityTests).GetTypeInfo(), kvpArray); var deploymentItems = this.deploymentItemUtility.GetClassLevelDeploymentItems(typeof(DeploymentItemUtilityTests), this.warnings); var expectedDeploymentItems = new DeploymentItem[] @@ -96,7 +104,7 @@ public void GetClassLevelDeploymentItemsShouldReturnMoreThanOneDeploymentItems() this.defaultDeploymentItemPath + "\\temp2", this.defaultDeploymentItemOutputDirectory) }; - this.SetupDeploymentItems(typeof(DeploymentItemUtilityTests), deploymentItemAttributes); + this.SetupDeploymentItems(typeof(DeploymentItemUtilityTests).GetTypeInfo(), deploymentItemAttributes); var deploymentItems = this.deploymentItemUtility.GetClassLevelDeploymentItems( @@ -128,7 +136,7 @@ public void GetClassLevelDeploymentItemsShouldNotReturnDuplicateDeploymentItemEn this.defaultDeploymentItemPath, this.defaultDeploymentItemOutputDirectory) }; - this.SetupDeploymentItems(typeof(DeploymentItemUtilityTests), deploymentItemAttributes); + this.SetupDeploymentItems(typeof(DeploymentItemUtilityTests).GetTypeInfo(), deploymentItemAttributes); var deploymentItems = this.deploymentItemUtility.GetClassLevelDeploymentItems( @@ -157,7 +165,7 @@ public void GetClassLevelDeploymentItemsShouldReportWarningsForInvalidDeployment null, this.defaultDeploymentItemOutputDirectory) }; - this.SetupDeploymentItems(typeof(DeploymentItemUtilityTests), deploymentItemAttributes); + this.SetupDeploymentItems(typeof(DeploymentItemUtilityTests).GetTypeInfo(), deploymentItemAttributes); var deploymentItems = this.deploymentItemUtility.GetClassLevelDeploymentItems(typeof(DeploymentItemUtilityTests), this.warnings); @@ -170,12 +178,12 @@ public void GetClassLevelDeploymentItemsShouldReportWarningsForInvalidDeployment CollectionAssert.AreEqual(expectedDeploymentItems, deploymentItems.ToArray()); Assert.AreEqual(1, this.warnings.Count); - TestFrameworkV2.StringAssert.Contains(this.warnings.ToArray()[0], Resource.DeploymentItemPathCannotBeNullOrEmpty); + StringAssert.Contains(this.warnings.ToArray()[0], Resource.DeploymentItemPathCannotBeNullOrEmpty); } #endregion - #region GetDeploymentItems tests +#region GetDeploymentItems tests [TestMethod] public void GetDeploymentItemsShouldReturnNullOnNoDeploymentItems() @@ -339,9 +347,9 @@ public void GetDeploymentItemsShouldReturnClassAndMethodLevelDeploymentItemsWith CollectionAssert.AreEqual(expectedDeploymentItems, deploymentItems.ToArray()); } - #endregion +#endregion - #region IsValidDeploymentItem tests +#region IsValidDeploymentItem tests [TestMethod] public void IsValidDeploymentItemShouldReportWarningIfSourcePathIsNull() @@ -419,9 +427,9 @@ public void IsValidDeploymentItemShouldReturnTrueForAValidDeploymentItem() Assert.IsTrue(string.Empty.Equals(warning)); } - #endregion +#endregion - #region HasDeployItems tests +#region HasDeployItems tests [TestMethod] public void HasDeployItemsShouldReturnFalseForNoDeploymentItems() @@ -447,9 +455,9 @@ public void HasDeployItemsShouldReturnTrueWhenDeploymentItemsArePresent() Assert.IsTrue(this.deploymentItemUtility.HasDeploymentItems(testCase)); } - #endregion +#endregion - #region private methods +#region private methods private void SetupDeploymentItems(MemberInfo memberInfo, KeyValuePair[] deploymentItems) { @@ -467,6 +475,6 @@ private void SetupDeploymentItems(MemberInfo memberInfo, KeyValuePair(); diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/ns13TraceListenerManagerTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/ns13TraceListenerManagerTests.cs index 2a9333f722..323498ea47 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/ns13TraceListenerManagerTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/ns13TraceListenerManagerTests.cs @@ -3,7 +3,7 @@ namespace MSTestAdapter.PlatformServices.UnitTests.Services { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 using Microsoft.VisualStudio.TestTools.UnitTesting; #else extern alias FrameworkV1; diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/ns13TraceListenerTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/ns13TraceListenerTests.cs index b166248683..86382dcc62 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/ns13TraceListenerTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.3/ns13TraceListenerTests.cs @@ -3,8 +3,8 @@ namespace MSTestAdapter.PlatformServices.UnitTests.Services { -#if NETCOREAPP1_0 - using Microsoft.VisualStudio.TestTools.UnitTesting; +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; #else extern alias FrameworkV1;