static async Task Main(string[] args) { if (args.Length > 0) { var pair = new EnginePair(); pair.Engine1.Main = new CapnpEchoService(); var echoer = (CapabilityReflection.CreateProxy <IEchoer>(pair.Endpoint2.QueryMain()) as IEchoer); await Run(echoer); } else { using var server = new TcpRpcServer(); server.Main = new CapnpEchoService(); server.AddBuffering(); server.StartAccepting(IPAddress.Any, 5002); using var client = new TcpRpcClient(); client.AddBuffering(); client.Connect("localhost", 5002); await client.WhenConnected; using var echoer = client.GetMain <IEchoer>(); await Run(echoer); } }
public void PipelineCallDuringDisposal() { (var server, var client) = SetupClientServerPair(); using (server) using (client) { Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain <BareProxy>(); Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); IPromisedAnswer answer2; using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); var pipelined = (BareProxy)CapabilityReflection.CreateProxy <BareProxy>(answer.Access(new MemberAccessPath(new MemberAccessPath.MemberAccess[] { new MemberAccessPath.StructMemberAccess(1) }))); var args2 = DynamicSerializerState.CreateForRpc(); args2.SetStruct(1, 0); args2.WriteData(0, 654321); answer2 = pipelined.Call(0x8765432187654321, 0x4444, args2); } using (answer2) { (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; var tcs = new TaskCompletionSource <int>(); using (ct.Register(() => tcs.SetResult(0))) { Assert.IsTrue(tcs.Task.Wait(MediumNonDbgTimeout)); } var mock2 = new ProvidedCapabilityMock(); var result = DynamicSerializerState.CreateForRpc(); result.SetStruct(1, 2); result.WriteData(0, 654321); uint id = result.ProvideCapability(mock2).Value; result.LinkToCapability(1, id); mock.Return.SetResult(result); Assert.IsTrue(Assert.ThrowsExceptionAsync <TaskCanceledException>( async() => await answer2.WhenReturned).Wait(MediumNonDbgTimeout)); } } }
/// <summary> /// Detach this policy from given (censored) capability. /// </summary> /// <typeparam name="TCap">Capability interface type</typeparam> /// <param name="policy">Policy to detach</param> /// <param name="cap">Capability to clean</param> /// <returns>Clean capability instance (at least, without this interception policy)</returns> /// <exception cref="ArgumentNullException"><paramref name="policy"/> is null or /// <paramref name="cap"/> is null</exception> public static TCap Detach <TCap>(this IInterceptionPolicy policy, TCap cap) where TCap : class { if (policy == null) { throw new ArgumentNullException(nameof(policy)); } if (cap == null) { throw new ArgumentNullException(nameof(cap)); } switch (cap) { case Proxy proxy: return(CapabilityReflection.CreateProxy <TCap>(Detach(policy, proxy.ConsumedCap)) as TCap); case CensorCapability ccap: { var cur = ccap; var stk = new Stack <IInterceptionPolicy>(); do { if (policy.Equals(cur.Policy)) { var cur2 = cur.InterceptedCapability; foreach (var p in stk) { cur2 = p.Attach(cur2); } return(cur2 as TCap); } stk.Push(cur.Policy); cur = cur.InterceptedCapability as CensorCapability; }while (cur != null); return(ccap as TCap); } default: return(cap); } }
public void PipelineCallAfterDisposal() { (var server, var client) = SetupClientServerPair(); using (server) using (client) { Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain <BareProxy>(); Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); BareProxy pipelined; using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); pipelined = (BareProxy)CapabilityReflection.CreateProxy <BareProxy>( answer.Access(new MemberAccessPath(new MemberAccessPath.MemberAccess[] { new MemberAccessPath.StructMemberAccess(1) }))); } var args2 = DynamicSerializerState.CreateForRpc(); args2.SetStruct(1, 0); args2.WriteData(0, 654321); try { pipelined.Call(0x8765432187654321, 0x4444, args2); Assert.Fail("Expected an exception here"); } catch (ObjectDisposedException) { } catch (TaskCanceledException) { } } }
/// <summary> /// Attach this policy to given capability. /// </summary> /// <typeparam name="TCap">Capability interface type</typeparam> /// <param name="policy">Policy to attach</param> /// <param name="cap">Capability to censor</param> /// <returns>Censored capability instance</returns> /// <exception cref="ArgumentNullException"><paramref name="policy"/> is null or /// <paramref name="cap"/> is null</exception> public static TCap Attach <TCap>(this IInterceptionPolicy policy, TCap cap) where TCap : class { if (policy == null) { throw new ArgumentNullException(nameof(policy)); } if (cap == null) { throw new ArgumentNullException(nameof(cap)); } var cur = cap as CensorCapability; while (cur != null) { if (policy.Equals(cur.Policy)) { return(cap); } cur = cur.InterceptedCapability as CensorCapability; } switch (cap) { case Proxy proxy: return((CapabilityReflection.CreateProxy <TCap>( Attach(policy, proxy.ConsumedCap !)) as TCap) !); case ConsumedCapability ccap: return((new CensorCapability(ccap, policy) as TCap) !); default: var temp = (CapabilityReflection.CreateProxy <TCap>( CapabilityReflection.CreateSkeletonInternal(cap).AsCapability())) as TCap; return(Attach(policy, temp !) !); } }
/// <summary> /// Wraps a capability implementation in a Proxy. /// </summary> /// <param name="impl">Capability implementation</param> /// <returns>Proxy</returns> /// <exception cref="System.ArgumentNullException"><paramref name="impl"/> is null.</exception> /// <exception cref="InvalidCapabilityInterfaceException">No <see cref="SkeletonAttribute"/> found on implemented interface(s).</exception> /// <exception cref="System.InvalidOperationException">Mismatch between generic type arguments (if capability interface is generic).</exception> /// <exception cref="System.ArgumentException">Mismatch between generic type arguments (if capability interface is generic).</exception> /// <exception cref="System.Reflection.TargetInvocationException">Problem with instatiating the Skeleton (constructor threw exception).</exception> /// <exception cref="System.MemberAccessException">Caller does not have permission to invoke the Skeleton constructor.</exception> /// <exception cref="System.TypeLoadException">Problem with building the Skeleton type, or problem with loading some dependent class.</exception> public static BareProxy FromImpl(object impl) { return(new BareProxy(CapabilityReflection.CreateSkeletonInternal(impl).AsCapability())); }
public void PipelineMultiple() { (var server, var client) = SetupClientServerPair(); using (server) using (client) { Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain <BareProxy>(); Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); var pipelined = (BareProxy)CapabilityReflection.CreateProxy <BareProxy>(answer.Access(new MemberAccessPath(new MemberAccessPath.MemberAccess[] { new MemberAccessPath.StructMemberAccess(1) }))); var args2 = DynamicSerializerState.CreateForRpc(); args2.SetStruct(1, 0); args2.WriteData(0, 111111); var args3 = DynamicSerializerState.CreateForRpc(); args3.SetStruct(1, 0); args3.WriteData(0, 222222); using (var answer2 = pipelined.Call(0x1111111111111111, 0x1111, args2)) using (var answer3 = pipelined.Call(0x2222222222222222, 0x2222, args3)) { (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; Assert.AreEqual <ulong>(0x1234567812345678, interfaceId); Assert.AreEqual <ushort>(0x3333, methodId); Assert.AreEqual(ObjectKind.Struct, inargs.Kind); Assert.AreEqual(123456, inargs.ReadDataInt(0)); var mock2 = new ProvidedCapabilityMultiCallMock(); var result = DynamicSerializerState.CreateForRpc(); result.SetStruct(1, 2); result.WriteData(0, 654321); uint id = result.ProvideCapability(mock2).Value; result.LinkToCapability(1, id); mock.Return.SetResult(result); Assert.IsTrue(answer.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); Assert.IsFalse(ct.IsCancellationRequested); var args4 = DynamicSerializerState.CreateForRpc(); args4.SetStruct(1, 0); args4.WriteData(0, 333333); var args5 = DynamicSerializerState.CreateForRpc(); args5.SetStruct(1, 0); args5.WriteData(0, 444444); using (var answer4 = pipelined.Call(0x3333333333333333, 0x3333, args4)) using (var answer5 = pipelined.Call(0x4444444444444444, 0x4444, args5)) { var call2 = mock2.WhenCalled; var call3 = mock2.WhenCalled; var call4 = mock2.WhenCalled; var call5 = mock2.WhenCalled; Assert.IsTrue(call2.Wait(MediumNonDbgTimeout)); Assert.IsTrue(call3.Wait(MediumNonDbgTimeout)); Assert.IsTrue(call4.Wait(MediumNonDbgTimeout)); Assert.IsTrue(call5.Wait(MediumNonDbgTimeout)); Assert.AreEqual <ulong>(0x1111111111111111, call2.Result.InterfaceId); Assert.AreEqual <ulong>(0x2222222222222222, call3.Result.InterfaceId); Assert.AreEqual <ulong>(0x3333333333333333, call4.Result.InterfaceId); Assert.AreEqual <ulong>(0x4444444444444444, call5.Result.InterfaceId); var ret2 = DynamicSerializerState.CreateForRpc(); ret2.SetStruct(1, 0); ret2.WriteData(0, -1); call2.Result.Result.SetResult(ret2); var ret3 = DynamicSerializerState.CreateForRpc(); ret3.SetStruct(1, 0); ret3.WriteData(0, -2); call3.Result.Result.SetResult(ret3); var ret4 = DynamicSerializerState.CreateForRpc(); ret4.SetStruct(1, 0); ret4.WriteData(0, -3); call4.Result.Result.SetResult(ret4); var ret5 = DynamicSerializerState.CreateForRpc(); ret5.SetStruct(1, 0); ret5.WriteData(0, -4); call5.Result.Result.SetResult(ret5); Assert.IsTrue(answer2.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); Assert.IsTrue(answer3.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); Assert.IsTrue(answer4.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); Assert.IsTrue(answer5.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); Assert.AreEqual(-1, answer2.WhenReturned.Result.ReadDataInt(0)); Assert.AreEqual(-2, answer3.WhenReturned.Result.ReadDataInt(0)); Assert.AreEqual(-3, answer4.WhenReturned.Result.ReadDataInt(0)); Assert.AreEqual(-4, answer5.WhenReturned.Result.ReadDataInt(0)); } } } } }
public void PipelineAfterReturn() { (var server, var client) = SetupClientServerPair(); using (server) using (client) { Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain <BareProxy>(); Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; Assert.AreEqual <ulong>(0x1234567812345678, interfaceId); Assert.AreEqual <ushort>(0x3333, methodId); Assert.AreEqual(ObjectKind.Struct, inargs.Kind); Assert.AreEqual(123456, inargs.ReadDataInt(0)); var mock2 = new ProvidedCapabilityMock(); var result = DynamicSerializerState.CreateForRpc(); result.SetStruct(1, 2); result.WriteData(0, 654321); uint id = result.ProvideCapability(mock2).Value; result.LinkToCapability(1, id); mock.Return.SetResult(result); using (var pipelined = (BareProxy)CapabilityReflection.CreateProxy <BareProxy>( answer.Access( new MemberAccessPath( new MemberAccessPath.MemberAccess[] { new MemberAccessPath.StructMemberAccess(1) })))) { var args2 = DynamicSerializerState.CreateForRpc(); args2.SetStruct(1, 0); args2.WriteData(0, 654321); using (var answer2 = pipelined.Call(0x8765432187654321, 0x4444, args2)) { Assert.IsTrue(answer.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); Assert.IsTrue(mock2.WhenCalled.Wait(MediumNonDbgTimeout)); (var interfaceId2, var methodId2, var inargs2, var ct2) = mock2.WhenCalled.Result; Assert.AreEqual <ulong>(0x8765432187654321, interfaceId2); Assert.AreEqual <ushort>(0x4444, methodId2); Assert.AreEqual(ObjectKind.Struct, inargs2.Kind); Assert.AreEqual(654321, inargs2.ReadDataInt(0)); var result2 = DynamicSerializerState.CreateForRpc(); result2.SetStruct(1, 0); result2.WriteData(0, 222222); mock2.Return.SetResult(result2); Assert.IsTrue(answer2.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); var outresult2 = answer2.WhenReturned.Result; Assert.AreEqual(ObjectKind.Struct, outresult2.Kind); Assert.AreEqual(222222, outresult2.ReadDataInt(0)); } } } } }
public void IsValidCapabilityInterface() { Assert.ThrowsException <ArgumentNullException>(() => CapabilityReflection.IsValidCapabilityInterface(null)); Assert.IsTrue(CapabilityReflection.IsValidCapabilityInterface(typeof(ITestInterface))); Assert.IsFalse(CapabilityReflection.IsValidCapabilityInterface(typeof(CapabilityReflectionTests))); }
public void ValidateCapabilityInterface() { Assert.ThrowsException <ArgumentNullException>(() => CapabilityReflection.ValidateCapabilityInterface(null)); CapabilityReflection.ValidateCapabilityInterface(typeof(ITestInterface)); Assert.ThrowsException <InvalidCapabilityInterfaceException>(() => CapabilityReflection.ValidateCapabilityInterface(typeof(CapabilityReflectionTests))); }
/// <summary> /// Wraps a capability implementation in a Proxy. /// </summary> /// <param name="impl">Capability implementation</param> /// <returns>Proxy</returns> /// <exception cref="System.ArgumentNullException"><paramref name="impl"/> is null.</exception> /// <exception cref="InvalidCapabilityInterfaceException">No <see cref="SkeletonAttribute"/> found on implemented interface(s).</exception> /// <exception cref="System.InvalidOperationException">Mismatch between generic type arguments (if capability interface is generic).</exception> /// <exception cref="System.ArgumentException">Mismatch between generic type arguments (if capability interface is generic).</exception> /// <exception cref="System.Reflection.TargetInvocationException">Problem with instatiating the Skeleton (constructor threw exception).</exception> /// <exception cref="System.MemberAccessException">Caller does not have permission to invoke the Skeleton constructor.</exception> /// <exception cref="System.TypeLoadException">Problem with building the Skeleton type, or problem with loading some dependent class.</exception> public static BareProxy FromImpl(object impl) { return(new BareProxy(LocalCapability.Create(CapabilityReflection.CreateSkeleton(impl)))); }
protected static T SetupEnginePair <T>(object main, DecisionTree decisionTree, out EnginePair pair) where T : class { pair = new EnginePair(decisionTree); pair.Engine1.Main = main; return(CapabilityReflection.CreateProxy <T>(pair.Endpoint2.QueryMain()) as T); }