[tests] Rework TestRuntime.RunAsync. (#18391)

* Move all the RunAsync logic to the TestRuntime class, instead of having some
  in TestRuntime and some in AppDelegate.
* Create a unified Task-based implementation for all platforms, optionally showing
  a UI on the platforms where we can do that.
* Remove all the overloads that took a DateTime timeout, and instead only use a
  TimeSpan timeout. This simplified some of the code.
* The new Task-based implementation will capture any exceptions (and rethrow most
  of them) from the tasks we're waiting for, so no need to do that in each RunAsync
  caller. This simplifies the testing code a lot for some tests.
* Add a new TryRunAsync method that will return (instead of rethrowing) any exceptions.
  This simplifies some of the testing code (which verifies the correct exception,
  or ignores the test in case of some exceptions).
* The new Task-based implementation will bubble up any NUnit exceptions, which
  means that the tasks we're waiting for can call NUnit's Assert and the right thing
  happens (in particular Assert.Ignore will actually ignore the test).
This commit is contained in:
Rolf Bjarne Kvinge 2023-06-06 21:36:49 +02:00 коммит произвёл GitHub
Родитель 1ca3c6ad8a
Коммит b59587a0cd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
40 изменённых файлов: 515 добавлений и 564 удалений

Просмотреть файл

@ -0,0 +1,275 @@
#if !__WATCHOS__
#define CAN_SHOW_ASYNC_UI
#endif
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using CoreGraphics;
using Foundation;
using NUnit.Framework;
#if HAS_UIKIT
using UIKit;
using XColor = UIKit.UIColor;
using XImage = UIKit.UIImage;
using XImageView = UIKit.UIImageView;
using XViewController = UIKit.UIViewController;
#elif HAS_APPKIT
using AppKit;
using XColor = AppKit.NSColor;
using XImage = AppKit.NSImage;
using XImageView = AppKit.NSImageView;
using XViewController = AppKit.NSViewController;
#else
using XImage = Foundation.NSObject;
#endif
#nullable enable
partial class TestRuntime {
public static bool RunAsync (TimeSpan timeout, Task task, XImage? imageToShow = null)
{
return RunAsync (timeout, task, Task.CompletedTask, imageToShow);
}
public static bool RunAsync (TimeSpan timeout, Func<bool> check_completed, XImage? imageToShow = null)
{
return RunAsync (timeout, Task.CompletedTask, check_completed, imageToShow);
}
public static bool RunAsync (TimeSpan timeout, Func<Task> startTask, Func<bool> check_completed, XImage? imageToShow = null)
{
return RunAsync (timeout, startTask (), check_completed, imageToShow);
}
public static bool RunAsync (TimeSpan timeout, Func<Task> startTask, Task completionTask, XImage? imageToShow = null)
{
return RunAsync (timeout, startTask (), completionTask, imageToShow);
}
public static bool RunAsync (TimeSpan timeout, Action action, Func<bool> check_completed, XImage? imageToShow = null)
{
var actionTask = Task.Factory.StartNew (
action,
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext ()
);
return RunAsync (timeout, actionTask, check_completed, imageToShow);
}
public static bool RunAsync (TimeSpan timeout, Task startTask, Func<bool> check_completed, XImage? imageToShow = null)
{
var completionTaskSource = new TaskCompletionSource<bool> ();
var checkCompletionTimer = NSTimer.CreateRepeatingScheduledTimer (0.1, (NSTimer timer) => {
if (check_completed ()) {
completionTaskSource.SetResult (true);
timer.Invalidate ();
}
});
try {
return RunAsync (timeout, startTask, completionTaskSource.Task, imageToShow);
} finally {
checkCompletionTimer.Invalidate ();
}
}
public static bool RunAsync (TimeSpan timeout, Task startTask, Task completionTask, XImage? imageToShow = null)
{
var rv = TryRunAsync (timeout, startTask, completionTask, imageToShow, out var exception);
if (exception is not null)
throw exception;
return rv;
}
public static bool TryRunAsync (TimeSpan timeout, Func<Task> startTask, out Exception? exception)
{
return TryRunAsync (timeout, startTask (), Task.CompletedTask, null, out exception);
}
public static bool TryRunAsync (TimeSpan timeout, Task startTask, out Exception? exception)
{
return TryRunAsync (timeout, startTask, Task.CompletedTask, null, out exception);
}
public static bool TryRunAsync (TimeSpan timeout, Task startTask, Task completionTask, out Exception? exception)
{
return TryRunAsync (timeout, startTask, completionTask, null, out exception);
}
// This function returns 'false' if the timeout was hit before the two tasks completed.
// This is a bit unconventional: in particular 'true' will return if any of the tasks threw an exception.
public static bool TryRunAsync (TimeSpan timeout, Task startTask, Task completionTask, XImage? imageToShow, out Exception? exception)
{
#if CAN_SHOW_ASYNC_UI
using var ui = ShowAsyncUI (imageToShow);
#endif // CAN_SHOW_ASYNC_UI
exception = null;
try {
var runLoop = NSRunLoop.Main;
if (!runLoop.RunUntil (startTask, timeout))
return false;
startTask.GetAwaiter ().GetResult (); // Trigger any captured exceptions.
if (!runLoop.RunUntil (completionTask, timeout))
return false;
completionTask.GetAwaiter ().GetResult (); // Trigger any captured exceptions.
} catch (ResultStateException) {
// Don't capture any NUnit-related exceptions, those should bubble up and terminate the test accordingly.
throw;
} catch (Exception e) {
exception = e;
// We return 'true' here, because we didn't time out.
}
return true;
}
#if CAN_SHOW_ASYNC_UI
static IDisposable ShowAsyncUI (XImage? imageToShow = null)
{
var state = new AsyncState ();
state.Show (imageToShow);
return state;
}
class AsyncState : IDisposable {
#if HAS_UIKIT
UIViewController? initialRootViewController;
UIWindow? window;
UINavigationController? navigation;
#else
NSWindow? window;
#endif // HAS_UIKIT
public void Show (XImage? imageToShow)
{
var vc = new AsyncController (imageToShow);
#if HAS_UIKIT
window = UIApplication.SharedApplication.KeyWindow;
initialRootViewController = window.RootViewController;
navigation = initialRootViewController as UINavigationController;
// Pushing something to a navigation controller doesn't seem to work on phones
if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone)
navigation = null;
if (navigation is not null) {
navigation.PushViewController (vc, false);
} else {
window.RootViewController = vc;
}
#else
var size = new CGRect (0, 0, 300, 300);
var loc = new CGPoint ((NSScreen.MainScreen.Frame.Width - size.Width) / 2, (NSScreen.MainScreen.Frame.Height - size.Height) / 2);
window = new NSWindow (size, NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable | NSWindowStyle.Titled, NSBackingStore.Retained, false);
window.SetFrameOrigin (loc);
window.ContentViewController = vc;
window.MakeKeyAndOrderFront (null);
#endif // HAS_UIKIT
}
public void Hide ()
{
if (window is null)
return;
#if HAS_UIKIT
if (navigation is not null) {
navigation.PopViewController (false);
} else {
window.RootViewController = initialRootViewController;
}
#else
window.Close ();
window.Dispose ();
#endif // HAS_UIKIT
window = null;
}
public void Dispose ()
{
Hide ();
}
}
class AsyncController : XViewController {
XImage? imageToShow;
static int counter;
public AsyncController (XImage? imageToShow = null)
{
this.imageToShow = imageToShow;
counter++;
}
#if !HAS_UIKIT
public override void LoadView ()
{
View = new NSView ();
}
#endif // !HAS_UIKIT
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
XColor backgroundColor;
switch (counter % 2) {
case 0:
backgroundColor = XColor.Yellow;
break;
default:
backgroundColor = XColor.LightGray;
break;
}
#if HAS_UIKIT
View.BackgroundColor = backgroundColor;
#else
View.WantsLayer = true;
View.Layer.BackgroundColor = backgroundColor.CGColor;
#endif // HAS_UIKIT
if (imageToShow is not null) {
var imgView = new XImageView (View.Bounds);
imgView.Image = imageToShow;
#if HAS_UIKIT
imgView.ContentMode = UIViewContentMode.Center;
#endif // HAS_UIKIT
View.AddSubview (imgView);
}
}
}
#endif // CAN_SHOW_ASYNC_UI
}
namespace Foundation {
public static class NSRunLoop_Extensions {
// Returns true if task completed before the timeout,
// otherwise returns false
public static bool RunUntil (this NSRunLoop self, Task task, TimeSpan timeout)
{
var start = Stopwatch.StartNew ();
while (true) {
if (task.IsCompleted)
return true;
if (timeout <= start.Elapsed)
return false;
self.RunUntil (NSDate.Now.AddSeconds (0.1));
}
}
}
}

