mirror of
https://github.com/FabInfra/capnproto-dotnetcore_Runtime.git
synced 2025-03-12 14:51:41 +01:00
1357 lines
51 KiB
C#
1357 lines
51 KiB
C#
using Capnp;
|
|
using Capnp.Net.Runtime.Tests.GenImpls;
|
|
using Capnp.Rpc;
|
|
using Capnproto_test.Capnp.Test;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.IO.Pipelines;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Capnp.Net.Runtime.Tests
|
|
{
|
|
[TestClass]
|
|
[TestCategory("Coverage")]
|
|
public class EdgeCaseHandling: TestBase
|
|
{
|
|
class MemStreamEndpoint : IEndpoint
|
|
{
|
|
readonly FramePump _fromEnginePump;
|
|
readonly BinaryReader _reader;
|
|
readonly FrameTracing.RpcFrameTracer _tracer;
|
|
|
|
public bool Dismissed { get; private set; }
|
|
|
|
public MemStreamEndpoint()
|
|
{
|
|
var pipe = new Pipe();
|
|
_tracer = new FrameTracing.RpcFrameTracer(Console.Out, false);
|
|
_fromEnginePump = new FramePump(pipe.Writer.AsStream());
|
|
_fromEnginePump.AttachTracer(_tracer);
|
|
_reader = new BinaryReader(pipe.Reader.AsStream());
|
|
}
|
|
|
|
public void Dismiss()
|
|
{
|
|
Dismissed = true;
|
|
}
|
|
|
|
public void Forward(WireFrame frame)
|
|
{
|
|
_fromEnginePump.Send(frame);
|
|
}
|
|
|
|
public void Flush()
|
|
{
|
|
_fromEnginePump.Flush();
|
|
}
|
|
|
|
public WireFrame ReadNextFrame()
|
|
{
|
|
var frame = _reader.ReadWireFrame();
|
|
_tracer.TraceFrame(FrameTracing.FrameDirection.Rx, frame);
|
|
return frame;
|
|
}
|
|
}
|
|
|
|
class RpcEngineTester
|
|
{
|
|
readonly MemStreamEndpoint _fromEngine;
|
|
|
|
public RpcEngineTester()
|
|
{
|
|
Engine = new RpcEngine();
|
|
_fromEngine = new MemStreamEndpoint();
|
|
RealEnd = Engine.AddEndpoint(_fromEngine);
|
|
}
|
|
|
|
public RpcEngine Engine { get; }
|
|
public RpcEngine.RpcEndpoint RealEnd { get; }
|
|
public bool IsDismissed => _fromEngine.Dismissed;
|
|
|
|
public void Send(Action<Message.WRITER> build)
|
|
{
|
|
var mb = MessageBuilder.Create();
|
|
mb.InitCapTable();
|
|
build(mb.BuildRoot<Message.WRITER>());
|
|
RealEnd.Forward(mb.Frame);
|
|
}
|
|
|
|
public void Recv(Action<Message.READER> verify)
|
|
{
|
|
var task = Task.Run(() => DeserializerState.CreateRoot(_fromEngine.ReadNextFrame()));
|
|
Assert.IsTrue(task.Wait(MediumNonDbgTimeout), "reception timeout");
|
|
verify(new Message.READER(task.Result));
|
|
}
|
|
|
|
public void ExpectAbort()
|
|
{
|
|
Recv(_ => { Assert.AreEqual(Message.WHICH.Abort, _.which); });
|
|
Assert.IsTrue(IsDismissed);
|
|
Assert.ThrowsException<InvalidOperationException>(
|
|
() => Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 33; }));
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void DuplicateQuestion1()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; });
|
|
tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; });
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void DuplicateQuestion2()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; });
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Call;
|
|
_.Call.QuestionId = 99;
|
|
_.Call.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Call.Target.ImportedCap = bootCapId;
|
|
_.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id;
|
|
_.Call.MethodId = 0;
|
|
_.Call.Params.Content.Rewrap<TestInterface.Params_Foo.WRITER>();
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void DuplicateQuestion3()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; });
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Call;
|
|
_.Call.QuestionId = 42;
|
|
_.Call.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Call.Target.ImportedCap = bootCapId;
|
|
_.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id;
|
|
_.Call.MethodId = 0;
|
|
var wr = _.Call.Params.Content.Rewrap<TestInterface.Params_Foo.WRITER>();
|
|
wr.I = 123u;
|
|
wr.J = true;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Call;
|
|
_.Call.QuestionId = 42;
|
|
_.Call.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Call.Target.ImportedCap = bootCapId;
|
|
_.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id;
|
|
_.Call.MethodId = 0;
|
|
_.Call.Params.Content.Rewrap<TestInterface.Params_Foo.WRITER>();
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void NoBootstrap()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; });
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Exception, _.Return.which);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 1; });
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void DuplicateFinish()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; });
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Finish;
|
|
_.Finish.QuestionId = 99;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Finish;
|
|
_.Finish.QuestionId = 99;
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void DuplicateAnswer()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.Results;
|
|
_.Return.Results.CapTable.Init(1);
|
|
_.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderHosted;
|
|
_.Return.Results.CapTable[0].SenderHosted = 1;
|
|
});
|
|
Assert.IsTrue(proxy.WhenResolved.IsCompleted);
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Finish, _.which);
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.Results;
|
|
_.Return.Results.CapTable.Init(1);
|
|
_.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderHosted;
|
|
_.Return.Results.CapTable[0].SenderHosted = 1;
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedReturnAcceptFromThirdParty()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.AcceptFromThirdParty;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedReturnUnknown()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = (Return.WHICH)33;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void InvalidReturnTakeFromOtherQuestion()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.TakeFromOtherQuestion;
|
|
_.Return.TakeFromOtherQuestion = 1u;
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void InvalidReceiverHosted()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.Results;
|
|
_.Return.Results.CapTable.Init(1);
|
|
_.Return.Results.CapTable[0].which = CapDescriptor.WHICH.ReceiverHosted;
|
|
_.Return.Results.CapTable[0].ReceiverHosted = 0;
|
|
});
|
|
Assert.IsTrue(proxy.WhenResolved.IsCompleted);
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void InvalidReceiverAnswer()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.Results;
|
|
_.Return.Results.CapTable.Init(1);
|
|
_.Return.Results.CapTable[0].which = CapDescriptor.WHICH.ReceiverAnswer;
|
|
_.Return.Results.CapTable[0].ReceiverAnswer.QuestionId = 0;
|
|
_.Return.Results.CapTable[0].ReceiverAnswer.Transform.Init(1);
|
|
_.Return.Results.CapTable[0].ReceiverAnswer.Transform[0].which = PromisedAnswer.Op.WHICH.GetPointerField;
|
|
_.Return.Results.CapTable[0].ReceiverAnswer.Transform[0].GetPointerField = 0;
|
|
});
|
|
Assert.IsTrue(proxy.WhenResolved.IsCompleted);
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void InvalidCallTargetImportedCap()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; });
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Call;
|
|
_.Call.QuestionId = 1;
|
|
_.Call.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Call.Target.ImportedCap = bootCapId + 1;
|
|
_.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id;
|
|
_.Call.MethodId = 0;
|
|
_.Call.Params.Content.Rewrap<TestInterface.Params_Foo.WRITER>();
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void InvalidCallTargetPromisedAnswer()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; });
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Call;
|
|
_.Call.QuestionId = 1;
|
|
_.Call.Target.which = MessageTarget.WHICH.PromisedAnswer;
|
|
_.Call.Target.PromisedAnswer.QuestionId = 1;
|
|
_.Call.Target.PromisedAnswer.Transform.Init(1);
|
|
_.Call.Target.PromisedAnswer.Transform[0].which = PromisedAnswer.Op.WHICH.GetPointerField;
|
|
_.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id;
|
|
_.Call.MethodId = 0;
|
|
_.Call.Params.Content.Rewrap<TestInterface.Params_Foo.WRITER>();
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedCallTargetUnknown()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; });
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Call;
|
|
_.Call.QuestionId = 1;
|
|
_.Call.Target.which = (MessageTarget.WHICH)77;
|
|
_.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id;
|
|
_.Call.MethodId = 0;
|
|
_.Call.Params.Content.Rewrap<TestInterface.Params_Foo.WRITER>();
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void DuplicateResolve1()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.Results;
|
|
_.Return.Results.CapTable.Init(1);
|
|
_.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderPromise;
|
|
_.Return.Results.CapTable[0].SenderPromise = 0;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Resolve;
|
|
_.Resolve.which = Resolve.WHICH.Cap;
|
|
_.Resolve.Cap.which = CapDescriptor.WHICH.SenderHosted;
|
|
_.Resolve.Cap.SenderHosted = 1;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Finish, _.which);
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Resolve;
|
|
_.Resolve.which = Resolve.WHICH.Exception;
|
|
_.Resolve.Exception.Reason = "problem";
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Release, _.which);
|
|
});
|
|
|
|
// tester.ExpectAbort();
|
|
|
|
// Duplicate resolve is only a protocol error if the Rpc engine can prove misbehavior.
|
|
// In this case that proof is not possible because the preliminary cap is release (thus, removed from import table)
|
|
// immediately after the first resolution. Now we get the situation that the 2nd resolution refers to a non-existing
|
|
// cap. This is not considered a protocol error because it might be due to an expected race condition
|
|
// between receiver-side Release and sender-side Resolve.
|
|
}
|
|
|
|
[TestMethod]
|
|
public void DuplicateResolve2()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.Results;
|
|
_.Return.Results.CapTable.Init(1);
|
|
_.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderPromise;
|
|
_.Return.Results.CapTable[0].SenderPromise = 0;
|
|
_.Return.Results.Content.SetCapability(0);
|
|
});
|
|
proxy.Call(0, 0, DynamicSerializerState.CreateForRpc());
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Finish, _.which);
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Call, _.which);
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Resolve;
|
|
_.Resolve.which = Resolve.WHICH.Cap;
|
|
_.Resolve.Cap.which = CapDescriptor.WHICH.SenderHosted;
|
|
_.Resolve.Cap.SenderHosted = 1;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Resolve;
|
|
_.Resolve.which = Resolve.WHICH.Exception;
|
|
_.Resolve.Exception.Reason = "problem";
|
|
});
|
|
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedResolveCategory()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.Results;
|
|
_.Return.Results.CapTable.Init(1);
|
|
_.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderPromise;
|
|
_.Return.Results.CapTable[0].SenderPromise = 0;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Resolve;
|
|
_.Resolve.which = (Resolve.WHICH)7;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Finish, _.which);
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void InvalidResolve()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.Results;
|
|
_.Return.Results.CapTable.Init(1);
|
|
_.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderHosted;
|
|
_.Return.Results.CapTable[0].SenderHosted = 7;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Resolve;
|
|
_.Resolve.which = Resolve.WHICH.Cap;
|
|
_.Resolve.PromiseId = 7;
|
|
_.Resolve.Cap.which = CapDescriptor.WHICH.SenderHosted;
|
|
_.Resolve.Cap.SenderHosted = 1;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Finish, _.which);
|
|
});
|
|
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void DuplicateRelease1()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Release;
|
|
_.Release.Id = bootCapId;
|
|
_.Release.ReferenceCount = 1;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Release;
|
|
_.Release.Id = bootCapId;
|
|
_.Release.ReferenceCount = 1;
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void DuplicateRelease2()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Release;
|
|
_.Release.Id = bootCapId;
|
|
_.Release.ReferenceCount = 2;
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedAccept()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Accept;
|
|
_.Accept.Embargo = true;
|
|
_.Accept.QuestionId = 47;
|
|
_.Accept.Provision.SetStruct(1, 0);
|
|
_.Accept.Provision.Allocate();
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
Assert.AreEqual(Message.WHICH.Accept, _.Unimplemented.which);
|
|
Assert.IsTrue(_.Unimplemented.Accept.Embargo);
|
|
Assert.AreEqual(47u, _.Unimplemented.Accept.QuestionId);
|
|
Assert.AreEqual(1, _.Unimplemented.Accept.Provision.StructDataCount);
|
|
Assert.AreEqual(0, _.Unimplemented.Accept.Provision.StructPtrCount);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedJoin()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Join;
|
|
_.Join.QuestionId = 74;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
Assert.AreEqual(Message.WHICH.Join, _.Unimplemented.which);
|
|
Assert.AreEqual(74u, _.Unimplemented.Join.QuestionId);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedProvide()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Provide;
|
|
_.Provide.QuestionId = 666;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
Assert.AreEqual(Message.WHICH.Provide, _.Unimplemented.which);
|
|
Assert.AreEqual(666u, _.Unimplemented.Provide.QuestionId);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedObsoleteDelete()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.ObsoleteDelete;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
Assert.AreEqual(Message.WHICH.ObsoleteDelete, _.Unimplemented.which);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedObsoleteSave()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.ObsoleteSave;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
Assert.AreEqual(Message.WHICH.ObsoleteSave, _.Unimplemented.which);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedUnknown()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
tester.Send(_ => {
|
|
_.which = (Message.WHICH)123;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
Assert.AreEqual((Message.WHICH)123, _.Unimplemented.which);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedSendResultsToThirdParty()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; });
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Call;
|
|
_.Call.QuestionId = 42;
|
|
_.Call.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Call.Target.ImportedCap = bootCapId;
|
|
_.Call.InterfaceId = new TestInterface_Skeleton().InterfaceId;
|
|
_.Call.MethodId = 0;
|
|
var wr = _.Call.Params.Content.Rewrap<TestInterface.Params_Foo.WRITER>();
|
|
_.Call.Params.CapTable.Init(0);
|
|
_.Call.SendResultsTo.which = Call.sendResultsTo.WHICH.ThirdParty;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedSendResultsToUnknown()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Call;
|
|
_.Call.QuestionId = 42;
|
|
_.Call.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Call.Target.ImportedCap = bootCapId;
|
|
_.Call.InterfaceId = new TestInterface_Skeleton().InterfaceId;
|
|
_.Call.MethodId = 0;
|
|
var wr = _.Call.Params.Content.Rewrap<TestInterface.Params_Foo.WRITER>();
|
|
_.Call.Params.CapTable.Init(0);
|
|
_.Call.SendResultsTo.which = (Call.sendResultsTo.WHICH)13;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
class TestPipelineImpl3 : ITestPipeline
|
|
{
|
|
readonly TestPipelineImpl2 _impl;
|
|
readonly ITestPipeline _proxy;
|
|
|
|
public TestPipelineImpl3(Task complete)
|
|
{
|
|
_impl = new TestPipelineImpl2(complete);
|
|
var bproxy = BareProxy.FromImpl(_impl);
|
|
_proxy = bproxy.Cast<ITestPipeline>(true);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
}
|
|
|
|
public bool IsGrandsonCapDisposed => _impl.IsChildCapDisposed;
|
|
|
|
public Task<(string, TestPipeline.AnyBox)> GetAnyCap(uint n, BareProxy inCap, CancellationToken cancellationToken_ = default)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public Task<(string, TestPipeline.Box)> GetCap(uint n, ITestInterface inCap, CancellationToken cancellationToken_ = default)
|
|
{
|
|
return Task.FromResult(("foo", new TestPipeline.Box() { Cap = _proxy.GetCap(0, null).OutBox_Cap() }));
|
|
}
|
|
|
|
public Task TestPointers(ITestInterface cap, object obj, IReadOnlyList<ITestInterface> list, CancellationToken cancellationToken_ = default)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedResolve()
|
|
{
|
|
var tcs = new TaskCompletionSource<int>();
|
|
var tester = new RpcEngineTester();
|
|
var impl = new TestPipelineImpl3(tcs.Task);
|
|
tester.Engine.Main = impl;
|
|
|
|
uint bootCapId = 0;
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
bootCapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Call;
|
|
_.Call.QuestionId = 42;
|
|
_.Call.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Call.Target.ImportedCap = bootCapId;
|
|
_.Call.InterfaceId = new TestPipeline_Skeleton().InterfaceId;
|
|
_.Call.MethodId = 0;
|
|
var wr = _.Call.Params.Content.Rewrap<TestPipeline.Params_GetCap.WRITER>();
|
|
wr.InCap = null;
|
|
_.Call.Params.CapTable.Init(1);
|
|
_.Call.Params.CapTable[0].which = CapDescriptor.WHICH.ReceiverHosted;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(1, _.Return.Results.CapTable.Count);
|
|
Assert.AreEqual(CapDescriptor.WHICH.SenderPromise, _.Return.Results.CapTable[0].which);
|
|
});
|
|
tcs.SetResult(0);
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Resolve, _.which);
|
|
Assert.AreEqual(Resolve.WHICH.Cap, _.Resolve.which);
|
|
Assert.AreEqual(CapDescriptor.WHICH.SenderHosted, _.Resolve.Cap.which);
|
|
|
|
Assert.IsFalse(impl.IsGrandsonCapDisposed);
|
|
|
|
tester.Send(_1 =>
|
|
{
|
|
_1.which = Message.WHICH.Unimplemented;
|
|
_1.Unimplemented.which = Message.WHICH.Resolve;
|
|
Reserializing.DeepCopy(_.Resolve, _1.Unimplemented.Resolve);
|
|
});
|
|
|
|
Assert.IsFalse(impl.IsGrandsonCapDisposed);
|
|
|
|
tester.Send(_1 =>
|
|
{
|
|
_1.which = Message.WHICH.Finish;
|
|
_1.Finish.QuestionId = 42;
|
|
_1.Finish.ReleaseResultCaps = true;
|
|
});
|
|
|
|
Assert.IsTrue(impl.IsGrandsonCapDisposed);
|
|
});
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SenderLoopbackOnInvalidCap()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Disembargo;
|
|
_.Disembargo.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Disembargo.Target.ImportedCap = 0;
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SenderLoopbackOnInvalidPromisedAnswer()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Disembargo;
|
|
_.Disembargo.Context.which = Disembargo.context.WHICH.SenderLoopback;
|
|
_.Disembargo.Context.SenderLoopback = 0;
|
|
_.Disembargo.Target.which = MessageTarget.WHICH.PromisedAnswer;
|
|
_.Disembargo.Target.PromisedAnswer.QuestionId = 9;
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SenderLoopbackOnUnknownTarget()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Disembargo;
|
|
_.Disembargo.Context.which = Disembargo.context.WHICH.SenderLoopback;
|
|
_.Disembargo.Context.SenderLoopback = 0;
|
|
_.Disembargo.Target.which = (MessageTarget.WHICH)12;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ReceiverLoopbackOnInvalidCap()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Disembargo;
|
|
_.Disembargo.Context.which = Disembargo.context.WHICH.ReceiverLoopback;
|
|
_.Disembargo.Context.ReceiverLoopback = 0;
|
|
_.Disembargo.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Disembargo.Target.ImportedCap = 0;
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedDisembargoAccept()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Disembargo;
|
|
_.Disembargo.Context.which = Disembargo.context.WHICH.Accept;
|
|
_.Disembargo.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Disembargo.Target.ImportedCap = 0;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedDisembargoProvide()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Disembargo;
|
|
_.Disembargo.Context.which = Disembargo.context.WHICH.Provide;
|
|
_.Disembargo.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Disembargo.Target.ImportedCap = 0;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedDisembargoUnknown()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
tester.Engine.Main = new TestInterfaceImpl(new Counters());
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Disembargo;
|
|
_.Disembargo.Context.which = (Disembargo.context.WHICH)50;
|
|
_.Disembargo.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Disembargo.Target.ImportedCap = 0;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedCall()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.Results;
|
|
_.Return.Results.CapTable.Init(1);
|
|
_.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderHosted;
|
|
_.Return.Results.CapTable[0].SenderHosted = 1;
|
|
_.Return.Results.Content.SetCapability(0);
|
|
});
|
|
Assert.IsTrue(proxy.WhenResolved.IsCompleted);
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Finish, _.which);
|
|
});
|
|
var args = DynamicSerializerState.CreateForRpc();
|
|
var ti = new TestInterfaceImpl(new Counters());
|
|
args.ProvideCapability(ti);
|
|
proxy.Call(1, 2, args);
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Call, _.which);
|
|
Assert.AreEqual(1ul, _.Call.InterfaceId);
|
|
Assert.AreEqual((ushort)2, _.Call.MethodId);
|
|
|
|
Assert.IsFalse(ti.IsDisposed);
|
|
|
|
tester.Send(_1 =>
|
|
{
|
|
_1.which = Message.WHICH.Unimplemented;
|
|
_1.Unimplemented.which = Message.WHICH.Call;
|
|
Reserializing.DeepCopy(_.Call, _1.Unimplemented.Call);
|
|
});
|
|
|
|
Assert.IsTrue(ti.IsDisposed);
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnimplementedBootstrap()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
|
|
tester.Send(_1 =>
|
|
{
|
|
_1.which = Message.WHICH.Unimplemented;
|
|
_1.Unimplemented.which = Message.WHICH.Bootstrap;
|
|
Reserializing.DeepCopy(_.Bootstrap, _1.Unimplemented.Bootstrap);
|
|
});
|
|
});
|
|
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Abort()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
});
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Abort;
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ThirdPartyHostedBootstrap()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
|
|
tester.Send(_1 =>
|
|
{
|
|
_1.which = Message.WHICH.Return;
|
|
_1.Return.AnswerId = _.Bootstrap.QuestionId;
|
|
_1.Return.which = Return.WHICH.Results;
|
|
_1.Return.Results.CapTable.Init(1);
|
|
_1.Return.Results.CapTable[0].which = CapDescriptor.WHICH.ThirdPartyHosted;
|
|
_1.Return.Results.CapTable[0].ThirdPartyHosted.VineId = 27;
|
|
_1.Return.Results.Content.SetCapability(0);
|
|
});
|
|
});
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Finish, _.which);
|
|
});
|
|
|
|
proxy.Call(1, 2, DynamicSerializerState.CreateForRpc());
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Call, _.which);
|
|
Assert.AreEqual(MessageTarget.WHICH.ImportedCap, _.Call.Target.which);
|
|
Assert.AreEqual(27u, _.Call.Target.ImportedCap);
|
|
|
|
tester.Send(_1 =>
|
|
{
|
|
_1.which = Message.WHICH.Return;
|
|
_1.Return.AnswerId = _.Call.QuestionId;
|
|
_1.Return.which = Return.WHICH.Results;
|
|
_1.Return.Results.CapTable.Init(1);
|
|
_1.Return.Results.CapTable[0].which = CapDescriptor.WHICH.ThirdPartyHosted;
|
|
_1.Return.Results.CapTable[0].ThirdPartyHosted.VineId = 27;
|
|
_1.Return.Results.Content.SetCapability(0);
|
|
});
|
|
});
|
|
}
|
|
|
|
[TestMethod]
|
|
public void NoneImportBootstrap()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
|
|
tester.Send(_1 =>
|
|
{
|
|
_1.which = Message.WHICH.Return;
|
|
_1.Return.AnswerId = _.Bootstrap.QuestionId;
|
|
_1.Return.which = Return.WHICH.Results;
|
|
_1.Return.Results.CapTable.Init(1);
|
|
_1.Return.Results.CapTable[0].which = CapDescriptor.WHICH.None;
|
|
});
|
|
});
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Finish, _.which);
|
|
});
|
|
|
|
var answer = proxy.Call(1, 2, DynamicSerializerState.CreateForRpc());
|
|
var task = Impatient.MakePipelineAware(answer, _ => _);
|
|
Assert.IsTrue(task.IsFaulted);
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void UnknownImportBootstrap()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
|
|
tester.Send(_1 =>
|
|
{
|
|
_1.which = Message.WHICH.Return;
|
|
_1.Return.AnswerId = _.Bootstrap.QuestionId;
|
|
_1.Return.which = Return.WHICH.Results;
|
|
_1.Return.Results.CapTable.Init(1);
|
|
_1.Return.Results.CapTable[0].which = (CapDescriptor.WHICH)27;
|
|
});
|
|
});
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Unimplemented, _.which);
|
|
});
|
|
|
|
Assert.IsFalse(tester.IsDismissed);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ReturnToWrongSide1()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
var cap = tester.RealEnd.QueryMain();
|
|
var proxy = new BareProxy(cap);
|
|
Assert.IsFalse(proxy.WhenResolved.IsCompleted);
|
|
uint id = 0;
|
|
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Bootstrap, _.which);
|
|
id = _.Bootstrap.QuestionId;
|
|
});
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.ResultsSentElsewhere;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Finish, _.which);
|
|
});
|
|
Assert.IsTrue(proxy.WhenResolved.IsCompleted);
|
|
Assert.IsTrue(proxy.WhenResolved.WrappedTask.IsFaulted);
|
|
tester.ExpectAbort();
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ReturnToWrongSide2()
|
|
{
|
|
var tester = new RpcEngineTester();
|
|
|
|
tester.Engine.Main = new TestTailCallerImpl(new Counters());
|
|
|
|
tester.Send(_ => {
|
|
_.which = Message.WHICH.Bootstrap;
|
|
_.Bootstrap.QuestionId = 0;
|
|
});
|
|
uint bootstrapId = 0;
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.Results, _.Return.which);
|
|
Assert.AreEqual(CapDescriptor.WHICH.SenderHosted, _.Return.Results.CapTable[0].which);
|
|
bootstrapId = _.Return.Results.CapTable[0].SenderHosted;
|
|
});
|
|
tester.Send(_ =>
|
|
{
|
|
_.which = Message.WHICH.Call;
|
|
_.Call.Target.which = MessageTarget.WHICH.ImportedCap;
|
|
_.Call.Target.ImportedCap = 0;
|
|
_.Call.SendResultsTo.which = Call.sendResultsTo.WHICH.Caller;
|
|
_.Call.InterfaceId = new TestTailCaller_Skeleton().InterfaceId;
|
|
_.Call.MethodId = 0;
|
|
_.Call.QuestionId = 1;
|
|
var a = _.Call.Params.Content.Rewrap<TestTailCaller.Params_Foo.WRITER>();
|
|
a.Callee = new TestTailCalleeImpl(new Counters());
|
|
_.Call.Params.CapTable.Init(1);
|
|
_.Call.Params.CapTable[0].which = CapDescriptor.WHICH.SenderHosted;
|
|
_.Call.Params.CapTable[0].SenderHosted = 0;
|
|
});
|
|
uint q = 0;
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Call, _.which);
|
|
Assert.AreEqual(Call.sendResultsTo.WHICH.Yourself, _.Call.SendResultsTo.which);
|
|
q = _.Call.QuestionId;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Release, _.which);
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Return, _.which);
|
|
Assert.AreEqual(Return.WHICH.TakeFromOtherQuestion, _.Return.which);
|
|
});
|
|
tester.Send(_ =>
|
|
{
|
|
_.which = Message.WHICH.Return;
|
|
_.Return.which = Return.WHICH.Results;
|
|
_.Return.AnswerId = q;
|
|
var wr = _.Return.Results.Content.Rewrap<TestTailCallee.TailResult.WRITER>();
|
|
wr.C = new TestCallOrderImpl();
|
|
wr.I = 0;
|
|
wr.T = "test";
|
|
_.Return.Results.CapTable.Init(1);
|
|
_.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderHosted;
|
|
_.Return.Results.CapTable[0].SenderHosted = 1;
|
|
});
|
|
tester.Recv(_ => {
|
|
Assert.AreEqual(Message.WHICH.Finish, _.which);
|
|
});
|
|
tester.ExpectAbort();
|
|
}
|
|
}
|
|
}
|