test & fix

This commit is contained in:
Christian Köllner 2020-04-13 20:22:52 +02:00
parent a205b45d15
commit 4441ef6c8e
18 changed files with 206 additions and 95 deletions

View File

@ -176,5 +176,17 @@ namespace Capnp.Net.Runtime.Tests
{ {
NewDtbdctTestbed().RunTest(Testsuite.ReexportSenderPromise); NewDtbdctTestbed().RunTest(Testsuite.ReexportSenderPromise);
} }
[TestMethod]
public void CallAfterFinish1()
{
NewDtbdctTestbed().RunTest(Testsuite.CallAfterFinish1);
}
[TestMethod]
public void CallAfterFinish2()
{
NewDtbdctTestbed().RunTest(Testsuite.CallAfterFinish2);
}
} }
} }

View File

@ -29,6 +29,7 @@ namespace Capnp.Net.Runtime.Tests
{ {
var pipe = new Pipe(); var pipe = new Pipe();
_fromEnginePump = new FramePump(pipe.Writer.AsStream()); _fromEnginePump = new FramePump(pipe.Writer.AsStream());
_fromEnginePump.AttachTracer(new FrameTracing.RpcFrameTracer(Console.Out, false));
_reader = new BinaryReader(pipe.Reader.AsStream()); _reader = new BinaryReader(pipe.Reader.AsStream());
} }

View File