Просмотреть файл

@ -1,23 +0,0 @@
using System;
using AppKit;
using Foundation;
partial class TestRuntime {
public static bool RunAsync (TimeSpan timeout, Action action, Func<bool> check_completed, NSImage imageToShow = null)
{
return RunAsync (DateTime.Now.Add (timeout), action, check_completed, imageToShow);
}
public static bool RunAsync (DateTime timeout, Action action, Func<bool> check_completed, NSImage imageToShow = null)
{
NSTimer.CreateScheduledTimer (0.01, (v) => action ());
do {
if (timeout < DateTime.Now)
return false;
NSRunLoop.Main.RunUntil (NSDate.Now.AddSeconds (0.1));
} while (!check_completed ());
return true;
}
}

Просмотреть файл

@ -122,9 +122,6 @@
<Compile Include="..\..\common\TestRuntime.cs">
<Link>TestRuntime.cs</Link>
</Compile>
<Compile Include="..\..\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
<Compile Include="..\..\common\MonoNativeConfig.cs">
<Link>MonoNativeConfig.cs</Link>
</Compile>

Просмотреть файл

@ -35,9 +35,6 @@
<Compile Include="$(RootTestsDirectory)\common\mac\Mac.cs">
<Link>Mac.cs</Link>
</Compile>
<Compile Include="$(RootTestsDirectory)\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.EndsWith('-macos'))">

Просмотреть файл

@ -23,9 +23,6 @@
<ItemGroup Condition="$(TargetFramework.EndsWith('-macos'))">
<Compile Include="$(RootTestsDirectory)\common\mac\MacMain.cs" Condition="$(TargetFramework.EndsWith('-macos'))" Link="MacMain.cs" />
<Compile Include="$(RootTestsDirectory)\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.EndsWith('-macos'))">

Просмотреть файл

@ -38,9 +38,6 @@
<ItemGroup Condition="$(TargetFramework.EndsWith('-macos'))">
<Compile Include="$(RootTestsDirectory)\common\mac\MacMain.cs" Condition="$(TargetFramework.EndsWith('-macos'))" Link="MacMain.cs" />
<Compile Include="$(RootTestsDirectory)\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
<Compile Include="$(ThisTestDirectory)\..\..\mac\link all\LinkAllTest.cs" />
</ItemGroup>

Просмотреть файл

@ -32,9 +32,6 @@
<ItemGroup Condition="$(TargetFramework.EndsWith('-macos'))">
<Compile Include="$(RootTestsDirectory)\common\mac\MacMain.cs" Condition="$(TargetFramework.EndsWith('-macos'))" Link="MacMain.cs" />
<Compile Include="$(RootTestsDirectory)\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
<Compile Include="$(ThisTestDirectory)\..\..\mac\link sdk\LinkSdkTest.cs" />
</ItemGroup>

Просмотреть файл

@ -24,9 +24,6 @@
<ItemGroup Condition="$(TargetFramework.EndsWith('-macos'))">
<Compile Include="$(RootTestsDirectory)\common\mac\MacMain.cs" Condition="$(TargetFramework.EndsWith('-macos'))" Link="MacMain.cs" />
<Compile Include="$(RootTestsDirectory)\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.EndsWith('-macos'))">

Просмотреть файл

@ -32,9 +32,6 @@
<ItemGroup Condition="$(TargetFramework.EndsWith('-macos'))">
<Compile Include="$(RootTestsDirectory)\common\mac\MacMain.cs" Condition="$(TargetFramework.EndsWith('-macos'))" Link="MacMain.cs" />
<Compile Include="$(RootTestsDirectory)\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
<Compile Include="$(ThisTestDirectory)\..\..\mac\link sdk\LinkSdkTest.cs" />
</ItemGroup>

Просмотреть файл

@ -80,9 +80,6 @@
<Compile Include="..\..\..\common\TestRuntime.cs">
<Link>TestRuntime.cs</Link>
</Compile>
<Compile Include="..\..\..\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
<Compile Include="..\..\CommonDontLinkTest.cs">
<Link>CommonDontLinkTest.cs</Link>
</Compile>

Просмотреть файл

@ -93,9 +93,6 @@
<Compile Include="..\..\..\common\TestRuntime.cs">
<Link>TestRuntime.cs</Link>
</Compile>
<Compile Include="..\..\..\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
<Compile Include="..\..\CommonLinkAllTest.cs">
<Link>CommonLinkAllTest.cs</Link>
</Compile>

Просмотреть файл

@ -86,9 +86,6 @@
<Compile Include="..\..\..\common\TestRuntime.cs">
<Link>TestRuntime.cs</Link>
</Compile>
<Compile Include="..\..\..\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
<Compile Include="..\..\CommonLinkSdkTest.cs">
<Link>CommonLinkSdkTest.cs</Link>
</Compile>

Просмотреть файл

@ -2,6 +2,9 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using CoreFoundation;
using Foundation;
using UIKit;
using MonoTouch.NUnit.UI;
@ -43,69 +46,7 @@ public partial class AppDelegate : UIApplicationDelegate {
window.RootViewController = bckp;
}
}
public static bool RunAsync (DateTime timeout, Action action, Func<bool> check_completed, UIImage imageToShow = null)
{
var vc = new AsyncController (action, imageToShow);
var bckp = window.RootViewController;
var navigation = bckp as UINavigationController;
if (navigation is not null) {
navigation.PushViewController (vc, false);
} else {
window.RootViewController = vc;
}
try {
do {
if (timeout < DateTime.Now)
return false;
NSRunLoop.Main.RunUntil (NSDate.Now.AddSeconds (0.1));
} while (!check_completed ());
} finally {
if (navigation is not null) {
navigation.PopViewController (false);
} else {
window.RootViewController = bckp;
}
}
return true;
}
}
class AsyncController : UIViewController {
Action action;
UIImage imageToShow;
static int counter;
public AsyncController (Action action, UIImage imageToShow = null)
{
this.action = action;
this.imageToShow = imageToShow;
counter++;
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
switch (counter % 2) {
case 0:
View.BackgroundColor = UIColor.Yellow;
break;
default:
View.BackgroundColor = UIColor.LightGray;
break;
}
if (imageToShow is not null) {
var imgView = new UIImageView (View.Bounds);
imgView.Image = imageToShow;
imgView.ContentMode = UIViewContentMode.Center;
View.AddSubview (imgView);
}
NSTimer.CreateScheduledTimer (0.01, (v) => action ());
}
}
#endif // !__WATCHOS__

Просмотреть файл

