diff --git a/mk/xamarin.mk b/mk/xamarin.mk index 537af408111..1dc19353839 100644 --- a/mk/xamarin.mk +++ b/mk/xamarin.mk @@ -1,5 +1,5 @@ # Available versions can be seen here: # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.Tools.Mlaunch/versions -MLAUNCH_NUGET_VERSION=1.1.113 +MLAUNCH_NUGET_VERSION=1.1.115 # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/AppleDocReader/versions ADR_NUGET_VERSION=1.0.0 diff --git a/tests/common/DotNet.cs b/tests/common/DotNet.cs index 1f7a5c73e86..5ee58a7720b 100644 --- a/tests/common/DotNet.cs +++ b/tests/common/DotNet.cs @@ -222,6 +222,7 @@ public static ExecutionResult Execute (string verb, string project, Dictionary (); args.Add (verb); args.Add (project); @@ -288,11 +289,15 @@ public static ExecutionResult Execute (string verb, string project, Dictionary", " true\n "); + File.WriteAllText (proj, csproj); + + // Replace generated tests with a single passing test + var testFile = Path.Combine (outputDir, "Test1.cs"); + File.WriteAllText (testFile, $@"namespace {template}; + +[TestClass] +public sealed class Test1 {{ + [TestMethod] + public void TestMethod1 () + {{ + }} +}} +"); + + // Boot a simulator so that ComputeRunArguments can find a device + var runtimeIdentifier = GetDefaultRuntimeIdentifier (platform); + var deviceUdid = GetDeviceUdid (outputDir, runtimeIdentifier); + BootSimulator (deviceUdid); + + // Run 'dotnet test' directly using Execution.RunAsync. + // dotnet test's MTP flow doesn't forward /p: properties to its internal + // ComputeRunArguments MSBuild API call, so properties must be in the csproj. + var env = new Dictionary (); + env ["MSBuildSDKsPath"] = null; + env ["MSBUILD_EXE_PATH"] = null; + var binlog = Path.Combine (outputDir, "log-test.binlog"); + var testArgs = new List { "test", proj, $"/bl:{binlog}" }; + var testResult = Execution.RunAsync (DotNet.Executable, testArgs, env, Console.Out, workingDirectory: outputDir, timeout: TimeSpan.FromMinutes (10)).Result; + Assert.AreEqual (0, testResult.ExitCode, $"'dotnet test' failed with exit code {testResult.ExitCode}.\nBinlog: {binlog}\nOutput:\n{testResult.Output.MergedOutput}"); + } + + static string GetDeviceUdid (string projectDirectory, string runtimeIdentifier) + { + var tmpdir = Cache.CreateTemporaryDirectory (); + var outputFile = Path.Combine (tmpdir, "AvailableDevices.json"); + var args = new List { + "build", + "-t:ComputeAvailableDevices", + "-getItem:Devices", + $"-getResultOutputFile:{outputFile}", + $"-p:RuntimeIdentifier={runtimeIdentifier}", + }; + + var env = new Dictionary (); + env ["MSBuildSDKsPath"] = null; + env ["MSBUILD_EXE_PATH"] = null; + var rv = Execution.RunAsync (DotNet.Executable, args, env, Console.Out, workingDirectory: projectDirectory, timeout: TimeSpan.FromMinutes (2)).Result; + Assert.AreEqual (0, rv.ExitCode, $"Failed to compute available devices. Output:\n{rv.Output.MergedOutput}"); + + var output = File.ReadAllText (outputFile); + var doc = JsonDocument.Parse (output); + var devices = doc.RootElement.GetProperty ("Items").GetProperty ("Devices").EnumerateArray ().Select (e => { + var identity = e.GetProperty ("Identity").GetString ()!; + var osVersion = Version.Parse (e.GetProperty ("OSVersion").GetString ()!); + var deviceTypeIdentifier = e.GetProperty ("DeviceTypeIdentifier").GetString ()!; + return (Identity: identity, OsVersion: osVersion, DeviceTypeIdentifier: deviceTypeIdentifier); + }).OrderByDescending (d => d.OsVersion).ThenBy (d => d.DeviceTypeIdentifier).ThenBy (d => d.Identity).ToList (); + + Assert.That (devices, Is.Not.Empty, $"No devices found. Output:\n{output}"); + return devices.First ().Identity; + } + + static void BootSimulator (string udid) + { + var rv = Execution.RunAsync ("xcrun", new List { "simctl", "boot", udid }, timeout: TimeSpan.FromMinutes (1)).Result; + // Exit code 149 means "already booted", which is fine + if (rv.ExitCode != 0 && rv.ExitCode != 149) + Assert.Fail ($"Failed to boot simulator {udid}. Exit code: {rv.ExitCode}\nOutput:\n{rv.Output.MergedOutput}"); + } + } +}