Merge fixes of TestExecutionContext and testContext for async tests
This commit is contained in:
Коммит
5105746728
|
@ -6,12 +6,15 @@
|
|||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
|
||||
namespace NUnit.Core
|
||||
{
|
||||
public class ContextDictionary : Hashtable
|
||||
[Serializable]
|
||||
public class ContextDictionary : MarshalByRefObject, IDictionary, ILogicalThreadAffinative
|
||||
{
|
||||
internal TestExecutionContext _context;
|
||||
private readonly Hashtable _storage = new Hashtable();
|
||||
|
||||
public ContextDictionary() { }
|
||||
|
||||
|
@ -20,7 +23,7 @@ namespace NUnit.Core
|
|||
_context = context;
|
||||
}
|
||||
|
||||
public override object this[object key]
|
||||
public object this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -43,13 +46,87 @@ namespace NUnit.Core
|
|||
? _context.TestPackage.Settings["WorkDirectory"]
|
||||
: Environment.CurrentDirectory;
|
||||
default:
|
||||
return base[key];
|
||||
return _storage[key];
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
base[key] = value;
|
||||
_storage[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDictionary Interface non-implementation
|
||||
|
||||
void IDictionary.Remove(object key)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
ICollection IDictionary.Keys
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
ICollection IDictionary.Values
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
bool IDictionary.IsReadOnly
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
bool IDictionary.IsFixedSize
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
bool IDictionary.Contains(object key)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IDictionary.Add(object key, object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void IDictionary.Clear()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ICollection.CopyTo(Array array, int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
int ICollection.Count
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
object ICollection.SyncRoot
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
bool ICollection.IsSynchronized
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,8 +4,6 @@
|
|||
// obtain a copy of the license at http://nunit.org.
|
||||
// ****************************************************************
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
@ -398,7 +396,7 @@ namespace NUnit.Core
|
|||
public static void Save()
|
||||
{
|
||||
current = new TestExecutionContext(current);
|
||||
CallContext.SetData("NUnit.Framework.TestContext", current.contextDictionary);
|
||||
CallContext.LogicalSetData("NUnit.Framework.TestContext", current.contextDictionary);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -409,7 +407,7 @@ namespace NUnit.Core
|
|||
{
|
||||
current.ReverseChanges();
|
||||
current = current.prior;
|
||||
CallContext.SetData("NUnit.Framework.TestContext", current.contextDictionary);
|
||||
CallContext.LogicalSetData("NUnit.Framework.TestContext", current.contextDictionary);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ namespace NUnit.Core
|
|||
this.thrownException = null;
|
||||
this.listener = listener;
|
||||
this.filter = filter;
|
||||
this.contextDictionary = (ContextDictionary)CallContext.GetData("NUnit.Framework.TestContext");
|
||||
this.contextDictionary = (ContextDictionary)CallContext.LogicalGetData("NUnit.Framework.TestContext");
|
||||
|
||||
log.Debug("Starting test in separate thread");
|
||||
thread.Start();
|
||||
|
@ -133,7 +133,7 @@ namespace NUnit.Core
|
|||
/// </summary>
|
||||
private void RunTestProc()
|
||||
{
|
||||
CallContext.SetData("NUnit.Framework.TestContext", contextDictionary);
|
||||
CallContext.LogicalSetData("NUnit.Framework.TestContext", contextDictionary);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#if NET_3_5 || NET_4_0 || NET_4_5
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
@ -27,37 +26,42 @@ namespace nunit.core.tests.net45
|
|||
{
|
||||
get
|
||||
{
|
||||
yield return new object[] { Method("VoidTestSuccess"), ResultState.Success, 1 };
|
||||
yield return new object[] { Method("VoidTestFailure"), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method("VoidTestError"), ResultState.Error, 0 };
|
||||
yield return new object[] { Method("VoidTestExpectedException"), ResultState.Success, 0 };
|
||||
yield return new object[] { Method(f => f.VoidTestSuccess()), ResultState.Success, 1 };
|
||||
yield return new object[] { Method(f => f.VoidTestFailure()), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method(f => f.VoidTestError()), ResultState.Error, 0 };
|
||||
yield return new object[] { Method(f => f.VoidTestExpectedException()), ResultState.Success, 0 };
|
||||
|
||||
yield return new object[] { Method("TaskTestSuccess"), ResultState.Success, 1 };
|
||||
yield return new object[] { Method("TaskTestFailure"), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method("TaskTestError"), ResultState.Error, 0 };
|
||||
yield return new object[] { Method("TaskTestExpectedException"), ResultState.Success, 0 };
|
||||
yield return new object[] { Method(f => f.TaskTestSuccess()), ResultState.Success, 1 };
|
||||
yield return new object[] { Method(f => f.TaskTestFailure()), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method(f => f.TaskTestError()), ResultState.Error, 0 };
|
||||
yield return new object[] { Method(f => f.TaskTestExpectedException()), ResultState.Success, 0 };
|
||||
|
||||
yield return new object[] { Method("TaskTTestCaseWithResultCheckSuccess"), ResultState.Success, 0 };
|
||||
yield return new object[] { Method("TaskTTestCaseWithResultCheckFailure"), ResultState.Failure, 0 };
|
||||
yield return new object[] { Method("TaskTTestCaseWithResultCheckError"), ResultState.Failure, 0 };
|
||||
yield return new object[] { Method("TaskTTestCaseWithResultCheckSuccessReturningNull"), ResultState.Success, 0 };
|
||||
yield return new object[] { Method("TaskTTestCaseWithoutResultCheckExpectedExceptionSuccess"), ResultState.Success, 0 };
|
||||
yield return new object[] { Method(f => f.TaskTTestCaseWithResultCheckSuccess()), ResultState.Success, 0 };
|
||||
yield return new object[] { Method(f => f.TaskTTestCaseWithResultCheckFailure()), ResultState.Failure, 0 };
|
||||
yield return new object[] { Method(f => f.TaskTTestCaseWithResultCheckError()), ResultState.Failure, 0 };
|
||||
yield return new object[] { Method(f => f.TaskTTestCaseWithResultCheckSuccessReturningNull()), ResultState.Success, 0 };
|
||||
yield return new object[] { Method(f => f.TaskTTestCaseWithoutResultCheckExpectedExceptionSuccess()), ResultState.Success, 0 };
|
||||
|
||||
yield return new object[] { Method("NestedVoidTestSuccess"), ResultState.Success, 1 };
|
||||
yield return new object[] { Method("NestedVoidTestFailure"), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method("NestedVoidTestError"), ResultState.Error, 0 };
|
||||
yield return new object[] { Method(f => f.NestedVoidTestSuccess()), ResultState.Success, 1 };
|
||||
yield return new object[] { Method(f => f.NestedVoidTestFailure()), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method(f => f.NestedVoidTestError()), ResultState.Error, 0 };
|
||||
|
||||
yield return new object[] { Method("NestedTaskTestSuccess"), ResultState.Success, 1 };
|
||||
yield return new object[] { Method("NestedTaskTestFailure"), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method("NestedTaskTestError"), ResultState.Error, 0 };
|
||||
yield return new object[] { Method(f => f.NestedTaskTestSuccess()), ResultState.Success, 1 };
|
||||
yield return new object[] { Method(f => f.NestedTaskTestFailure()), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method(f => f.NestedTaskTestError()), ResultState.Error, 0 };
|
||||
|
||||
yield return new object[] { Method("VoidTestMultipleSuccess"), ResultState.Success, 1 };
|
||||
yield return new object[] { Method("VoidTestMultipleFailure"), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method("VoidTestMultipleError"), ResultState.Error, 0 };
|
||||
yield return new object[] { Method(f => f.VoidTestMultipleSuccess()), ResultState.Success, 1 };
|
||||
yield return new object[] { Method(f => f.VoidTestMultipleFailure()), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method(f => f.VoidTestMultipleError()), ResultState.Error, 0 };
|
||||
|
||||
yield return new object[] { Method("TaskTestMultipleSuccess"), ResultState.Success, 1 };
|
||||
yield return new object[] { Method("TaskTestMultipleFailure"), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method("TaskTestMultipleError"), ResultState.Error, 0 };
|
||||
yield return new object[] { Method(f => f.TaskTestMultipleSuccess()), ResultState.Success, 1 };
|
||||
yield return new object[] { Method(f => f.TaskTestMultipleFailure()), ResultState.Failure, 1 };
|
||||
yield return new object[] { Method(f => f.TaskTestMultipleError()), ResultState.Error, 0 };
|
||||
|
||||
yield return new object[] { Method(f => f.VoidCheckTestContextAcrossTasks()), ResultState.Success, 2 };
|
||||
yield return new object[] { Method(f => f.VoidCheckTestContextWithinTestBody()), ResultState.Success, 2 };
|
||||
yield return new object[] { Method(f => f.TaskCheckTestContextAcrossTasks()), ResultState.Success, 2 };
|
||||
yield return new object[] { Method(f => f.TaskCheckTestContextWithinTestBody()), ResultState.Success, 2 };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +85,7 @@ namespace nunit.core.tests.net45
|
|||
|
||||
SynchronizationContext.SetSynchronizationContext(context);
|
||||
|
||||
var method = _builder.BuildFrom(Method("VoidAssertSynchrnoizationContext"));
|
||||
var method = _builder.BuildFrom(Method(f => f.VoidAssertSynchronizationContext()));
|
||||
|
||||
var result = method.Run(new NullListener(), TestFilter.Empty);
|
||||
|
||||
|
@ -91,9 +95,9 @@ namespace nunit.core.tests.net45
|
|||
Assert.That(result.AssertCount, Is.EqualTo(1), "Wrong assertion count");
|
||||
}
|
||||
|
||||
private static MethodInfo Method(string name)
|
||||
private static MethodInfo Method(Expression<Action<AsyncRealFixture>> action)
|
||||
{
|
||||
return typeof (AsyncRealFixture).GetMethod(name);
|
||||
return ((MethodCallExpression)action.Body).Method;
|
||||
}
|
||||
|
||||
public class CustomSynchronizationContext : SynchronizationContext
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#if NET_3_5 || NET_4_0 || NET_4_5
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using NUnit.Core;
|
||||
using NUnit.Core.Builders;
|
||||
|
@ -23,9 +25,9 @@ namespace nunit.core.tests.net45
|
|||
{
|
||||
get
|
||||
{
|
||||
yield return new object[] { Method("AsyncVoidTest"), RunState.Runnable };
|
||||
yield return new object[] { Method("AsyncTaskTest"), RunState.Runnable };
|
||||
yield return new object[] { Method("AsyncTaskTTest"), RunState.NotRunnable };
|
||||
yield return new object[] { Method(f => f.AsyncVoidTest()), RunState.Runnable };
|
||||
yield return new object[] { Method(f => f.AsyncTaskTest()), RunState.Runnable };
|
||||
yield return new object[] { Method(f => f.AsyncTaskTTest()), RunState.NotRunnable };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,13 +35,13 @@ namespace nunit.core.tests.net45
|
|||
{
|
||||
get
|
||||
{
|
||||
yield return new object[] { Method("AsyncVoidTestCaseWithResultCheck"), RunState.NotRunnable };
|
||||
yield return new object[] { Method("AsyncTaskTestCaseWithResultCheck"), RunState.NotRunnable };
|
||||
yield return new object[] { Method("AsyncTaskTTestCaseWithResultCheck"), RunState.Runnable };
|
||||
yield return new object[] { Method("AsyncVoidTestCaseWithoutResultCheck"), RunState.Runnable };
|
||||
yield return new object[] { Method("AsyncTaskTestCaseWithoutResultCheck"), RunState.Runnable };
|
||||
yield return new object[] { Method("AsyncTaskTTestCaseWithoutResultCheck"), RunState.NotRunnable };
|
||||
yield return new object[] { Method("AsyncTaskTTestCaseExpectedExceptionWithoutResultCheck"), RunState.Runnable };
|
||||
yield return new object[] { Method(f => f.AsyncVoidTestCaseWithResultCheck()), RunState.NotRunnable };
|
||||
yield return new object[] { Method(f => f.AsyncTaskTestCaseWithResultCheck()), RunState.NotRunnable };
|
||||
yield return new object[] { Method(f => f.AsyncTaskTTestCaseWithResultCheck()), RunState.Runnable };
|
||||
yield return new object[] { Method(f => f.AsyncVoidTestCaseWithoutResultCheck()), RunState.Runnable };
|
||||
yield return new object[] { Method(f => f.AsyncTaskTestCaseWithoutResultCheck()), RunState.Runnable };
|
||||
yield return new object[] { Method(f => f.AsyncTaskTTestCaseWithoutResultCheck()), RunState.NotRunnable };
|
||||
yield return new object[] { Method(f => f.AsyncTaskTTestCaseExpectedExceptionWithoutResultCheck()), RunState.Runnable };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +69,7 @@ namespace nunit.core.tests.net45
|
|||
[Test]
|
||||
public void Non_async_task()
|
||||
{
|
||||
var built = _sut.BuildFrom(Method("NonAsyncTask"));
|
||||
var built = _sut.BuildFrom(Method(f => f.NonAsyncTask()));
|
||||
|
||||
Assert.That(built, Is.Not.InstanceOf<NUnitAsyncTestMethod>());
|
||||
Assert.That(built.RunState, Is.EqualTo(RunState.NotRunnable));
|
||||
|
@ -76,15 +78,15 @@ namespace nunit.core.tests.net45
|
|||
[Test]
|
||||
public void Non_async_task_with_result()
|
||||
{
|
||||
var built = _sut.BuildFrom(Method("NonAsyncTaskWithResult"));
|
||||
var built = _sut.BuildFrom(Method(f => f.NonAsyncTaskWithResult()));
|
||||
|
||||
Assert.That(built, Is.Not.InstanceOf<NUnitAsyncTestMethod>());
|
||||
Assert.That(built.RunState, Is.EqualTo(RunState.NotRunnable));
|
||||
}
|
||||
|
||||
public MethodInfo Method(string name)
|
||||
private static MethodInfo Method(Expression<Action<AsyncDummyFixture>> action)
|
||||
{
|
||||
return typeof (AsyncDummyFixture).GetMethod(name);
|
||||
return ((MethodCallExpression) action.Body).Method;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,13 +41,13 @@ namespace NUnit.Core.Tests
|
|||
[Test]
|
||||
public void ILogicalThreadAffinativeTest()
|
||||
{
|
||||
CallContext.SetData( CONTEXT_DATA, new EmptyCallContextData() );
|
||||
CallContext.LogicalSetData( CONTEXT_DATA, new EmptyCallContextData() );
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ILogicalThreadAffinativeTestConsole()
|
||||
{
|
||||
CallContext.SetData( CONTEXT_DATA, new EmptyCallContextData() );
|
||||
CallContext.LogicalSetData( CONTEXT_DATA, new EmptyCallContextData() );
|
||||
// TODO: make this Assertable
|
||||
//Console.WriteLine("ILogicalThreadAffinativeTest");
|
||||
Console.Out.Flush();
|
||||
|
@ -60,7 +60,7 @@ namespace NUnit.Core.Tests
|
|||
GenericPrincipal prpal = new GenericPrincipal(ident,
|
||||
new string[] {"Level1"});
|
||||
|
||||
CallContext.SetData( CONTEXT_DATA, new PrincipalCallContextData( prpal ) );
|
||||
CallContext.LogicalSetData( CONTEXT_DATA, new PrincipalCallContextData( prpal ) );
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using NUnit.TestData.TestContextData;
|
||||
using NUnit.TestUtilities;
|
||||
|
@ -232,9 +233,27 @@ namespace NUnit.Core.Tests
|
|||
}
|
||||
|
||||
[Test, RequiresThread]
|
||||
public void CanAccessTestContextOnSeparateThread()
|
||||
public void CanAccessTestContextWhenRunningTestOnSeparateThread()
|
||||
{
|
||||
Assert.That(TestContext.CurrentContext.Test.Name, Is.EqualTo("CanAccessTestContextOnSeparateThread"));
|
||||
Assert.That(TestContext.CurrentContext.Test.Name, Is.EqualTo("CanAccessTestContextWhenRunningTestOnSeparateThread"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanAccessTestContextFromThreadSpawnWithinTest()
|
||||
{
|
||||
var testName = new object[1];
|
||||
|
||||
var thread = new Thread(FillTestNameFromContext);
|
||||
thread.Start(testName);
|
||||
thread.Join();
|
||||
|
||||
Assert.IsNotNull(testName[0]);
|
||||
Assert.AreEqual(testName[0], TestContext.CurrentContext.Test.Name);
|
||||
}
|
||||
|
||||
private static void FillTestNameFromContext(object arg)
|
||||
{
|
||||
((object[])arg)[0] = TestContext.CurrentContext.Test.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@ namespace NUnit.Framework
|
|||
{
|
||||
get
|
||||
{
|
||||
return new TestContext((IDictionary)CallContext.GetData(contextKey));
|
||||
return new TestContext((IDictionary)CallContext.LogicalGetData(contextKey));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace test_assembly_net45
|
|||
}
|
||||
|
||||
[Test]
|
||||
public async void VoidAssertSynchrnoizationContext()
|
||||
public async void VoidAssertSynchronizationContext()
|
||||
{
|
||||
Assert.That(SynchronizationContext.Current, Is.InstanceOf<AsyncSynchronizationContext>());
|
||||
await Task.Yield();
|
||||
|
@ -174,7 +174,7 @@ namespace test_assembly_net45
|
|||
[Test]
|
||||
public async void VoidTestMultipleError()
|
||||
{
|
||||
var result = await ReturnOne();
|
||||
await ReturnOne();
|
||||
await ThrowException();
|
||||
|
||||
Assert.Fail("Should never get here");
|
||||
|
@ -199,12 +199,57 @@ namespace test_assembly_net45
|
|||
[Test]
|
||||
public async Task TaskTestMultipleError()
|
||||
{
|
||||
var result = await ReturnOne();
|
||||
await ReturnOne();
|
||||
await ThrowException();
|
||||
|
||||
Assert.Fail("Should never get here");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async void VoidCheckTestContextAcrossTasks()
|
||||
{
|
||||
var testName = await GetTestNameFromContext();
|
||||
|
||||
Assert.IsNotNull(testName);
|
||||
Assert.AreEqual(testName, TestContext.CurrentContext.Test.Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TaskCheckTestContextAcrossTasks()
|
||||
{
|
||||
var testName = await GetTestNameFromContext();
|
||||
|
||||
Assert.IsNotNull(testName);
|
||||
Assert.AreEqual(testName, TestContext.CurrentContext.Test.Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async void VoidCheckTestContextWithinTestBody()
|
||||
{
|
||||
var testName = TestContext.CurrentContext.Test.Name;
|
||||
|
||||
await ReturnOne();
|
||||
|
||||
Assert.IsNotNull(testName);
|
||||
Assert.AreEqual(testName, TestContext.CurrentContext.Test.Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TaskCheckTestContextWithinTestBody()
|
||||
{
|
||||
var testName = TestContext.CurrentContext.Test.Name;
|
||||
|
||||
await ReturnOne();
|
||||
|
||||
Assert.IsNotNull(testName);
|
||||
Assert.AreEqual(testName, TestContext.CurrentContext.Test.Name);
|
||||
}
|
||||
|
||||
private static Task<string> GetTestNameFromContext()
|
||||
{
|
||||
return Task.Run(() => TestContext.CurrentContext.Test.Name);
|
||||
}
|
||||
|
||||
private static Task<int> ReturnOne()
|
||||
{
|
||||
return Task.Run(() => 1);
|
||||
|
|
Загрузка…
Ссылка в новой задаче