@ -276,7 +276,7 @@ namespace Capnp.Net.Runtime.Tests
} }
[TestMethod] [TestMethod]
public void ListOfUShorts() public void ListOfUShortsWrongUse()
{ {
var b = MessageBuilder.Create(); var b = MessageBuilder.Create();
var wrong = b.CreateObject<DynamicSerializerState>(); var wrong = b.CreateObject<DynamicSerializerState>();
@ -289,6 +289,54 @@ namespace Capnp.Net.Runtime.Tests
Assert.ThrowsException<ArgumentOutOfRangeException>(() => list.ListWriteValue(64, (ushort)1)); Assert.ThrowsException<ArgumentOutOfRangeException>(() => list.ListWriteValue(64, (ushort)1));
} }
[TestMethod]
public void ListOfUShortsFromSegment()
{
var b = MessageBuilder.Create();
var list = b.CreateObject<ListOfPrimitivesSerializer<ushort>>();
var array = new ushort[] { 1, 2, 3, 4, 5, 6 };
var segment = new ArraySegment<ushort>(array, 1, 3);
list.Init(segment);
CollectionAssert.AreEqual(segment.ToArray(), list.ToArray());
}
[TestMethod]
public void ListOfUShortsFromDeser()
{
var b = MessageBuilder.Create();
var list0 = b.CreateObject<ListOfPrimitivesSerializer<ushort>>();
var expected = new ushort[] { 2, 3, 4 };
list0.Init(expected);
var deser = ((DeserializerState)list0).RequireList().CastUShort();
var list = b.CreateObject<ListOfPrimitivesSerializer<ushort>>();
list.Init(deser);
CollectionAssert.AreEqual(expected, list.ToArray());
}
[TestMethod]
public void ListOfUShortsFromSer()
{
var b = MessageBuilder.Create();
var list0 = b.CreateObject<ListOfPrimitivesSerializer<ushort>>();
var expected = new ushort[] { 2, 3, 4 };
list0.Init(expected);
var list = b.CreateObject<ListOfPrimitivesSerializer<ushort>>();
list.Init(list0);
CollectionAssert.AreEqual(expected, list.ToArray());
}
[TestMethod]
public void ListOfUShortsFromList()
{
var b = MessageBuilder.Create();
var list0 = b.CreateObject<ListOfPrimitivesSerializer<ushort>>();
var expected = new List<ushort> { 2, 3, 4 };
list0.Init(expected);
var list = b.CreateObject<ListOfPrimitivesSerializer<ushort>>();
list.Init(list0);
CollectionAssert.AreEqual(expected, list.ToArray());
}
[TestMethod] [TestMethod]
public void ListOfUInts() public void ListOfUInts()
{ {
@ -1093,7 +1141,7 @@ namespace Capnp.Net.Runtime.Tests
{ {
var mb = MessageBuilder.Create(); var mb = MessageBuilder.Create();
var dss = mb.CreateObject<DynamicSerializerState>(); var dss = mb.CreateObject<DynamicSerializerState>();
dss.SetStruct(0, 4); dss.SetStruct(0, 5);
var s1 = mb.CreateObject<SomeStruct.WRITER>(); var s1 = mb.CreateObject<SomeStruct.WRITER>();
s1.SomeText = "foo"; s1.SomeText = "foo";
s1.MoreText = "bar"; s1.MoreText = "bar";
@ -1109,7 +1157,8 @@ namespace Capnp.Net.Runtime.Tests
s4.SomeText = "1"; s4.SomeText = "1";
var arr = new SomeStruct.WRITER[] { s3, s4 }; var arr = new SomeStruct.WRITER[] { s3, s4 };
dss.LinkObject(2, arr); dss.LinkObject(2, arr);
Assert.ThrowsException<InvalidCapabilityInterfaceException>(() => dss.LinkObject(3, new object())); Assert.ThrowsException<InvalidOperationException>(() => dss.LinkObject(3, new object()));
dss.LinkObject(3, new SomeStruct() { SomeText = "corge" });
var t1 = dss.BuildPointer(0).Rewrap<SomeStruct.WRITER>(); var t1 = dss.BuildPointer(0).Rewrap<SomeStruct.WRITER>();
Assert.AreEqual("foo", t1.SomeText); Assert.AreEqual("foo", t1.SomeText);
@ -1121,7 +1170,8 @@ namespace Capnp.Net.Runtime.Tests
Assert.AreEqual(2, l.Count); Assert.AreEqual(2, l.Count);
Assert.AreEqual("0", l[0].SomeText); Assert.AreEqual("0", l[0].SomeText);
Assert.AreEqual("1", l[1].SomeText); Assert.AreEqual("1", l[1].SomeText);
Assert.AreEqual(ObjectKind.Nil, dss.BuildPointer(3).Kind); Assert.AreEqual("corge", dss.BuildPointer(3).Rewrap<SomeStruct.WRITER>().SomeText);
Assert.AreEqual(ObjectKind.Nil, dss.BuildPointer(4).Kind);
} }
[TestMethod] [TestMethod]
@ -1138,5 +1188,23 @@ namespace Capnp.Net.Runtime.Tests
Assert.IsTrue(cap.IsDisposed); Assert.IsTrue(cap.IsDisposed);
dss2.Dispose(); dss2.Dispose();
} }
[TestMethod]
public void ProvideCapability()
{
var dss = DynamicSerializerState.CreateForRpc();
var impl = new TestInterfaceImpl2();
var p1 = (Proxy)Proxy.Share<ITestInterface>(impl);
var p2 = (Proxy)Proxy.Share<ITestInterface>(impl);
Assert.AreEqual(0u, dss.ProvideCapability(p1));
Assert.AreEqual(0u, dss.ProvideCapability(p2.ConsumedCap));
Assert.AreEqual(0u, dss.ProvideCapability(CapabilityReflection.CreateSkeleton(impl)));
Assert.IsTrue(p1.IsDisposed);
Assert.IsFalse(p2.IsDisposed);
p2.Dispose();
Assert.IsFalse(impl.IsDisposed);
dss.Dispose();
Assert.IsTrue(impl.IsDisposed);
}
} }
} }

View File

@ -823,8 +823,9 @@ namespace Capnp.Net.Runtime.Tests
server.StartAccepting(IPAddress.Any, TcpPort); server.StartAccepting(IPAddress.Any, TcpPort);
var client1 = new TcpRpcClient("localhost", TcpPort); var client1 = new TcpRpcClient("localhost", TcpPort);
Assert.IsTrue(client1.WhenConnected.Wait(MediumNonDbgTimeout)); Assert.IsTrue(client1.WhenConnected.Wait(MediumNonDbgTimeout), "Did not connect");
Assert.IsTrue(SpinWait.SpinUntil(() => client1.State == ConnectionState.Down, MediumNonDbgTimeout)); Assert.IsTrue(SpinWait.SpinUntil(() => client1.State == ConnectionState.Down, MediumNonDbgTimeout),
$"Connection did not go down: {client1.State}");
} }
[TestMethod] [TestMethod]

View File

