Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
Enable UAP Remote Execution for all tests
Browse files Browse the repository at this point in the history
This change to enable remote execution of all corefx tests in UAP. Because the remote execution code for UAP is using WinRT APIs and to avoid forcing adding UAP configuration to all test projects, we factor the remote execution code into its own test library (called TestHelper) which is cross compiled.
  • Loading branch information
tarekgh committed Jun 14, 2017
1 parent 2e833a4 commit 412bdb6
Show file tree
Hide file tree
Showing 45 changed files with 372 additions and 313 deletions.
8 changes: 8 additions & 0 deletions src/CoreFx.Private.TestUtilities/dir.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\dir.props" />
<PropertyGroup>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<AssemblyKey>Test</AssemblyKey>
</PropertyGroup>
</Project>
8 changes: 8 additions & 0 deletions src/CoreFx.Private.TestUtilities/ref/Configurations.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
netstandard;
</BuildConfigurations>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.IO;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;

namespace System.Diagnostics
{
public abstract partial class RemoteExecutorTestBase : System.IO.FileCleanupTestBase
{
public const int FailWaitTimeoutMilliseconds = 60000;
protected static readonly string HostRunner;
protected static readonly string HostRunnerName;
public const int SuccessExitCode = 42;
protected static readonly string TestConsoleApp;
protected RemoteExecutorTestBase() { }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<int> method, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<string, int> method, string arg, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<string, string, int> method, string arg1, string arg2, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<string, string, string, int> method, string arg1, string arg2, string arg3, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<string, string, string, string, int> method, string arg1, string arg2, string arg3, string arg4, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<string, string, string, string, string, int> method, string arg1, string arg2, string arg3, string arg4, string arg5, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<System.Threading.Tasks.Task<int>> method, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvokeRaw(System.Delegate method, string unparsedArg, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public sealed partial class RemoteInvokeHandle : System.IDisposable
{
public RemoteInvokeHandle(System.Diagnostics.Process process, System.Diagnostics.RemoteInvokeOptions options) { }
public System.Diagnostics.RemoteInvokeOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public System.Diagnostics.Process Process { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public void Dispose() { }
}
}
public sealed partial class RemoteInvokeOptions
{
public RemoteInvokeOptions() { }
public bool CheckExitCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public bool EnableProfiling { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public bool Start { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public System.Diagnostics.ProcessStartInfo StartInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public int TimeOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
}
}
namespace System.IO
{
public abstract partial class FileCleanupTestBase : System.IDisposable
{
protected FileCleanupTestBase() { }
protected string TestDirectory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public void Dispose() { }
protected virtual void Dispose(bool disposing) { }
~FileCleanupTestBase() { }
protected string GetTestFileName(System.Nullable<int> index=default(System.Nullable<int>), [System.Runtime.CompilerServices.CallerMemberNameAttribute]string memberName=null, [System.Runtime.CompilerServices.CallerLineNumberAttribute]int lineNumber=0) { throw null; }
protected string GetTestFilePath(System.Nullable<int> index=default(System.Nullable<int>), [System.Runtime.CompilerServices.CallerMemberNameAttribute]string memberName=null, [System.Runtime.CompilerServices.CallerLineNumberAttribute]int lineNumber=0) { throw null; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<ProjectGuid>{E2E59C98-998F-9965-991D-99411166AF6F}</ProjectGuid>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="CoreFx.Private.TestUtilities.cs" />
</ItemGroup>

<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
12 changes: 12 additions & 0 deletions src/CoreFx.Private.TestUtilities/src/Configurations.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
uapaot-Windows_NT;
uap-Windows_NT;
netfx-Windows_NT;
netcoreapp-Windows_NT;
netcoreapp-Unix;
</BuildConfigurations>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<AssemblyName>CoreFx.Private.TestUtilities</AssemblyName>
<ProjectGuid>{5B7EAEC-93CB-40DF-BE40-A60BC189B737}</ProjectGuid>
<RuntimeProjectFile>$(ProjectDir)\external\test-runtime\XUnit.Runtime.depproj</RuntimeProjectFile>
<ClsCompliant>false</ClsCompliant>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Unix-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Unix-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uapaot-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uapaot-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Windows_NT-Release|AnyCPU'" />

<ItemGroup>
<Compile Include="System\IO\FileCleanupTestBase.cs" />
<Compile Include="System\Diagnostics\RemoteExecutorTestBase.cs" />
<Compile Condition="'$(TargetGroup)' == 'netcoreapp'" Include="System\Diagnostics\RemoteExecutorTestBase.netcore.cs" />
<Compile Condition="'$(TargetGroup)' == 'netfx'" Include="System\Diagnostics\RemoteExecutorTestBase.netfx.cs" />
<Compile Condition="'$(TargetGroup)' != 'uap'" Include="System\Diagnostics\RemoteExecutorTestBase.Process.cs" />
<Compile Condition="'$(TargetGroup)' == 'uap'" Include="System\Diagnostics\RemoteExecutorTestBase.uap.cs" />
<Compile Condition="'$(TargetGroup)' == 'uapaot'" Include="System\Diagnostics\RemoteExecutorTestBase.uapaot.cs" />
</ItemGroup>

<ItemGroup>
<Reference Include="System.Runtime" />
<Reference Include="System.IO.FileSystem" />
<Reference Include="System.Threading.Thread" />
<Reference Include="System.Runtime.Extensions" />
<Reference Include="System.Diagnostics.Process" />
<Reference Include="System.ComponentModel.Primitives" />
<Reference Include="System.Runtime.InteropServices.RuntimeInformation" />

<ReferenceFromRuntime Include="xunit.core" />
<ReferenceFromRuntime Include="Xunit.NetCore.Extensions" />
<ReferenceFromRuntime Include="xunit.assert" />
</ItemGroup>

<ItemGroup Condition="'$(TargetGroup)' == 'uap'">
<Reference Include="Windows" />
<Reference Include="mscorlib" />
<Reference Include="System.Runtime.WindowsRuntime" />
</ItemGroup>

<ItemGroup Condition="'$(TargetGroup)' == 'netfx'">
<Reference Include="mscorlib" />
<Reference Include="System" />
</ItemGroup>

<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Xunit;

namespace System.Diagnostics
{
/// <summary>Base class used for all tests that need to spawn a remote process.</summary>
public abstract partial class RemoteExecutorTestBase : FileCleanupTestBase
{
/// <summary>Invokes the method from this assembly in another process using the specified arguments.</summary>
/// <param name="method">The method to invoke.</param>
/// <param name="args">The arguments to pass to the method.</param>
/// <param name="start">true if this function should Start the Process; false if that responsibility is left up to the caller.</param>
/// <param name="psi">The ProcessStartInfo to use, or null for a default.</param>
private static RemoteInvokeHandle RemoteInvoke(MethodInfo method, string[] args, RemoteInvokeOptions options)
{
options = options ?? new RemoteInvokeOptions();

// Verify the specified method is and that it returns an int (the exit code),
// and that if it accepts any arguments, they're all strings.
Assert.True(method.ReturnType == typeof(int) || method.ReturnType == typeof(Task<int>));
Assert.All(method.GetParameters(), pi => Assert.Equal(typeof(string), pi.ParameterType));

// And make sure it's in this assembly. This isn't critical, but it helps with deployment to know
// that the method to invoke is available because we're already running in this assembly.
Type t = method.DeclaringType;
Assembly a = t.GetTypeInfo().Assembly;

// Start the other process and return a wrapper for it to handle its lifetime and exit checking.
var psi = options.StartInfo;
psi.UseShellExecute = false;

if (!options.EnableProfiling)
{
// Profilers / code coverage tools doing coverage of the test process set environment
// variables to tell the targeted process what profiler to load. We don't want the child process
// to be profiled / have code coverage, so we remove these environment variables for that process
// before it's started.
psi.Environment.Remove("Cor_Profiler");
psi.Environment.Remove("Cor_Enable_Profiling");
psi.Environment.Remove("CoreClr_Profiler");
psi.Environment.Remove("CoreClr_Enable_Profiling");
}

// If we need the host (if it exists), use it, otherwise target the console app directly.
string testConsoleAppArgs = "\"" + a.FullName + "\" " + t.FullName + " " + method.Name + " " + string.Join(" ", args);

if (!File.Exists(TestConsoleApp))
throw new IOException("RemoteExecutorConsoleApp test app isn't present in the test runtime directory.");

psi.FileName = HostRunner;
psi.Arguments = ExtraParameter + testConsoleAppArgs;

// Return the handle to the process, which may or not be started
return new RemoteInvokeHandle(options.Start ?
Process.Start(psi) :
new Process() { StartInfo = psi }, options);
}
}
}
Loading

0 comments on commit 412bdb6

Please sign in to comment.