Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion external/Xamarin.MacDev
Submodule Xamarin.MacDev updated 235 files
2 changes: 1 addition & 1 deletion mk/xamarin.mk
Original file line number Diff line number Diff line change
@@ -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
15 changes: 10 additions & 5 deletions tests/common/DotNet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ public static ExecutionResult Execute (string verb, string project, Dictionary<s
case "publish":
case "restore":
case "run":
case "test":
var args = new List<string> ();
args.Add (verb);
args.Add (project);
Expand Down Expand Up @@ -288,11 +289,15 @@ public static ExecutionResult Execute (string verb, string project, Dictionary<s
Console.WriteLine ($"Binlog: {binlogPath}");

// Work around https://github.com/dotnet/msbuild/issues/8845
args.Add ("/v:diag");
args.Add ("/consoleloggerparameters:Verbosity=Quiet");
// vb does not have preview lang, so we force it to latest
if (project.EndsWith (".vbproj", StringComparison.OrdinalIgnoreCase))
args.Add ("/p:LangVersion=latest");
// Skip these for 'dotnet test' because they leak through '-- ' in
// RunArguments and get passed to the test runner as app arguments.
if (verb != "test") {
args.Add ("/v:diag");
args.Add ("/consoleloggerparameters:Verbosity=Quiet");
// vb does not have preview lang, so we force it to latest
if (project.EndsWith (".vbproj", StringComparison.OrdinalIgnoreCase))
args.Add ("/p:LangVersion=latest");
}
// End workaround

if (msbuildParallelism.HasValue) {
Expand Down
102 changes: 102 additions & 0 deletions tests/dotnet/UnitTests/DotNetTestTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using System.Text.Json;

using Xamarin.Tests;
using Xamarin.Utils;

#nullable enable

namespace Xamarin.Tests {
[TestFixture]
public class DotNetTestTest : TestBaseClass {
[Test]
[TestCase (ApplePlatform.iOS, "iostest")]
[TestCase (ApplePlatform.TVOS, "tvostest")]
// macOS and Mac Catalyst don't use mlaunch (they use 'open' via Desktop.targets),
// so MTP support requires a different approach for these platforms.
// [TestCase (ApplePlatform.MacCatalyst, "maccatalysttest")]
// [TestCase (ApplePlatform.MacOSX, "macostest")]
public void DotNetTest (ApplePlatform platform, string template)
{
Configuration.IgnoreIfIgnoredPlatform (platform);

var tmpDir = Cache.CreateTemporaryDirectory ();
var outputDir = Path.Combine (tmpDir, template);
DotNet.AssertNew (outputDir, template);
var proj = Path.Combine (outputDir, $"{template}.csproj");

// dotnet test internally calls ComputeRunArguments via MSBuild API without
// forwarding /p: properties, so we must set them in the project file directly.
var csproj = File.ReadAllText (proj);
csproj = csproj.Replace ("</PropertyGroup>", " <UseFloatingTargetPlatformVersion>true</UseFloatingTargetPlatformVersion>\n </PropertyGroup>");
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<string, string?> ();
env ["MSBuildSDKsPath"] = null;
env ["MSBUILD_EXE_PATH"] = null;
var binlog = Path.Combine (outputDir, "log-test.binlog");
var testArgs = new List<string> { "test", proj, $"/bl:{binlog}" };
var testResult = Execution.RunAsync (DotNet.Executable, testArgs, env, Console.Out, workingDirectory: outputDir, timeout: TimeSpan.FromMinutes (10)).Result;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's failing with "Running the ComputeRunArguments target to discover run commands failed for this project. Fix the errors and warnings and run again.", so maybe a binlog would be able to reveal what's going on?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest has a .binlog now, but it's partial (because something aborted), and I can't seem to get the error message out of it.

I think the problem is something to do with having no Simulator running at all -- are these tests setup for having a simulator? Or should we test in a different place?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error message is:

Running the ComputeRunArguments target to discover run commands failed for this project. Fix the errors and warnings and run again.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it locally, and this is what happens:

Exit code: 1
  Standard output: Using Xcode 26.4.1 found in /Applications/Xcode_26.4.1.app/Contents/Developer
  Running in dotnet test mode...
  xcrun simctl list --json --json-output /var/folders/wh/sk44ynps73x6w9_ktl99dr7c0000gp/T/tmp12ZLGx.tmp
  Target simulator: iPad Air 11-inch (M4) (2F869A26-03F4-4965-A010-FD33C6C2D994) (2F869A26-03F4-4965-A010-FD33C6C2D994)
  App path: bin/Debug/net11.0-ios/iossimulator-arm64/iostest.app/
  Bundle identifier: com.companyname.iostest
  dotnet test mode (pipe: /tmp/7f82dab60eaf49cd8ee2f1768f441d70)
  [RemoteTestAdapter] Installing app: bin/Debug/net11.0-ios/iossimulator-arm64/iostest.app/
  xcrun simctl install 2F869A26-03F4-4965-A010-FD33C6C2D994 bin/Debug/net11.0-ios/iossimulator-arm64/iostest.app/
  Error output: 	An error was encountered processing the command (domain=com.apple.CoreSimulator.SimError, code=405):
  	Unable to lookup in current state: Shutdown
  error HE1045: Failed to execute 'simctl': 'simctl install 2F869A26-03F4-4965-A010-FD33C6C2D994 bin/Debug/net11.0-ios/iossimulator-arm64/iostest.app/' returned the exit code 149.
  error HE1046: Additional output: xcrun simctl install 2F869A26-03F4-4965-A010-FD33C6C2D994 bin/Debug/net11.0-ios/iossimulator-arm64/iostest.app/
  error HE1046: Additional output: An error was encountered processing the command (domain=com.apple.CoreSimulator.SimError, code=405):
  error HE1046: Additional output: Unable to lookup in current state: Shutdown

Test run summary: Zero tests ran
  error: 1

  total: 0
  failed: 0
  succeeded: 0
  skipped: 0
  duration: 4s 175ms
Test run completed with non-success exit code: 1 (see: https://aka.ms/testingplatform/exitcodes)

The simulator has to be launched before you can install apps into it.

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<string> {
"build",
"-t:ComputeAvailableDevices",
"-getItem:Devices",
$"-getResultOutputFile:{outputFile}",
$"-p:RuntimeIdentifier={runtimeIdentifier}",
};

var env = new Dictionary<string, string?> ();
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<string> { "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}");
}
}
}
Loading