@ -285,5 +285,17 @@ namespace Capnp.Net.Runtime.Tests
{ {
NewLocalhostTcpTestbed().RunTest(Testsuite.NoTailCallMt); NewLocalhostTcpTestbed().RunTest(Testsuite.NoTailCallMt);
} }
[TestMethod]
public void CallAfterFinish1()
{
NewLocalhostTcpTestbed().RunTest(Testsuite.CallAfterFinish1);
}
[TestMethod]
public void CallAfterFinish2()
{
NewLocalhostTcpTestbed().RunTest(Testsuite.CallAfterFinish2);
}
} }
} }

View File

@ -40,6 +40,10 @@ namespace Capnp.Net.Runtime.Tests
// exception had to be serialized, so we receive // exception had to be serialized, so we receive
// the wrapped version. // the wrapped version.
} }
catch (TaskCanceledException)
{
// Also used in some test
}
catch (System.Exception exception) catch (System.Exception exception)
{ {
Assert.Fail($"Got wrong kind of exception: {exception}"); Assert.Fail($"Got wrong kind of exception: {exception}");
@ -407,7 +411,9 @@ namespace Capnp.Net.Runtime.Tests
// Note that this was a bug in previous versions: // Note that this was a bug in previous versions:
// Since passing a cap has move semantics, we need to create an explicit copy. // Since passing a cap has move semantics, we need to create an explicit copy.
var copy = Proxy.Share(cap); var copy = Proxy.Share(cap);
Assert.IsFalse(((Proxy)copy).IsDisposed);
var ctask = main.CallFoo(copy, default); var ctask = main.CallFoo(copy, default);
Assert.IsTrue(((Proxy)copy).IsDisposed);
testbed.MustComplete(ctask); testbed.MustComplete(ctask);
Assert.AreEqual("bar", ctask.Result); Assert.AreEqual("bar", ctask.Result);
@ -820,5 +826,34 @@ namespace Capnp.Net.Runtime.Tests
testbed.MustComplete(tcsd.Task); testbed.MustComplete(tcsd.Task);
} }
} }
public static void CallAfterFinish1(ITestbed testbed)
{
var counters = new Counters();
var impl = new TestMoreStuffImpl3();
using (var main = testbed.ConnectMain<ITestMoreStuff>(impl))
{
using (var held = main.GetHeld().Eager())
{
testbed.CloseClient();
testbed.ExpectPromiseThrows(held.Foo(123, true));
}
}
}
public static void CallAfterFinish2(ITestbed testbed)
{
var counters = new Counters();
var impl = new TestMoreStuffImpl3();
using (var main = testbed.ConnectMain<ITestMoreStuff>(impl))
{
using (var cts = new CancellationTokenSource())
using (var held = main.GetHeld(cts.Token).Eager())
{
cts.Cancel();
testbed.ExpectPromiseThrows(held.Foo(123, true));
}
}
}
} }
} }

View File