@ -11,6 +11,8 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Foundation;
using AudioToolbox;
using ObjCRuntime;
@ -30,16 +32,16 @@ namespace MonoTouchFixtures.AudioToolbox {
var path = NSBundle.MainBundle.PathForResource ("1", "caf", "AudioToolbox");
using (var ss = SystemSound.FromFile (NSUrl.FromFilename (path))) {
var completed = false;
var completed = new TaskCompletionSource<bool> ();
const int timeout = 10;
Assert.AreEqual (AudioServicesError.None, ss.AddSystemSoundCompletion (delegate
{
completed = true;
completed.SetResult (true);
}));
ss.PlaySystemSound ();
Assert.IsTrue (TestRuntime.RunAsync (DateTime.Now.AddSeconds (timeout), async () => { }, () => completed), "PlaySystemSound");
Assert.IsTrue (TestRuntime.RunAsync (TimeSpan.FromSeconds (timeout), completed.Task), "PlaySystemSound");
}
}
@ -64,13 +66,11 @@ namespace MonoTouchFixtures.AudioToolbox {
using (var ss = SystemSound.FromFile (NSUrl.FromFilename (path))) {
var completed = false;
var completed = new TaskCompletionSource<bool> ();
const int timeout = 10;
completed = false;
Assert.IsTrue (TestRuntime.RunAsync (DateTime.Now.AddSeconds (timeout), async () =>
ss.PlaySystemSound (() => { completed = true; }
), () => completed), "TestCallbackPlaySystem");
ss.PlaySystemSound (() => { completed.SetResult (true); });
Assert.IsTrue (TestRuntime.RunAsync (TimeSpan.FromSeconds (timeout), completed.Task), "TestCallbackPlaySystem");
}
}
@ -84,13 +84,11 @@ namespace MonoTouchFixtures.AudioToolbox {
using (var ss = SystemSound.FromFile (NSUrl.FromFilename (path))) {
var completed = false;
var completed = new TaskCompletionSource<bool> ();
const int timeout = 10;
completed = false;
Assert.IsTrue (TestRuntime.RunAsync (DateTime.Now.AddSeconds (timeout), async () =>
ss.PlayAlertSound (() => { completed = true; }
), () => completed), "TestCallbackPlayAlert");
ss.PlayAlertSound (() => { completed.SetResult (true); });
Assert.IsTrue (TestRuntime.RunAsync (TimeSpan.FromSeconds (timeout), completed.Task), "TestCallbackPlayAlert");
}
}

Просмотреть файл

@ -63,7 +63,7 @@ namespace MonoTouchFixtures.CoreFoundation {
Assert.Throws<ArgumentNullException> (() => db.Notify (DispatchQueue.MainQueue, (Action) null), "Null 2");
db.Notify (DispatchQueue.MainQueue, notification);
DispatchQueue.MainQueue.DispatchAsync (db);
TestRuntime.RunAsync (DateTime.Now.AddSeconds (5), () => { }, () => notified);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), () => { }, () => notified);
Assert.IsTrue (called, "Called");
}
}
@ -81,7 +81,7 @@ namespace MonoTouchFixtures.CoreFoundation {
Assert.Throws<ArgumentNullException> (() => db.Notify (DispatchQueue.MainQueue, (DispatchBlock) null), "Null 2");
db.Notify (DispatchQueue.MainQueue, notification_block);
DispatchQueue.MainQueue.DispatchAsync (db);
TestRuntime.RunAsync (DateTime.Now.AddSeconds (5), () => { }, () => notified);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), () => { }, () => notified);
Assert.IsTrue (called, "Called");
}
}

Просмотреть файл

@ -58,7 +58,7 @@ namespace MonoTouchFixtures.CoreFoundation {
var callback = new Action (() => called = true);
using (var block = new DispatchBlock (callback)) {
dg.Notify (DispatchQueue.MainQueue, block);
TestRuntime.RunAsync (DateTime.Now.AddSeconds (5), () => { }, () => called);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), () => { }, () => called);
Assert.IsTrue (called, "Called");
}
}
@ -71,7 +71,7 @@ namespace MonoTouchFixtures.CoreFoundation {
var called = false;
var callback = new Action (() => called = true);
dg.Notify (DispatchQueue.MainQueue, callback);
TestRuntime.RunAsync (DateTime.Now.AddSeconds (5), () => { }, () => called);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), () => { }, () => called);
Assert.IsTrue (called, "Called");
}
}

Просмотреть файл

@ -9,6 +9,8 @@
using System;
using System.IO;
using System.Threading.Tasks;
using CoreFoundation;
using Foundation;
using ObjCRuntime;
@ -118,18 +120,22 @@ namespace MonoTouchFixtures.CoreFoundation {
TestRuntime.AssertSystemVersion (ApplePlatform.MacOSX, 10, 10, throwIfOtherPlatform: false);
using (var queue = new DispatchQueue ("DispatchAsync")) {
var called = false;
var callback = new Action (() => called = true);
queue.DispatchAsync (callback);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), () => { }, () => called);
Assert.IsTrue (called, "Called");
called = false;
using (var dg = new DispatchBlock (callback)) {
queue.DispatchAsync (dg);
dg.Wait (TimeSpan.FromSeconds (5));
{
var called = new TaskCompletionSource<bool> ();
var callback = new Action (() => called.SetResult (true));
queue.DispatchAsync (callback);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), called.Task);
Assert.IsTrue (called.Task.Result, "Called");
}
{
var called = new TaskCompletionSource<bool> ();
var callback = new Action (() => called.SetResult (true));
using (var dg = new DispatchBlock (callback)) {
queue.DispatchAsync (dg);
dg.Wait (TimeSpan.FromSeconds (5));
}
Assert.IsTrue (called.Task.Result, "Called DispatchBlock");
}
Assert.IsTrue (called, "Called DispatchBlock");
}
}
@ -140,18 +146,22 @@ namespace MonoTouchFixtures.CoreFoundation {
TestRuntime.AssertSystemVersion (ApplePlatform.MacOSX, 10, 10, throwIfOtherPlatform: false);
using (var queue = new DispatchQueue ("DispatchBarrierAsync")) {
var called = false;
var callback = new Action (() => called = true);
queue.DispatchBarrierAsync (callback);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), () => { }, () => called);
Assert.IsTrue (called, "Called");
called = false;
using (var dg = new DispatchBlock (callback)) {
queue.DispatchBarrierAsync (dg);
dg.Wait (TimeSpan.FromSeconds (5));
{
var called = new TaskCompletionSource<bool> ();
var callback = new Action (() => called.SetResult (true));
queue.DispatchBarrierAsync (callback);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), called.Task);
Assert.IsTrue (called.Task.Result, "Called");
}
{
var called = new TaskCompletionSource<bool> ();
var callback = new Action (() => called.SetResult (true));
using (var dg = new DispatchBlock (callback)) {
queue.DispatchBarrierAsync (dg);
dg.Wait (TimeSpan.FromSeconds (5));
}
Assert.IsTrue (called.Task.Result, "Called DispatchBlock");
}
Assert.IsTrue (called, "Called DispatchBlock");
}
}

Просмотреть файл

