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 build) { var mb = MessageBuilder.Create(); mb.InitCapTable(); build(mb.BuildRoot()); RealEnd.Forward(mb.Frame); } public void Recv(Action 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( () => 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(); }); 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(); 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(); }); 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(); }); 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(); }); 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(); }); 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(); _.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(); _.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(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 list, CancellationToken cancellationToken_ = default) { throw new NotImplementedException(); } } [TestMethod] public void UnimplementedResolve() { var tcs = new TaskCompletionSource(); 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(); 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(); 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(); 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(); } } }