@ -19,6 +19,8 @@ namespace Capnp.Net.Runtime.Tests
void MustComplete(params Task[] tasks); void MustComplete(params Task[] tasks);
void MustNotComplete(params Task[] tasks); void MustNotComplete(params Task[] tasks);
void FlushCommunication(); void FlushCommunication();
void CloseClient();
void CloseServer();
long ClientSendCount { get; } long ClientSendCount { get; }
} }
@ -84,7 +86,13 @@ namespace Capnp.Net.Runtime.Tests
{ {
var frame = _frameBuffer.Dequeue(); var frame = _frameBuffer.Dequeue();
_recursion = true; _recursion = true;
try
{
OtherEndpoint.Forward(frame); OtherEndpoint.Forward(frame);
}
catch (InvalidOperationException)
{
}
_recursion = false; _recursion = false;
return true; return true;
@ -177,6 +185,16 @@ namespace Capnp.Net.Runtime.Tests
{ {
Assert.IsFalse(tasks.Any(t => t.IsCompleted)); Assert.IsFalse(tasks.Any(t => t.IsCompleted));
} }
void ITestbed.CloseClient()
{
throw new NotSupportedException();
}
void ITestbed.CloseServer()
{
throw new NotSupportedException();
}
} }
protected class DtbdctTestbed : ITestbed, ITestController protected class DtbdctTestbed : ITestbed, ITestController
@ -231,17 +249,27 @@ namespace Capnp.Net.Runtime.Tests
} }
long ITestbed.ClientSendCount => _enginePair.Channel2SendCount; long ITestbed.ClientSendCount => _enginePair.Channel2SendCount;
void ITestbed.CloseClient()
{
_enginePair.Endpoint1.Dismiss();
}
void ITestbed.CloseServer()
{
_enginePair.Endpoint2.Dismiss();
}
} }
protected class LocalhostTcpTestbed : ITestbed, ITestController protected class LocalhostTcpTestbed : ITestbed, ITestController
{ {
TcpRpcServer _server; TcpRpcServer _server;
TcpRpcClient _client; TcpRpcClient _client;
bool _prematurelyClosed;
public void RunTest(Action<ITestbed> action) public void RunTest(Action<ITestbed> action)
{ {
(_server, _client) = SetupClientServerPair(); (_server, _client) = SetupClientServerPair();
//_client.WhenConnected.Wait(MediumNonDbgTimeout);
Assert.IsTrue(SpinWait.SpinUntil(() => _server.ConnectionCount > 0, MediumNonDbgTimeout)); Assert.IsTrue(SpinWait.SpinUntil(() => _server.ConnectionCount > 0, MediumNonDbgTimeout));
var conn = _server.Connections[0]; var conn = _server.Connections[0];
@ -250,10 +278,13 @@ namespace Capnp.Net.Runtime.Tests
{ {
action(this); action(this);
if (!_prematurelyClosed)
{
Assert.IsTrue(SpinWait.SpinUntil(() => _client.SendCount == conn.RecvCount, MediumNonDbgTimeout)); Assert.IsTrue(SpinWait.SpinUntil(() => _client.SendCount == conn.RecvCount, MediumNonDbgTimeout));
Assert.IsTrue(SpinWait.SpinUntil(() => conn.SendCount == _client.RecvCount, MediumNonDbgTimeout)); Assert.IsTrue(SpinWait.SpinUntil(() => conn.SendCount == _client.RecvCount, MediumNonDbgTimeout));
} }
} }
}
T ITestbed.ConnectMain<T>(object main) T ITestbed.ConnectMain<T>(object main)
{ {
@ -293,6 +324,18 @@ namespace Capnp.Net.Runtime.Tests
} }
long ITestbed.ClientSendCount => _client.SendCount; long ITestbed.ClientSendCount => _client.SendCount;
void ITestbed.CloseClient()
{
_prematurelyClosed = true;
_client.Dispose();
}
void ITestbed.CloseServer()
{
_prematurelyClosed = true;
_server.Dispose();
}
} }
public static int TcpPort = 49152; public static int TcpPort = 49152;

View File

@ -31,7 +31,7 @@ namespace Capnp
/// <summary> /// <summary>
/// The list's data /// The list's data
/// </summary> /// </summary>
public Span<T> Data => MemoryMarshal.Cast<ulong, T>(RawData); public Span<T> Data => MemoryMarshal.Cast<ulong, T>(RawData).Slice(0, Count);
/// <summary> /// <summary>
/// Gets or sets the value at given index. /// Gets or sets the value at given index.
@ -118,7 +118,7 @@ namespace Capnp
IEnumerable<T> Enumerate() IEnumerable<T> Enumerate()
{ {
for (int i = 0; i < Data.Length; i++) for (int i = 0; i < Count; i++)
yield return Data[i]; yield return Data[i];
} }

View File

@ -239,7 +239,7 @@ namespace Capnp.Rpc
} }
/// <summary> /// <summary>
/// Checks whether a given type qualifies as cpapbility interface. /// Checks whether a given type qualifies as capability interface.
/// </summary> /// </summary>
/// <param name="interfaceType">type to check</param> /// <param name="interfaceType">type to check</param>
/// <returns>true when <paramref name="interfaceType"/> is a capability interface</returns> /// <returns>true when <paramref name="interfaceType"/> is a capability interface</returns>

View File

@ -104,12 +104,6 @@ namespace Capnp.Rpc
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
} }
if (cap == null)
{
args.Dispose();
throw new RpcException("Broken capability");
}
using var proxy = new Proxy(cap); using var proxy = new Proxy(cap);
var call = proxy.Call(interfaceId, methodId, args, default); var call = proxy.Call(interfaceId, methodId, args, default);
var whenReturned = call.WhenReturned; var whenReturned = call.WhenReturned;

View File