@ -177,7 +177,7 @@ namespace MonoTouchFixtures.CoreFoundation {
Exception ex;
bool foundProxies;
// similar to the other tests, but we want to ensure that the async/await API works
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), async () => {
try {
CancellationTokenSource cancelSource = new CancellationTokenSource ();
CancellationToken cancelToken = cancelSource.Token;
@ -219,7 +219,7 @@ namespace MonoTouchFixtures.CoreFoundation {
Exception ex;
bool foundProxies;
// similar to the other tests, but we want to ensure that the async/await API works
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), async () => {
try {
CancellationTokenSource cancelSource = new CancellationTokenSource ();
CancellationToken cancelToken = cancelSource.Token;
@ -290,7 +290,7 @@ namespace MonoTouchFixtures.CoreFoundation {
Exception ex;
bool foundProxies;
// similar to the other tests, but we want to ensure that the async/await API works
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), async () => {
try {
CancellationTokenSource cancelSource = new CancellationTokenSource ();
CancellationToken cancelToken = cancelSource.Token;
@ -329,7 +329,7 @@ namespace MonoTouchFixtures.CoreFoundation {
Exception ex;
bool foundProxies;
// similar to the other tests, but we want to ensure that the async/await API works
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), async () => {
try {
CancellationTokenSource cancelSource = new CancellationTokenSource ();
CancellationToken cancelToken = cancelSource.Token;

Просмотреть файл

@ -33,7 +33,7 @@ namespace MonoTouchFixtures.CoreGraphics {
{
// Render an image with a pattern, and show it briefly on screen.
// It's supposed to show a blue oval with green plus signs inside.
TestRuntime.RunAsync (DateTime.Now.AddSeconds (0.1), () => { }, () => true, GetRenderedPattern ());
TestRuntime.RunAsync (TimeSpan.FromSeconds (0.1), () => { }, () => true, GetRenderedPattern ());
}
public UIImage GetRenderedPattern ()

Просмотреть файл

@ -80,7 +80,7 @@ namespace MonoTouchFixtures.CoreServices {
var taskCompletionSource = new TaskCompletionSource<CFHTTPMessage> ();
// the following code has to be in a diff thread, else, we are blocking the current loop, not cool
// perform a request so that we fail in the auth, then create the auth object and check the count
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), async () => {
using (var request = CFHTTPMessage.CreateRequest (
new Uri (NetworkResources.Httpbin.GetStatusCodeUrl (HttpStatusCode.Unauthorized)), "GET", null)) {
request.SetBody (Array.Empty<byte> ()); // empty body, we are not interested

Просмотреть файл

@ -73,28 +73,19 @@ namespace MonoTouchFixtures.Foundation {
// Networking seems broken on our macOS 10.9 bot, so skip this test.
TestRuntime.AssertSystemVersion (ApplePlatform.MacOSX, 10, 10, throwIfOtherPlatform: false);
Exception ex = null;
var done = new ManualResetEvent (false);
var success = false;
Task.Run (async () => {
try {
var config = NSUrlSessionConfiguration.DefaultSessionConfiguration;
config.WeakProtocolClasses = NSArray.FromNSObjects (new Class (typeof (CustomUrlProtocol)));
var session = NSUrlSession.FromConfiguration (config);
var custom_url = new NSUrl ("foo://server");
using (var task = await session.CreateDownloadTaskAsync (custom_url)) {
success = true;
}
} catch (Exception e) {
ex = e;
} finally {
done.Set ();
var task = Task.Run (async () => {
var config = NSUrlSessionConfiguration.DefaultSessionConfiguration;
config.WeakProtocolClasses = NSArray.FromNSObjects (new Class (typeof (CustomUrlProtocol)));
var session = NSUrlSession.FromConfiguration (config);
var custom_url = new NSUrl ("foo://server");
using (var task = await session.CreateDownloadTaskAsync (custom_url)) {
success = true;
}
});
Assert.IsTrue (TestRuntime.RunAsync (DateTime.Now.AddSeconds (10), () => { }, () => done.WaitOne (0)), "Timed out");
Assert.IsNull (ex, "Exception");
Assert.IsTrue (TestRuntime.RunAsync (TimeSpan.FromSeconds (10), task), "Timed out");
Assert.That (CustomUrlProtocol.State, Is.EqualTo (5), "State");
Assert.IsTrue (success, "Success");
}

Просмотреть файл

@ -9,6 +9,7 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Foundation;
#if MONOMAC
@ -26,8 +27,10 @@ namespace MonoTouchFixtures.Foundation {
[TestFixture]
[Preserve (AllMembers = true)]
public class UrlSessionTest {
void AssertTrueOrIgnoreInCI (bool value, ref Exception ex, string message)
void AssertTrueOrIgnoreInCI (Task task, string message)
{
var value = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), task, out var ex);
if (value) {
TestRuntime.IgnoreInCIIfBadNetwork (ex);
Assert.IsNull (ex, message + " Exception");
@ -35,11 +38,10 @@ namespace MonoTouchFixtures.Foundation {
}
TestRuntime.IgnoreInCI ($"This test times out randomly in CI due to bad network: {message}");
Assert.IsNull (ex, $"Exception - {message}");
Assert.Fail (message);
}
//TODO: TestRuntime.RunAsync is not on mac currently
#if !MONOMAC
// FIXME all test cases are failing on bots with Xcode 8 / watchOS 3
#if !__WATCHOS__
[Test]
@ -55,84 +57,20 @@ namespace MonoTouchFixtures.Foundation {
var file_url = NSUrl.FromFilename (tmpfile);
var file_data = NSData.FromFile (tmpfile);
var request = new NSUrlRequest (url);
var completed = false;
var timeout = 30;
Exception ex = null;
var uploadRequest = new NSMutableUrlRequest (url);
uploadRequest.HttpMethod = "POST";
/* CreateDataTask */
completed = false;
AssertTrueOrIgnoreInCI (TestRuntime.RunAsync (DateTime.Now.AddSeconds (timeout), async () => {
try {
await session.CreateDataTaskAsync (request);
} catch (Exception e) {
ex = e;
} finally {
completed = true;
}
}, () => completed), ref ex, "CreateDataTask a");
completed = false;
AssertTrueOrIgnoreInCI (TestRuntime.RunAsync (DateTime.Now.AddSeconds (timeout), async () => {
try {
await session.CreateDataTaskAsync (url);
} catch (Exception e) {
ex = e;
} finally {
completed = true;
}
}, () => completed), ref ex, "CreateDataTask b");
AssertTrueOrIgnoreInCI (session.CreateDataTaskAsync (request), "CreateDataTask a");
AssertTrueOrIgnoreInCI (session.CreateDataTaskAsync (url), "CreateDataTask b");
/* CreateDownloadTask */
completed = false;
AssertTrueOrIgnoreInCI (TestRuntime.RunAsync (DateTime.Now.AddSeconds (timeout), async () => {
try {
await session.CreateDownloadTaskAsync (request);
} catch (Exception e) {
ex = e;
} finally {
completed = true;
}
}, () => completed), ref ex, "CreateDownloadTask a");
completed = false;
AssertTrueOrIgnoreInCI (TestRuntime.RunAsync (DateTime.Now.AddSeconds (timeout), async () => {
try {
await session.CreateDownloadTaskAsync (url);
} catch (Exception e) {
ex = e;
} finally {
completed = true;
}
}, () => completed), ref ex, "CreateDownloadTask b");
AssertTrueOrIgnoreInCI (session.CreateDownloadTaskAsync (request), "CreateDownloadTask a");
AssertTrueOrIgnoreInCI (session.CreateDownloadTaskAsync (url), "CreateDownloadTask b");
/* CreateUploadTask */
completed = false;
AssertTrueOrIgnoreInCI (TestRuntime.RunAsync (DateTime.Now.AddSeconds (timeout), async () => {
try {
var uploadRequest = new NSMutableUrlRequest (url);
uploadRequest.HttpMethod = "POST";
await session.CreateUploadTaskAsync (uploadRequest, file_url);
} catch /* (Exception ex) */ {
// Console.WriteLine ("Ex: {0}", ex);
} finally {
completed = true;
}
}, () => completed), ref ex, "CreateUploadTask a");
completed = false;
AssertTrueOrIgnoreInCI (TestRuntime.RunAsync (DateTime.Now.AddSeconds (timeout), async () => {
try {
var uploadRequest = new NSMutableUrlRequest (url);
uploadRequest.HttpMethod = "POST";
await session.CreateUploadTaskAsync (uploadRequest, file_data);
} catch /* (Exception ex) */ {
// Console.WriteLine ("Ex: {0}", ex);
} finally {
completed = true;
}
}, () => completed), ref ex, "CreateUploadTask b");
AssertTrueOrIgnoreInCI (session.CreateUploadTaskAsync (uploadRequest, file_url), "CreateUploadTask a");
AssertTrueOrIgnoreInCI (session.CreateUploadTaskAsync (uploadRequest, file_data), "CreateUploadTask b");
}
[Test]
@ -140,38 +78,29 @@ namespace MonoTouchFixtures.Foundation {
{
TestRuntime.AssertXcodeVersion (5, 0);
bool completed = false;
int failed_iteration = -1;
Exception ex = null;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
for (int i = 0; i < 5; i++) {
// Use the default configuration so we can make use of the shared cookie storage.
var session = NSUrlSession.FromConfiguration (NSUrlSessionConfiguration.DefaultSessionConfiguration);
var rv = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
for (int i = 0; i < 5; i++) {
// Use the default configuration so we can make use of the shared cookie storage.
var session = NSUrlSession.FromConfiguration (NSUrlSessionConfiguration.DefaultSessionConfiguration);
var downloadUri = NetworkResources.MicrosoftUri;
var downloadResponse = await session.CreateDownloadTaskAsync (downloadUri);
var downloadUri = NetworkResources.MicrosoftUri;
var downloadResponse = await session.CreateDownloadTaskAsync (downloadUri);
var tempLocation = downloadResponse.Location;
if (!File.Exists (tempLocation.Path)) {
Console.WriteLine ("#{1} {0} does not exists", tempLocation, i);
failed_iteration = i;
break;
}
var tempLocation = downloadResponse.Location;
if (!File.Exists (tempLocation.Path)) {
Console.WriteLine ("#{1} {0} does not exists", tempLocation, i);
failed_iteration = i;
break;
}
} catch (Exception e) {
ex = e;
} finally {
completed = true;
}
}, () => completed);
}, out var ex);
TestRuntime.IgnoreInCIIfBadNetwork (ex);
Assert.IsNull (ex, "Exception");
Assert.AreEqual (-1, failed_iteration, "Failed");
}
#endif
[Test]
public void SharedSession ()

Просмотреть файл

@ -2,33 +2,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Foundation;
using UIKit;
using ObjCRuntime;
using System.Runtime.InteropServices;
partial class TestRuntime {
public static bool RunAsync (TimeSpan timeout, Action action, Func<bool> check_completed, UIImage imageToShow = null)
{
return RunAsync (DateTime.Now.Add (timeout), action, check_completed, imageToShow);
}
public static bool RunAsync (DateTime timeout, Action action, Func<bool> check_completed, UIImage imageToShow = null)
{
#if __WATCHOS__
NSTimer.CreateScheduledTimer (0.01, (v) => action ());
do {
if (timeout < DateTime.Now)
return false;
NSRunLoop.Main.RunUntil (NSDate.Now.AddSeconds (0.1));
} while (!check_completed ());
return true;
#else
return AppDelegate.RunAsync (timeout, action, check_completed, imageToShow);
#endif
}
}
#nullable enable
// This prevents the need for putting lots of #ifdefs inside the list of usings.
#if __WATCHOS__

Просмотреть файл

@ -91,7 +91,7 @@ namespace MonoTouchFixtures.MetalPerformanceShadersGraph {
completed = true;
});
Assert.IsTrue (TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
Assert.IsTrue (TestRuntime.RunAsync (TimeSpan.FromSeconds (30), async () => {
}, () => completed), "Completion");
// Don't need to commit since EncodeTrainingBatch oddly does that

Просмотреть файл

@ -91,7 +91,7 @@ namespace MonoTouchFixtures.Network {
var changesEvent = new AutoResetEvent (false);
var browserReady = new AutoResetEvent (false);
var finalEvent = new AutoResetEvent (false);
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), async () => {
// start the browser, before the listener
browser.SetStateChangesHandler ((st, er) => {
// assert here with a `st` of `Fail`

Просмотреть файл

@ -64,7 +64,7 @@ namespace MonoTouchFixtures.Network {
}
[TearDown]
public void TearDown () => connection.Dispose ();
public void TearDown () => connection?.Dispose ();
[Test]
public void TestEndpointProperty () => Assert.IsNotNull (connection.Endpoint);

Просмотреть файл

@ -28,7 +28,7 @@ namespace monotouchtest.Network {
NWPath finalPath = null;
bool isPathUpdated = false;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), async () => {
monitor.SnapshotHandler = ((path) => {
if (path is not null) {
@ -64,7 +64,7 @@ namespace monotouchtest.Network {
}
});
monitor.Start ();
TestRuntime.RunAsync (DateTime.Now.AddSeconds (3), () => { }, () => oldPath is not null);
TestRuntime.RunAsync (TimeSpan.FromSeconds (3), () => { }, () => oldPath is not null);
// Set a different handler
monitor.SnapshotHandler = ((path) => {
@ -73,7 +73,7 @@ namespace monotouchtest.Network {
}
});
monitor.Start ();
TestRuntime.RunAsync (DateTime.Now.AddSeconds (3), () => { }, () => newPath is not null);
TestRuntime.RunAsync (TimeSpan.FromSeconds (3), () => { }, () => newPath is not null);
monitor.Cancel ();
Assert.IsNotNull (oldPath, "oldPath set (no timeout)");

Просмотреть файл

@ -2,6 +2,8 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using CoreFoundation;
using Foundation;
using Network;
@ -167,27 +169,26 @@ namespace MonoTouchFixtures.Network {
[Test]
public void EnumerateGatewayTest ()
{
var e1 = new ManualResetEvent (false);
var e2 = new ManualResetEvent (false);
var e1 = new TaskCompletionSource<bool> ();
var e2 = new TaskCompletionSource<bool> ();
var monitor = new NWPathMonitor ();
try {
monitor.SetQueue (DispatchQueue.DefaultGlobalQueue);
monitor.Start ();
monitor.SnapshotHandler += path => {
path.EnumerateGateways (gateway => {
e1.Set ();
e1.TrySetResult (true);
return true;
});
path.EnumerateInterfaces (@interface => {
e2.Set ();
e2.TrySetResult (true);
return true;
});
};
TestRuntime.RunAsync (TimeSpan.FromSeconds (5),
() => { },
() => WaitHandle.WaitAll (new WaitHandle [] { e1, e2 }, 0));
var rv = WaitHandle.WaitAll (new WaitHandle [] { e1, e2 }, 10000);
var rv = TestRuntime.RunAsync (TimeSpan.FromSeconds (5),
Task.CompletedTask,
Task.WhenAll (e1.Task, e2.Task));
if (!rv)
TestRuntime.IgnoreInCI ("This test doesn't seem to be working on the bots, uncommon network setup?");
Assert.IsTrue (rv, "Called back");

Просмотреть файл

@ -2127,7 +2127,7 @@ namespace MonoTouchFixtures.ObjCRuntime {
thread.Join ();
GC.Collect ();
GC.WaitForPendingFinalizers ();
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), () => { }, () => ObjCBlockTester.FreedBlockCount > initialFreedCount);
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), () => { }, () => ObjCBlockTester.FreedBlockCount > initialFreedCount);
Assert.IsNull (ex, "No exceptions");
Assert.That (ObjCBlockTester.FreedBlockCount, Is.GreaterThan (initialFreedCount), "freed blocks");
}

Просмотреть файл

@ -5,6 +5,7 @@ using System.Drawing;
#endif
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using CoreGraphics;
using Foundation;
@ -805,7 +806,7 @@ Additional information:
});
// Iterate over the runloop in case something has to happen on the main thread for the objects to be collected.
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), () => { }, checkForCollectedManagedObjects);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), checkForCollectedManagedObjects);
Assert.IsTrue (checkForCollectedManagedObjects (), "Any collected objects");
@ -843,7 +844,7 @@ Additional information:
t.Start ();
Assert.IsTrue (t.Join (TimeSpan.FromSeconds (10)), "Background thread completion");
TestRuntime.RunAsync (TimeSpan.FromSeconds (2), () => { }, () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (2), () => {
// Iterate over the runloop a bit to make sure we're just not collecting because objects are queued on for things to happen on the main thread
GC.Collect ();
GC.WaitForPendingFinalizers ();

Просмотреть файл

@ -14,6 +14,7 @@ using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Foundation;
#if MONOMAC
@ -84,26 +85,26 @@ namespace MonoTouchFixtures.Security {
using (var queue = new DispatchQueue ("TrustAsync")) {
bool assert = false; // we don't want to assert in another queue
bool called = false;
var called = new TaskCompletionSource<bool> ();
var err = trust.Evaluate (DispatchQueue.MainQueue, (t, result) => {
assert = t.Handle == trust.Handle && result == expectedTrust;
called = true;
called.SetResult (true);
});
Assert.That (err, Is.EqualTo (SecStatusCode.Success), "async1/err");
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), () => { }, () => called);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), called.Task);
Assert.True (assert, "async1");
}
if (TestRuntime.CheckXcodeVersion (11, 0)) {
using (var queue = new DispatchQueue ("TrustErrorAsync")) {
bool assert = false; // we don't want to assert in another queue
bool called = false;
var called = new TaskCompletionSource<bool> ();
var err = trust.Evaluate (DispatchQueue.MainQueue, (t, result, error) => {
assert = t.Handle == trust.Handle && !result && error is not null;
called = true;
called.SetResult (true);
});
Assert.That (err, Is.EqualTo (SecStatusCode.Success), "async2/err");
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), () => { }, () => called);
TestRuntime.RunAsync (TimeSpan.FromSeconds (5), called.Task);
Assert.True (assert, "async2");
}
}

Просмотреть файл

@ -34,18 +34,6 @@ namespace MonoTests.System.Net.Http {
TestRuntime.AssertSystemVersion (ApplePlatform.MacOSX, 10, 10, throwIfOtherPlatform: false);
}
void PrintHandlerToTest ()
{
#if !__WATCHOS__
Console.WriteLine (new HttpClientHandler ());
Console.WriteLine (new CFNetworkHandler ());
#if NET
Console.WriteLine (new SocketsHttpHandler ());
#endif
#endif
Console.WriteLine (new NSUrlSessionHandler ());
}
HttpMessageHandler GetHandler (Type handler_type)
{
#if !__WATCHOS__
@ -78,22 +66,12 @@ namespace MonoTests.System.Net.Http {
TestRuntime.AssertSystemVersion (ApplePlatform.MacOSX, 10, 9, throwIfOtherPlatform: false);
TestRuntime.AssertSystemVersion (ApplePlatform.iOS, 7, 0, throwIfOtherPlatform: false);
PrintHandlerToTest ();
bool done = false;
string response = null;
Exception ex = null;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
HttpClient client = new HttpClient (GetHandler (handlerType));
response = await client.GetStringAsync ("http://doesnotexist.xamarin.com");
} catch (Exception e) {
ex = e;
} finally {
done = true;
}
}, () => done);
var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
HttpClient client = new HttpClient (GetHandler (handlerType));
response = await client.GetStringAsync ("http://doesnotexist.xamarin.com");
}, out var ex);
Assert.IsTrue (done, "Did not time out");
Assert.IsNull (response, $"Response is not null {response}");
@ -107,34 +85,26 @@ namespace MonoTests.System.Net.Http {
{
var managedCookieResult = false;
var nativeCookieResult = false;
Exception ex = null;
var completed = false;
IEnumerable<string> nativeCookies = null;
IEnumerable<string> managedCookies = null;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
var completed = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
var url = NetworkResources.Httpbin.GetSetCookieUrl ("cookie", "chocolate-chip");
try {
var managedHandler = new HttpClientHandler () {
AllowAutoRedirect = false,
};
var managedClient = new HttpClient (managedHandler);
var managedResponse = await managedClient.GetAsync (url);
managedCookieResult = managedResponse.Headers.TryGetValues ("Set-Cookie", out managedCookies);
var managedHandler = new HttpClientHandler () {
AllowAutoRedirect = false,
};
var managedClient = new HttpClient (managedHandler);
var managedResponse = await managedClient.GetAsync (url);
managedCookieResult = managedResponse.Headers.TryGetValues ("Set-Cookie", out managedCookies);
var nativeHandler = new NSUrlSessionHandler () {
AllowAutoRedirect = false,
};
nativeHandler.AllowAutoRedirect = true;
var nativeClient = new HttpClient (nativeHandler);
var nativeResponse = await nativeClient.GetAsync (url);
nativeCookieResult = nativeResponse.Headers.TryGetValues ("Set-Cookie", out nativeCookies);
} catch (Exception e) {
ex = e;
} finally {
completed = true;
}
}, () => completed);
var nativeHandler = new NSUrlSessionHandler () {
AllowAutoRedirect = false,
};
nativeHandler.AllowAutoRedirect = true;
var nativeClient = new HttpClient (nativeHandler);
var nativeResponse = await nativeClient.GetAsync (url);
nativeCookieResult = nativeResponse.Headers.TryGetValues ("Set-Cookie", out nativeCookies);
}, out var ex);
if (!completed || !managedCookieResult || !nativeCookieResult)
TestRuntime.IgnoreInCI ("Transient network failure - ignore in CI");
@ -159,32 +129,24 @@ namespace MonoTests.System.Net.Http {
string managedCookieResult = null;
string nativeCookieResult = null;
Exception ex = null;
var completed = false;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
var managedHandler = new HttpClientHandler () {
AllowAutoRedirect = false,
CookieContainer = cookieContainer,
};
var managedClient = new HttpClient (managedHandler);
var managedResponse = await managedClient.GetAsync (url);
managedCookieResult = await managedResponse.Content.ReadAsStringAsync ();
var completed = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
var managedHandler = new HttpClientHandler () {
AllowAutoRedirect = false,
CookieContainer = cookieContainer,
};
var managedClient = new HttpClient (managedHandler);
var managedResponse = await managedClient.GetAsync (url);
managedCookieResult = await managedResponse.Content.ReadAsStringAsync ();
var nativeHandler = new NSUrlSessionHandler () {
AllowAutoRedirect = true,
CookieContainer = cookieContainer,
};
var nativeClient = new HttpClient (nativeHandler);
var nativeResponse = await nativeClient.GetAsync (url);
nativeCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
} catch (Exception e) {
ex = e;
} finally {
completed = true;
}
}, () => completed);
var nativeHandler = new NSUrlSessionHandler () {
AllowAutoRedirect = true,
CookieContainer = cookieContainer,
};
var nativeClient = new HttpClient (nativeHandler);
var nativeResponse = await nativeClient.GetAsync (url);
nativeCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
}, out var ex);
if (!completed || managedCookieResult.Contains ("502 Bad Gateway") || nativeCookieResult.Contains ("502 Bad Gateway") || managedCookieResult.Contains ("504 Gateway Time-out") || nativeCookieResult.Contains ("504 Gateway Time-out"))
TestRuntime.IgnoreInCI ("Transient network failure - ignore in CI");
@ -203,25 +165,16 @@ namespace MonoTests.System.Net.Http {
var cookieContainer = new CookieContainer ();
string nativeCookieResult = null;
Exception ex = null;
var completed = false;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
var nativeHandler = new NSUrlSessionHandler () {
AllowAutoRedirect = true,
CookieContainer = cookieContainer,
};
var nativeClient = new HttpClient (nativeHandler);
var nativeResponse = await nativeClient.GetAsync (url);
nativeCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
} catch (Exception e) {
ex = e;
} finally {
completed = true;
}
}, () => completed);
var completed = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
var nativeHandler = new NSUrlSessionHandler () {
AllowAutoRedirect = true,
CookieContainer = cookieContainer,
};
var nativeClient = new HttpClient (nativeHandler);
var nativeResponse = await nativeClient.GetAsync (url);
nativeCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
}, out var ex);
if (!completed)
TestRuntime.IgnoreInCI ("Transient network failure - ignore in CI");
@ -244,31 +197,20 @@ namespace MonoTests.System.Net.Http {
string nativeSetCookieResult = null;
string nativeCookieResult = null;
var completed = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
var nativeHandler = new NSUrlSessionHandler () {
AllowAutoRedirect = true,
UseCookies = false,
};
var nativeClient = new HttpClient (nativeHandler);
var nativeResponse = await nativeClient.GetAsync (url);
nativeSetCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
Exception ex = null;
var completed = false;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
var nativeHandler = new NSUrlSessionHandler () {
AllowAutoRedirect = true,
UseCookies = false,
};
var nativeClient = new HttpClient (nativeHandler);
var nativeResponse = await nativeClient.GetAsync (url);
nativeSetCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
// got the response, perofm a second queries to the cookies endpoint to get
// the actual cookies sent from the storage
nativeResponse = await nativeClient.GetAsync (NetworkResources.Httpbin.CookiesUrl);
nativeCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
} catch (Exception e) {
ex = e;
} finally {
completed = true;
}
}, () => completed);
// got the response, perofm a second queries to the cookies endpoint to get
// the actual cookies sent from the storage
nativeResponse = await nativeClient.GetAsync (NetworkResources.Httpbin.CookiesUrl);
nativeCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
}, out var ex);
if (!completed)
TestRuntime.IgnoreInCI ("Transient network failure - ignore in CI");
@ -290,31 +232,20 @@ namespace MonoTests.System.Net.Http {
string nativeCookieResult = null;
var cookieContainer = new CookieContainer ();
var completed = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
var nativeHandler = new NSUrlSessionHandler () {
AllowAutoRedirect = true,
UseCookies = false,
};
var nativeClient = new HttpClient (nativeHandler);
var nativeResponse = await nativeClient.GetAsync (url);
nativeSetCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
Exception ex = null;
var completed = false;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
var nativeHandler = new NSUrlSessionHandler () {
AllowAutoRedirect = true,
UseCookies = false,
};
var nativeClient = new HttpClient (nativeHandler);
var nativeResponse = await nativeClient.GetAsync (url);
nativeSetCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
// got the response, preform a second queries to the cookies endpoint to get
// the actual cookies sent from the storage
nativeResponse = await nativeClient.GetAsync (NetworkResources.Httpbin.CookiesUrl);
nativeCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
} catch (Exception e) {
ex = e;
} finally {
completed = true;
}
}, () => completed);
// got the response, preform a second queries to the cookies endpoint to get
// the actual cookies sent from the storage
nativeResponse = await nativeClient.GetAsync (NetworkResources.Httpbin.CookiesUrl);
nativeCookieResult = await nativeResponse.Content.ReadAsStringAsync ();
}, out var ex);
if (!completed)
TestRuntime.IgnoreInCI ("Transient network failure - ignore in CI");
@ -357,26 +288,18 @@ namespace MonoTests.System.Net.Http {
bool containsAuthorizarion = false;
bool containsHeaders = false;
string json = "";
bool done = false;
Exception ex = null;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
HttpClient client = new HttpClient (GetHandler (handlerType));
client.BaseAddress = NetworkResources.Httpbin.Uri;
var byteArray = new UTF8Encoding ().GetBytes ("username:password");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ("Basic", Convert.ToBase64String (byteArray));
var result = await client.GetAsync (NetworkResources.Httpbin.GetRedirectUrl (3));
// get the data returned from httpbin which contains the details of the requested performed.
json = await result.Content.ReadAsStringAsync ();
containsAuthorizarion = json.Contains ("Authorization");
containsHeaders = json.Contains ("headers"); // ensure we do have the headers in the response
} catch (Exception e) {
ex = e;
} finally {
done = true;
}
}, () => done);
var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
HttpClient client = new HttpClient (GetHandler (handlerType));
client.BaseAddress = NetworkResources.Httpbin.Uri;
var byteArray = new UTF8Encoding ().GetBytes ("username:password");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ("Basic", Convert.ToBase64String (byteArray));
var result = await client.GetAsync (NetworkResources.Httpbin.GetRedirectUrl (3));
// get the data returned from httpbin which contains the details of the requested performed.
json = await result.Content.ReadAsStringAsync ();
containsAuthorizarion = json.Contains ("Authorization");
containsHeaders = json.Contains ("headers"); // ensure we do have the headers in the response
}, out var ex);
if (!done) { // timeouts happen in the bots due to dns issues, connection issues etc.. we do not want to fail
Assert.Inconclusive ("Request timedout.");
@ -410,8 +333,6 @@ namespace MonoTests.System.Net.Http {
bool validationCbWasExecuted = false;
bool customValidationCbWasExecuted = false;
bool invalidServicePointManagerCbWasExcuted = false;
bool done = false;
Exception ex = null;
Type expectedExceptionType = null;
HttpResponseMessage result = null;
@ -456,20 +377,17 @@ namespace MonoTests.System.Net.Http {
Assert.Fail ($"Invalid HttpMessageHandler: '{handler.GetType ()}'.");
}
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
try {
HttpClient client = new HttpClient (handler);
client.BaseAddress = NetworkResources.Httpbin.Uri;
var byteArray = new UTF8Encoding ().GetBytes ("username:password");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ("Basic", Convert.ToBase64String (byteArray));
result = await client.GetAsync (NetworkResources.Httpbin.GetRedirectUrl (3));
} catch (Exception e) {
ex = e;
} finally {
done = true;
ServicePointManager.ServerCertificateValidationCallback = null;
}
}, () => done);
}, out var ex);
if (!done) { // timeouts happen in the bots due to dns issues, connection issues etc.. we do not want to fail
Assert.Inconclusive ("Request timedout.");
@ -495,8 +413,6 @@ namespace MonoTests.System.Net.Http {
TestRuntime.AssertSystemVersion (ApplePlatform.iOS, 7, 0, throwIfOtherPlatform: false);
bool servicePointManagerCbWasExcuted = false;
bool done = false;
Exception ex = null;
var handler = GetHandler (handlerType);
if (handler is NSUrlSessionHandler ns) {
@ -515,20 +431,17 @@ namespace MonoTests.System.Net.Http {
};
}
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
try {
HttpClient client = new HttpClient (handler);
client.BaseAddress = NetworkResources.Httpbin.Uri;
var byteArray = new UTF8Encoding ().GetBytes ("username:password");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ("Basic", Convert.ToBase64String (byteArray));
var result = await client.GetAsync (NetworkResources.Httpbin.GetRedirectUrl (3));
} catch (Exception e) {
ex = e;
} finally {
done = true;
ServicePointManager.ServerCertificateValidationCallback = null;
}
}, () => done);
}, out var ex);
if (!done) { // timeouts happen in the bots due to dns issues, connection issues etc.. we do not want to fail
Assert.Inconclusive ("Request timedout.");
@ -539,6 +452,7 @@ namespace MonoTests.System.Net.Http {
Assert.AreNotEqual (ex.InnerException.Message, "Error: TrustFailure");
}
}
Assert.IsNull (ex);
}
#if NET
@ -550,8 +464,6 @@ namespace MonoTests.System.Net.Http {
TestRuntime.AssertSystemVersion (ApplePlatform.iOS, 7, 0, throwIfOtherPlatform: false);
bool callbackWasExecuted = false;
bool done = false;
Exception ex = null;
HttpResponseMessage result = null;
X509Certificate2 serverCertificate = null;
SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None;
@ -565,16 +477,10 @@ namespace MonoTests.System.Net.Http {
}
};
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
var client = new HttpClient (handler);
result = await client.GetAsync (url);
} catch (Exception e) {
ex = e;
} finally {
done = true;
}
}, () => done);
var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
var client = new HttpClient (handler);
result = await client.GetAsync (url);
}, out var ex);
if (!done) { // timeouts happen in the bots due to dns issues, connection issues etc.. we do not want to fail
Assert.Inconclusive ("Request timedout.");
@ -595,8 +501,6 @@ namespace MonoTests.System.Net.Http {
TestRuntime.AssertSystemVersion (ApplePlatform.iOS, 7, 0, throwIfOtherPlatform: false);
bool callbackWasExecuted = false;
bool done = false;
Exception ex = null;
Exception ex2 = null;
HttpResponseMessage result = null;
@ -608,6 +512,8 @@ namespace MonoTests.System.Net.Http {
if (errors == SslPolicyErrors.RemoteCertificateChainErrors && TestRuntime.IsInCI)
return false;
Assert.AreEqual (SslPolicyErrors.None, errors);
} catch (ResultStateException) {
throw;
} catch (Exception e) {
ex2 = e;
}
@ -615,16 +521,10 @@ namespace MonoTests.System.Net.Http {
}
};
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
var client = new HttpClient (handler);
result = await client.GetAsync (url);
} catch (Exception e) {
ex = e;
} finally {
done = true;
}
}, () => done);
var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
var client = new HttpClient (handler);
result = await client.GetAsync (url);
}, out var ex);
if (!done) { // timeouts happen in the bots due to dns issues, connection issues etc.. we do not want to fail
Assert.Inconclusive ("Request timedout.");
@ -666,20 +566,11 @@ namespace MonoTests.System.Net.Http {
var client = new HttpClient (handler);
bool done = false;
HttpStatusCode httpStatus = HttpStatusCode.NotFound;
Exception ex = null;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
var result = await client.GetAsync (NetworkResources.Httpbin.GetBasicAuthUrl (validUsername, validPassword));
httpStatus = result.StatusCode;
} catch (Exception e) {
ex = e;
} finally {
done = true;
}
}, () => done);
var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
var result = await client.GetAsync (NetworkResources.Httpbin.GetBasicAuthUrl (validUsername, validPassword));
httpStatus = result.StatusCode;
}, out var ex);
if (!done) { // timeouts happen in the bots due to dns issues, connection issues etc.. we do not want to fail
Assert.Inconclusive ("Request timedout.");
@ -705,20 +596,11 @@ namespace MonoTests.System.Net.Http {
var firstClient = new HttpClient (firstHandler);
bool done = false;
HttpStatusCode httpStatus = HttpStatusCode.NotFound;
Exception ex = null;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
var result = await firstClient.GetAsync (url);
httpStatus = result.StatusCode;
} catch (Exception e) {
ex = e;
} finally {
done = true;
}
}, () => done);
var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
var result = await firstClient.GetAsync (url);
httpStatus = result.StatusCode;
}, out var ex);
if (!done) { // timeouts happen in the bots due to dns issues, connection issues etc.. we do not want to fail
Assert.Inconclusive ("First request timedout.");
@ -735,20 +617,11 @@ namespace MonoTests.System.Net.Http {
var secondClient = new HttpClient (secondHandler);
done = false;
httpStatus = HttpStatusCode.NotFound;
ex = null;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
try {
var result = await secondClient.GetAsync (url);
httpStatus = result.StatusCode;
} catch (Exception e) {
ex = e;
} finally {
done = true;
}
}, () => done);
done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => {
var result = await secondClient.GetAsync (url);
httpStatus = result.StatusCode;
}, out ex);
if (!done) { // timeouts happen in the bots due to dns issues, connection issues etc.. we do not want to fail
Assert.Inconclusive ("Second request timedout.");

Просмотреть файл

@ -82,7 +82,7 @@ namespace MonoTouchFixtures.UIKit {
}
pool.Dispose ();
TestRuntime.RunAsync (DateTime.Now.AddSeconds (1), () => { GC.Collect (); }, () => finalizedAnyCtor && finalizedAnyAddTarget1 && finalizedAnyAddTarget2);
TestRuntime.RunAsync (TimeSpan.FromSeconds (1), () => { GC.Collect (); }, () => finalizedAnyCtor && finalizedAnyAddTarget1 && finalizedAnyAddTarget2);
Assert.IsTrue (finalizedAnyCtor, "Any finalized");
Assert.IsTrue (finalizedAnyAddTarget1, "AddTarget1 finalized");
Assert.IsTrue (finalizedAnyAddTarget2, "AddTarget2 finalized");
@ -105,7 +105,7 @@ namespace MonoTouchFixtures.UIKit {
// add gesture recognizer to UI view
using UIView view = new UIView ();
view.AddGestureRecognizer (recognizer);
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), () => {
// change state of gesture recognizer to execute callback
recognizer.State = UIGestureRecognizerState.Changed;
recognizer.State = UIGestureRecognizerState.Ended;

Просмотреть файл

@ -40,7 +40,7 @@ namespace MonoTouchFixtures.UIKit {
var didSuccess = true;
var done = false;
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), async () => {
try {
var res = await UIGuidedAccessRestriction.ConfigureAccessibilityFeaturesAsync (UIGuidedAccessAccessibilityFeature.Zoom, true);
gotError = res.Error is not null; // We expect an error back from the API call.

Просмотреть файл

@ -25,7 +25,7 @@ namespace MonoTouchFixtures.WebKit {
var completed = false;
string d = Path.Combine (NSBundle.MainBundle.ResourcePath, "access-denied.html");
string g = Path.Combine (NSBundle.MainBundle.ResourcePath, "access-granted.html");
TestRuntime.RunAsync (DateTime.Now.AddSeconds (3000), async () => {
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), async () => {
using (var denied = NSUrl.FromFilename (d))
using (var granted = NSUrl.FromFilename (g)) {
var options = new NSAttributedStringDocumentAttributes {

Просмотреть файл

@ -12,9 +12,6 @@
<Compile Include="..\..\..\common\Configuration.cs">
<Link>Configuration.cs</Link>
</Compile>
<Compile Include="..\..\..\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
<Compile Include="..\..\..\common\ExecutionHelper.cs">
<Link>ExecutionHelper.cs</Link>
</Compile>

Просмотреть файл

@ -49,6 +49,9 @@
<Compile Include="$(RootTestsDirectory)\common\TestRuntime.cs">
<Link>TestRuntime.cs</Link>
</Compile>
<Compile Include="$(RootTestsDirectory)\common\TestRuntime.RunAsync.cs">
<Link>TestRuntime.RunAsync.cs</Link>
</Compile>
<Compile Include="$(RootTestsDirectory)\common\ConditionalCompilation.cs">
<Link>ConditionalCompilation.cs</Link>
</Compile>

Просмотреть файл

@ -58,7 +58,7 @@ namespace MonoTouchFixtures {
GC.WaitForPendingFinalizers ();
GC.WaitForPendingFinalizers ();
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), () => { }, () => MyParentView.weakcount < totalTestObjects);
TestRuntime.RunAsync (TimeSpan.FromSeconds (30), () => { }, () => MyParentView.weakcount < totalTestObjects);
Assert.That (MyParentView.weakcount, Is.LessThan (totalTestObjects), "No retain cycles expected");
}

Просмотреть файл

@ -200,6 +200,9 @@
<Compile Include="..\common\TestRuntime.cs">
<Link>TestRuntime.cs</Link>
</Compile>
<Compile Include="..\common\TestRuntime.RunAsync.cs">
<Link>TestRuntime.RunAsync.cs</Link>
</Compile>
<Compile Include="..\common\ConditionalCompilation.cs">
<Link>ConditionalCompilation.cs</Link>
</Compile>

Просмотреть файл

@ -121,15 +121,15 @@
<Compile Include="..\common\TestRuntime.cs">
<Link>TestRuntime.cs</Link>
</Compile>
<Compile Include="..\common\TestRuntime.RunAsync.cs">
<Link>TestRuntime.RunAsync.cs</Link>
</Compile>
<Compile Include="..\common\Extensions.cs">
<Link>Extensions.cs</Link>
</Compile>
<Compile Include="..\common\mac\MacMain.cs">
<Link>MacMain.cs</Link>
</Compile>
<Compile Include="..\common\mac\TestRuntime.macos.cs">
<Link>TestRuntime.macos.cs</Link>
</Compile>
<Compile Include="..\common\ExecutionHelper.cs">
<Link>ExecutionHelper.cs</Link>
</Compile>