diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadHandler.cs b/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadHandler.cs index 669ee80882..d9e3980e2d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadHandler.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadHandler.cs @@ -29,16 +29,30 @@ public HotReloadHandler(IConsole console, IOutputDevice outputDevice, IOutputDev _console = console; _outputDevice = outputDevice; _outputDeviceDataProducer = outputDeviceDataProducer; - _console.CancelKeyPress += (_, _) => + + if (!IsCancelKeyPressNotSupported()) { - if (!s_shutdownProcess) + _console.CancelKeyPress += (_, _) => { - s_shutdownProcess = true; - SemaphoreSlim.Release(); - } - }; + if (!s_shutdownProcess) + { + s_shutdownProcess = true; + SemaphoreSlim.Release(); + } + }; + } } + [SupportedOSPlatformGuard("android")] + [SupportedOSPlatformGuard("ios")] + [SupportedOSPlatformGuard("tvos")] + [SupportedOSPlatformGuard("browser")] + private static bool IsCancelKeyPressNotSupported() + => RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")); + // Called automatically by the runtime through the MetadataUpdateHandlerAttribute public static void ClearCache(Type[]? _) { @@ -82,10 +96,22 @@ public async Task ShouldRunAsync(Task? waitExecutionCompletion, Cancellati // We're closing } - _console!.Clear(); + if (!IsClearNotSupported()) + { + _console!.Clear(); + } + await _outputDevice.DisplayAsync(_outputDeviceDataProducer, new TextOutputDeviceData(ExtensionResources.HotReloadSessionStarted)); return !s_shutdownProcess; } + + [SupportedOSPlatformGuard("android")] + [SupportedOSPlatformGuard("ios")] + [SupportedOSPlatformGuard("tvos")] + private static bool IsClearNotSupported() + => RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")); #endif } diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs index 557efac8e0..3a20e02cb1 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs @@ -191,7 +191,9 @@ public Task ValidateCommandLineOptionsAsync(ICommandLineOption { // We let the api to do the validity check before to go down the subscription path. // If we don't fail here but we fail below means that the parent process is not there anymore and we can take it as exited. +#pragma warning disable CA1416 // Validate platform compatibility _ = Process.GetProcessById(parentProcessPid); +#pragma warning restore CA1416 } catch (ArgumentException ex) { diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/CountDownEventExtensions.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/CountDownEventExtensions.cs index 159488ef2c..ccf927e17e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/CountDownEventExtensions.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/CountDownEventExtensions.cs @@ -26,12 +26,14 @@ internal static async Task WaitAsync(this CountdownEvent countdownEvent, u // executeOnlyOnce set to true to indicate that the thread will no longer wait on the waitObject // parameter after the delegate has been called; // false to indicate that the timer is reset every time the wait operation completes until the wait is unregistered. +#pragma warning disable CA1416 // Validate platform compatibility registeredHandle = ThreadPool.RegisterWaitForSingleObject( waitObject: countdownEvent.WaitHandle, callBack: (state, timedOut) => ((TaskCompletionSource)state!).TrySetResult(!timedOut), state: tcs, millisecondsTimeOutInterval: millisecondsTimeOutInterval, executeOnlyOnce: true); +#pragma warning restore CA1416 #pragma warning restore SA1115 // Parameter should follow comma // Register the cancellation callback @@ -45,7 +47,9 @@ internal static async Task WaitAsync(this CountdownEvent countdownEvent, u // If the callback method executes because the WaitHandle is // signaled, stop future execution of the callback method // by unregistering the WaitHandle. +#pragma warning disable CA1416 // Validate platform compatibility registeredHandle?.Unregister(null); +#pragma warning restore CA1416 await DisposeHelper.DisposeAsync(tokenRegistration); } } diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/NonCooperativeParentProcessListener.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/NonCooperativeParentProcessListener.cs index 040ed07481..4dfff2be7b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/NonCooperativeParentProcessListener.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/NonCooperativeParentProcessListener.cs @@ -26,9 +26,11 @@ private void SubscribeToParentProcess() try { +#pragma warning disable CA1416 // Validate platform compatibility _parentProcess = Process.GetProcessById(int.Parse(pid[0], CultureInfo.InvariantCulture)); _parentProcess.EnableRaisingEvents = true; _parentProcess.Exited += ParentProcess_Exited; +#pragma warning restore CA1416 } catch (ArgumentException) { diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/IConsole.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/IConsole.cs index df9b17e028..64580f7ff9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/IConsole.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/IConsole.cs @@ -8,16 +8,36 @@ namespace Microsoft.Testing.Platform.Helpers; /// internal interface IConsole { + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] event ConsoleCancelEventHandler? CancelKeyPress; + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public int BufferHeight { get; } + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public int BufferWidth { get; } public bool IsOutputRedirected { get; } + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] void SetForegroundColor(ConsoleColor color); + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] ConsoleColor GetForegroundColor(); void WriteLine(); @@ -28,5 +48,8 @@ internal interface IConsole void Write(char value); + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] void Clear(); } diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs index 7e3040e2b1..a348ad0d7a 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs @@ -13,11 +13,19 @@ internal sealed class SystemConsole : IConsole /// /// Gets the height of the buffer area. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public int BufferHeight => Console.BufferHeight; /// /// Gets the width of the buffer area. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public int BufferWidth => Console.BufferWidth; /// @@ -43,35 +51,14 @@ static SystemConsole() }; } - // This is based on the UnsupportedOSPlatformAttribute on the API: - // https://github.com/dotnet/runtime/blob/8a79637e1454c751c24a984b7fb8af4c4d43394b/src/libraries/System.Console/src/System/Console.cs#L560-L563 - private static bool IsCancelKeyPressNotSupported() - => RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")) || - RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")) || - RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")) || - RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")); - + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public event ConsoleCancelEventHandler? CancelKeyPress { - add - { - if (IsCancelKeyPressNotSupported()) - { - return; - } - - Console.CancelKeyPress += value; - } - - remove - { - if (IsCancelKeyPressNotSupported()) - { - return; - } - - Console.CancelKeyPress -= value; - } + add => Console.CancelKeyPress += value; + remove => Console.CancelKeyPress -= value; } public void SuppressOutput() => _suppressOutput = true; @@ -108,33 +95,23 @@ public void Write(char value) } } + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public void SetForegroundColor(ConsoleColor color) - { -#if NET8_0_OR_GREATER - if (RuntimeInformation.RuntimeIdentifier.Contains("ios") || - RuntimeInformation.RuntimeIdentifier.Contains("android")) - { - return; - } -#endif -#pragma warning disable IDE0022 // Use expression body for method - Console.ForegroundColor = color; -#pragma warning restore IDE0022 // Use expression body for method - } + => Console.ForegroundColor = color; + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public ConsoleColor GetForegroundColor() - { -#if NET8_0_OR_GREATER - if (RuntimeInformation.RuntimeIdentifier.Contains("ios") || - RuntimeInformation.RuntimeIdentifier.Contains("android")) - { - return ConsoleColor.Black; - } -#endif -#pragma warning disable IDE0022 // Use expression body for method - return Console.ForegroundColor; -#pragma warning restore IDE0022 // Use expression body for method - } + => Console.ForegroundColor; - public void Clear() => Console.Clear(); + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + public void Clear() + => Console.Clear(); } diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemMainModule.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemMainModule.cs index e85b8e599e..a9eb7b3a73 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemMainModule.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemMainModule.cs @@ -8,7 +8,9 @@ internal sealed class SystemMainModule(ProcessModule? processModule) : IMainModu { private readonly ProcessModule? _processModule = processModule; +#pragma warning disable CA1416 // Validate platform compatibility public string? FileName => _processModule?.FileName; +#pragma warning restore CA1416 } #else internal sealed class SystemMainModule : IMainModule diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcess.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcess.cs index 76589c9b84..d38a5e75a9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcess.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcess.cs @@ -7,6 +7,7 @@ internal sealed class SystemProcess : IProcess, IDisposable { private readonly Process _process; +#pragma warning disable CA1416 // Validate platform compatibility public SystemProcess(Process process) { _process = process; @@ -51,4 +52,5 @@ public void Kill() #endif public void Dispose() => _process.Dispose(); +#pragma warning restore CA1416 } diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcessHandler.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcessHandler.cs index dbb7589ad8..b32ac01630 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcessHandler.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcessHandler.cs @@ -8,6 +8,7 @@ namespace Microsoft.Testing.Platform.Helpers; [SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "This is the Process wrapper.")] internal sealed class SystemProcessHandler : IProcessHandler { +#pragma warning disable CA1416 // Validate platform compatibility public IProcess GetCurrentProcess() => new SystemProcess(Process.GetCurrentProcess()); public IProcess GetProcessById(int pid) => new SystemProcess(Process.GetProcessById(pid)); @@ -21,4 +22,5 @@ public IProcess Start(ProcessStartInfo startInfo) process.EnableRaisingEvents = true; return new SystemProcess(process); } +#pragma warning restore CA1416 } diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemTask.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemTask.cs index 186d6ee484..624494b3f9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemTask.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemTask.cs @@ -44,7 +44,9 @@ public Task RunLongRunning(Func action, string name, CancellationToken can Name = name, }; +#pragma warning disable CA1416 // Validate platform compatibility thread.Start(); +#pragma warning restore CA1416 return taskCompletionSource.Task; } diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs index 7a983ea032..601ea403d2 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs @@ -107,6 +107,8 @@ protected override async Task InternalRunAsync() #else string arguments = string.Join(" ", partialCommandLine); #endif + +#pragma warning disable CA1416 // Validate platform compatibility ProcessStartInfo processStartInfo = new( executableInfo.FilePath, arguments) @@ -122,6 +124,7 @@ protected override async Task InternalRunAsync() UseShellExecute = false, #endif }; +#pragma warning restore CA1416 List dataConsumersBuilder = [.. _testHostsInformation.DataConsumer]; @@ -209,7 +212,9 @@ protected override async Task InternalRunAsync() foreach (EnvironmentVariable envVar in environmentVariables.GetAll()) { +#pragma warning disable CA1416 // Validate platform compatibility processStartInfo.EnvironmentVariables[envVar.Variable] = envVar.Value; +#pragma warning restore CA1416 } } @@ -224,9 +229,13 @@ protected override async Task InternalRunAsync() // Launch the test host process string testHostProcessStartupTime = _clock.UtcNow.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture); +#pragma warning disable CA1416 // Validate platform compatibility processStartInfo.EnvironmentVariables.Add($"{EnvironmentVariableConstants.TESTINGPLATFORM_TESTHOSTCONTROLLER_TESTHOSTPROCESSSTARTTIME}_{currentPID}", testHostProcessStartupTime); +#pragma warning restore CA1416 await _logger.LogDebugAsync($"{EnvironmentVariableConstants.TESTINGPLATFORM_TESTHOSTCONTROLLER_TESTHOSTPROCESSSTARTTIME}_{currentPID} '{testHostProcessStartupTime}'"); +#pragma warning disable CA1416 // Validate platform compatibility await _logger.LogDebugAsync($"Starting test host process '{processStartInfo.FileName}' with args '{processStartInfo.Arguments}'"); +#pragma warning restore CA1416 using IProcess testHostProcess = process.Start(processStartInfo); int? testHostProcessId = null; @@ -266,7 +275,9 @@ protected override async Task InternalRunAsync() // Wait for the test host controller to send the PID of the test host process using (CancellationTokenSource timeout = new(TimeoutHelper.DefaultHangTimeSpanTimeout)) { +#pragma warning disable CA1416 // Validate platform compatibility _waitForPid.Wait(timeout.Token); +#pragma warning restore CA1416 } await _logger.LogDebugAsync("Fire OnTestHostProcessStartedAsync"); diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs index 9161243880..39613088cd 100644 --- a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs +++ b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs @@ -15,6 +15,7 @@ namespace Microsoft.Testing.Platform.IPC; +#pragma warning disable CA1416 // Validate platform compatibility internal sealed class NamedPipeClient : NamedPipeBase, IClient { private readonly NamedPipeClientStream _namedPipeClientStream; diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs index 89deb4723e..dbb7775e98 100644 --- a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs +++ b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs @@ -61,7 +61,9 @@ public NamedPipeServer( CancellationToken cancellationToken) { Guard.NotNull(pipeNameDescription); +#pragma warning disable CA1416 // Validate platform compatibility _namedPipeServerStream = new((PipeName = pipeNameDescription).Name, PipeDirection.InOut, maxNumberOfServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); +#pragma warning restore CA1416 _callback = callback; _environment = environment; _logger = logger; @@ -76,7 +78,9 @@ public NamedPipeServer( public async Task WaitConnectionAsync(CancellationToken cancellationToken) { await _logger.LogDebugAsync($"Waiting for connection for the pipe name {PipeName.Name}"); +#pragma warning disable CA1416 // Validate platform compatibility await _namedPipeServerStream.WaitForConnectionAsync(cancellationToken); +#pragma warning restore CA1416 WasConnected = true; await _logger.LogDebugAsync($"Client connected to {PipeName.Name}"); _loopTask = _task.Run( @@ -113,7 +117,9 @@ private async Task InternalLoopAsync(CancellationToken cancellationToken) { int currentReadIndex = 0; #if NET +#pragma warning disable CA1416 // Validate platform compatibility int currentReadBytes = await _namedPipeServerStream.ReadAsync(_readBuffer.AsMemory(currentReadIndex, _readBuffer.Length), cancellationToken); +#pragma warning restore CA1416 #else int currentReadBytes = await _namedPipeServerStream.ReadAsync(_readBuffer, currentReadIndex, _readBuffer.Length, cancellationToken); #endif @@ -227,11 +233,15 @@ private async Task InternalLoopAsync(CancellationToken cancellationToken) try { #if NET +#pragma warning disable CA1416 // Validate platform compatibility await _namedPipeServerStream.WriteAsync(_messageBuffer.GetBuffer().AsMemory(0, (int)_messageBuffer.Position), cancellationToken); +#pragma warning restore CA1416 #else await _namedPipeServerStream.WriteAsync(_messageBuffer.GetBuffer(), 0, (int)_messageBuffer.Position, cancellationToken); #endif +#pragma warning disable CA1416 // Validate platform compatibility await _namedPipeServerStream.FlushAsync(cancellationToken); +#pragma warning restore CA1416 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { _namedPipeServerStream.WaitForPipeDrain(); diff --git a/src/Platform/Microsoft.Testing.Platform/Logging/FileLogger.cs b/src/Platform/Microsoft.Testing.Platform/Logging/FileLogger.cs index b099b3aee5..eeec19e5f5 100644 --- a/src/Platform/Microsoft.Testing.Platform/Logging/FileLogger.cs +++ b/src/Platform/Microsoft.Testing.Platform/Logging/FileLogger.cs @@ -144,7 +144,9 @@ private void InternalSyncLog(LogLevel logLevel, TState state, Exception? return; } +#pragma warning disable CA1416 // Validate platform compatibility if (!_semaphore.Wait(TimeoutHelper.DefaultHangTimeSpanTimeout)) +#pragma warning restore CA1416 { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, PlatformResources.TimeoutAcquiringSemaphoreErrorMessage, TimeoutHelper.DefaultHangTimeoutSeconds)); } diff --git a/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj b/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj index c0169e8474..c110a4ddca 100644 --- a/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj +++ b/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj @@ -74,6 +74,15 @@ This package provides the core platform and the .NET implementation of the proto + + + + + + + + + diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs index 55b320706a..4e8e511e22 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs @@ -54,10 +54,14 @@ public AnsiTerminal(IConsole console, string? baseDirectory) } public int Width +#pragma warning disable CA1416 // Validate platform compatibility => _console.IsOutputRedirected ? int.MaxValue : _console.BufferWidth; +#pragma warning restore CA1416 // Validate platform compatibility public int Height +#pragma warning disable CA1416 // Validate platform compatibility => _console.IsOutputRedirected ? int.MaxValue : _console.BufferHeight; +#pragma warning restore CA1416 // Validate platform compatibility public void Append(char value) { diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs index b72fa30d2e..aadf3c3fa0 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs @@ -19,12 +19,14 @@ internal sealed class NonAnsiTerminal : ITerminal public NonAnsiTerminal(IConsole console) { _console = console; - _defaultForegroundColor = _console.GetForegroundColor(); + _defaultForegroundColor = IsForegroundColorNotSupported() ? ConsoleColor.Black : _console.GetForegroundColor(); } +#pragma warning disable CA1416 // Validate platform compatibility public int Width => _console.IsOutputRedirected ? int.MaxValue : _console.BufferWidth; public int Height => _console.IsOutputRedirected ? int.MaxValue : _console.BufferHeight; +#pragma warning restore CA1416 // Validate platform compatibility public void Append(char value) => _console.Write(value); @@ -48,10 +50,24 @@ public void AppendLink(string path, int? lineNumber) } public void SetColor(TerminalColor color) - => _console.SetForegroundColor(ToConsoleColor(color)); + { + if (IsForegroundColorNotSupported()) + { + return; + } + + _console.SetForegroundColor(ToConsoleColor(color)); + } public void ResetColor() - => _console.SetForegroundColor(_defaultForegroundColor); + { + if (IsForegroundColorNotSupported()) + { + return; + } + + _console.SetForegroundColor(_defaultForegroundColor); + } public void ShowCursor() { @@ -225,4 +241,14 @@ public void StopBusyIndicator() { // nop } + + [SupportedOSPlatformGuard("android")] + [SupportedOSPlatformGuard("ios")] + [SupportedOSPlatformGuard("tvos")] + [SupportedOSPlatformGuard("browser")] + private static bool IsForegroundColorNotSupported() + => RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")); } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs index d369d99059..01a5f9030d 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs @@ -103,7 +103,9 @@ public void StartShowingProgress(int workerCount) _terminal.StartBusyIndicator(); // If we crash unexpectedly without completing this thread we don't want it to keep the process running. _refresher = new Thread(ThreadProc) { IsBackground = true }; +#pragma warning disable CA1416 // Validate platform compatibility _refresher.Start(); +#pragma warning restore CA1416 } } diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs index 8733a93026..6c578c2197 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs @@ -44,6 +44,7 @@ public Task CreateMessageHandlerAsync(CancellationToken cancell ? ConnectToTestPlatformClientAsync(_host, _port, cancellationToken) : StartTestPlatformServerAsync(port: _port, cancellationToken); +#pragma warning disable CA1416 // Validate platform compatibility private async Task ConnectToTestPlatformClientAsync(string clientHost, int clientPort, CancellationToken cancellationToken) { await _outputDevice.DisplayAsync(this, new TextOutputDeviceData(string.Format(CultureInfo.InvariantCulture, PlatformResources.ConnectingToClientHost, clientHost, clientPort))); @@ -84,6 +85,7 @@ private async Task StartTestPlatformServerAsync(int? port, Canc throw; } } +#pragma warning restore CA1416 public Task IsEnabledAsync() => Task.FromResult(false); } diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/TcpMessageHandler.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/TcpMessageHandler.cs index 782fddf1e4..1ea27abcde 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/TcpMessageHandler.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/TcpMessageHandler.cs @@ -37,6 +37,8 @@ internal sealed class TcpMessageHandler( protected override void Dispose(bool disposing) { base.Dispose(disposing); +#pragma warning disable CA1416 // Validate platform compatibility _client.Close(); +#pragma warning restore CA1416 } } diff --git a/src/Platform/Microsoft.Testing.Platform/Services/CTRLPlusCCancellationTokenSource.cs b/src/Platform/Microsoft.Testing.Platform/Services/CTRLPlusCCancellationTokenSource.cs index 9028714672..796b1e09b2 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/CTRLPlusCCancellationTokenSource.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/CTRLPlusCCancellationTokenSource.cs @@ -13,7 +13,7 @@ internal sealed class CTRLPlusCCancellationTokenSource : ITestApplicationCancell public CTRLPlusCCancellationTokenSource(IConsole? console = null, ILogger? logger = null) { - if (console is not null) + if (console is not null && !IsCancelKeyPressNotSupported()) { console.CancelKeyPress += OnConsoleCancelKeyPressed; } @@ -21,6 +21,16 @@ public CTRLPlusCCancellationTokenSource(IConsole? console = null, ILogger? logge _logger = logger; } + [SupportedOSPlatformGuard("android")] + [SupportedOSPlatformGuard("ios")] + [SupportedOSPlatformGuard("tvos")] + [SupportedOSPlatformGuard("browser")] + private static bool IsCancelKeyPressNotSupported() + => RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")); + public void CancelAfter(TimeSpan timeout) => _cancellationTokenSource.CancelAfter(timeout); public CancellationToken CancellationToken diff --git a/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs b/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs index e92049f5aa..c69e617b8a 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs @@ -30,7 +30,9 @@ public StopPoliciesService(ITestApplicationCancellationTokenSource testApplicati public bool IsAbortTriggered { get; private set; } private static void RegisterCallback(ref BlockingCollection? callbacks, T callback) +#pragma warning disable CA1416 // Validate platform compatibility => (callbacks ??= new()).Add(callback); +#pragma warning restore CA1416 public async Task ExecuteMaxFailedTestsCallbacksAsync(int maxFailedTests, CancellationToken cancellationToken) {