@ -237,28 +237,7 @@ namespace Capnp.Rpc
/// <param name="access">Access path</param> /// <param name="access">Access path</param>
/// <returns>Low-level capability</returns> /// <returns>Low-level capability</returns>
/// <exception cref="DeserializationException">The referenced member does not exist or does not resolve to a capability pointer.</exception> /// <exception cref="DeserializationException">The referenced member does not exist or does not resolve to a capability pointer.</exception>
public ConsumedCapability Access(MemberAccessPath access) public ConsumedCapability Access(MemberAccessPath access) => new RemoteAnswerCapability(this, access);
{
lock (ReentrancyBlocker)
{
if ( StateFlags.HasFlag(State.Returned) &&
!StateFlags.HasFlag(State.TailCall))
{
try
{
return access.Eval(WhenReturned.Result);
}
catch (AggregateException exception)
{
throw exception.InnerException!;
}
}
else
{
return new RemoteAnswerCapability(this, access);
}
}
}
/// <summary> /// <summary>
/// Refer to a (possibly nested) member of this question's (possibly future) result and return /// Refer to a (possibly nested) member of this question's (possibly future) result and return

View File

@ -161,7 +161,7 @@ namespace Capnp.Rpc
// When called from the Finalizer, we must not throw. // When called from the Finalizer, we must not throw.
// But when reference counting goes wrong, ConsumedCapability.Release() will throw an InvalidOperationException. // But when reference counting goes wrong, ConsumedCapability.Release() will throw an InvalidOperationException.
// The only option here is to suppress that exception. // The only option here is to suppress that exception.
try { _consumedCap.Release(); } try { _consumedCap?.Release(); }
catch { } catch { }
} }

View File

@ -109,18 +109,13 @@ namespace Capnp.Rpc
#if DebugEmbargos #if DebugEmbargos
Logger.LogDebug("Call by proxy"); Logger.LogDebug("Call by proxy");
#endif #endif
if (_question.StateFlags.HasFlag(PendingQuestion.State.CanceledByDispose)) if (_question.StateFlags.HasFlag(PendingQuestion.State.CanceledByDispose) ||
_question.StateFlags.HasFlag(PendingQuestion.State.FinishRequested))
{ {
args.Dispose(); args.Dispose();
throw new ObjectDisposedException(nameof(PendingQuestion)); throw new ObjectDisposedException(nameof(PendingQuestion));
} }
if (_question.StateFlags.HasFlag(PendingQuestion.State.FinishRequested))
{
args.Dispose();
throw new InvalidOperationException("Finish request was already sent");
}
_question.DisallowFinish(); _question.DisallowFinish();
++_pendingCallsOnPromise; ++_pendingCallsOnPromise;
var promisedAnswer = base.DoCall(interfaceId, methodId, args); var promisedAnswer = base.DoCall(interfaceId, methodId, args);

View File

@ -437,12 +437,9 @@ namespace Capnp.Rpc
why(ret); why(ret);
try try
{
lock (_callReturnBlocker)
{ {
Tx(mb.Frame); Tx(mb.Frame);
} }
}
catch (RpcException exception) catch (RpcException exception)
{ {
Logger.LogWarning($"Unable to return call: {exception.InnerException?.Message ?? exception.Message}"); Logger.LogWarning($"Unable to return call: {exception.InnerException?.Message ?? exception.Message}");

View File

@ -110,6 +110,7 @@ namespace Capnp.Rpc
} }
} }
}); });
PumpRunner.Start();
} }
public ConnectionState State { get; set; } = ConnectionState.Initializing; public ConnectionState State { get; set; } = ConnectionState.Initializing;
@ -191,8 +192,6 @@ namespace Capnp.Rpc
OnConnectionChanged?.Invoke(this, new ConnectionEventArgs(connection)); OnConnectionChanged?.Invoke(this, new ConnectionEventArgs(connection));
connection.Start(); connection.Start();
} }
connection.PumpRunner!.Start();
} }
} }
catch (SocketException) catch (SocketException)
@ -207,38 +206,6 @@ namespace Capnp.Rpc
} }
} }
void SafeJoin(Thread? thread)
{
if (thread == null)
{
return;
}
for (int retry = 0; retry < 5; ++retry)
{
try
{
if (!thread.Join(500))
{
Logger.LogError($"Unable to join {thread.Name} within timeout");
}
break;
}
catch (ThreadStateException)
{
// In rare cases it happens that despite thread.Start() was called, the thread did not actually start yet.
Logger.LogDebug("Waiting for thread to start in order to join it");
Thread.Sleep(100);
}
catch (System.Exception exception)
{
Logger.LogError($"Unable to join {thread.Name}: {exception.Message}");
break;
}
}
}
/// <summary> /// <summary>
/// Stops accepting incoming attempts and closes all existing connections. /// Stops accepting incoming attempts and closes all existing connections.
/// </summary> /// </summary>
@ -260,7 +227,7 @@ namespace Capnp.Rpc
{ {
connection.Client.Dispose(); connection.Client.Dispose();
connection.Pump?.Dispose(); connection.Pump?.Dispose();
SafeJoin(connection.PumpRunner); connection.PumpRunner?.Join(5000);
} }
_rpcEngine.BootstrapCap = null; _rpcEngine.BootstrapCap = null;
@ -286,7 +253,8 @@ namespace Capnp.Rpc
finally finally
{ {
_listener = null; _listener = null;
SafeJoin(_acceptorThread); if (Thread.CurrentThread != _acceptorThread)
_acceptorThread?.Join();
_acceptorThread = null; _acceptorThread = null;
} }
} }

View File

@ -1314,7 +1314,7 @@ namespace Capnp
/// </list></param> /// </list></param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="slot"/> is out of range.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="slot"/> is out of range.</exception>
/// <exception cref="InvalidOperationException"><list type="bullet"> /// <exception cref="InvalidOperationException"><list type="bullet">
/// <item><description>This state does neither describe a struct, nor a list of pointers</description></item> /// <item><description>Object neither describes a struct, nor a list of pointers, nor a capability</description></item>
/// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list> /// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list>
/// </exception> /// </exception>
public void LinkObject<T>(int slot, T obj) public void LinkObject<T>(int slot, T obj)
@ -1346,10 +1346,16 @@ namespace Capnp
break; break;
default: default:
if (Rpc.CapabilityReflection.IsValidCapabilityInterface(typeof(T))) try
{ {
LinkToCapability(slot, ProvideCapability(obj)); LinkToCapability(slot, ProvideCapability(obj));
} }
catch (Exception exception) when (
exception is Rpc.InvalidCapabilityInterfaceException ||
exception is InvalidOperationException)
{
throw new InvalidOperationException("Object neither describes a struct, nor a list of pointers, nor a capability", exception);
}
break; break;
} }
} }

View File

@ -10,7 +10,7 @@ namespace Capnp.Util
internal class StrictlyOrderedAwaitTask<T>: INotifyCompletion internal class StrictlyOrderedAwaitTask<T>: INotifyCompletion
{ {
readonly Task<T> _awaitedTask; readonly Task<T> _awaitedTask;
object _lock; object? _lock;
long _inOrder, _outOrder; long _inOrder, _outOrder;
public StrictlyOrderedAwaitTask(Task<T> awaitedTask) public StrictlyOrderedAwaitTask(Task<T> awaitedTask)
@ -26,7 +26,7 @@ namespace Capnp.Util
public async void OnCompleted(Action continuation) public async void OnCompleted(Action continuation)
{ {
object safeLock = Volatile.Read(ref _lock); object? safeLock = Volatile.Read(ref _lock);
if (safeLock == null) if (safeLock == null)
{ {
@ -69,7 +69,7 @@ namespace Capnp.Util
} }
} }
public bool IsCompleted => Volatile.Read(ref _lock) == null; public bool IsCompleted => Volatile.Read(ref _lock) == null || (_awaitedTask.IsCompleted && Volatile.Read(ref _inOrder) == 0);
public T GetResult() => _awaitedTask.GetAwaiter().GetResult(); public T GetResult() => _awaitedTask.GetAwaiter().GetResult();

View File

@ -20,7 +20,7 @@ If(!(test-path $coverageReportDir))
} }
& $openCover -target:"$vsTestConsole" ` & $openCover -target:"$vsTestConsole" `
-targetArgs:"/inIsolation $runtimeTests /TestCaseFilter:`"TestCategory=Coverage`"" ` -targetArgs:"/inIsolation $runtimeTests /TestCaseFilter:`"TestCategory=Coverage`" /Framework:.NETCoreApp,Version=v2.1" `
-filter:"+[Capnp.Net.Runtime]Capnp.*" ` -filter:"+[Capnp.Net.Runtime]Capnp.*" `
-excludebyattribute:"System.CodeDom.Compiler.GeneratedCodeAttribute" ` -excludebyattribute:"System.CodeDom.Compiler.GeneratedCodeAttribute" `
-output:"$coverageOutput" ` -output:"$coverageOutput" `