public static IDisposable StartSendingHeartbeats(this AmqpTestFramework testFramework, ConnectionId connectionId, TimeSpan interval) { var cancelationTokenSource = new CancellationTokenSource(); void SendHeartbeat() { testFramework .Send(connectionId, new HeartbeatFrame <Heartbeat>(0, new Heartbeat())); } void Schedule() { try { Task.Delay(interval, cancelationTokenSource.Token) .ContinueWith(task => SendHeartbeat(), cancelationTokenSource.Token) .ContinueWith(task => Schedule(), cancelationTokenSource.Token); } catch (OperationCanceledException) { } } Schedule(); return(new DisposableAction(() => cancelationTokenSource.Cancel())); }
public static AmqpTestFramework WithHeartbeats(this AmqpTestFramework testFramework, TimeSpan interval = default) { interval = interval == default ? TimeSpan.FromSeconds(DefaultHeartbeatIntervalInSeconds) : interval; var heartbeatRunners = new ConcurrentDictionary <ConnectionId, IDisposable>(); return(testFramework .On <Connection.TuneOk>((connectionId, frame) => { heartbeatRunners.TryAdd(connectionId, testFramework.StartSendingHeartbeats(connectionId, interval)); }) .On <Connection.Close>((connectionId, frame) => { if (heartbeatRunners.TryRemove(connectionId, out var runner)) { runner.Dispose(); } }) .On <Connection.CloseOk>((connectionId, frame) => { if (heartbeatRunners.TryRemove(connectionId, out var runner)) { runner.Dispose(); } }) .On <Heartbeat>((__, _) => { })); }
protected override void Given(IServiceContainer container) { var testServer = new AmqpTestFramework(Test.It.With.Amqp091.Protocol.Amqp091.ProtocolResolver); testServer .WithDefaultProtocolHeaderNegotiation() .WithDefaultSecurityNegotiation(heartbeatInterval: TimeSpan.FromSeconds(1)) .WithDefaultConnectionOpenNegotiation() .WithHeartbeats(interval: TimeSpan.FromSeconds(1)) .WithDefaultConnectionCloseNegotiation(); testServer.On <Heartbeat>((connectionId, frame) => { _heartbeatCancelationToken.Cancel(true); _heartbeats.Add(frame); _heartbeatCancelationToken = new CancellationTokenSource(); Task.Delay(4000) .ContinueWith(task => { _missingHeartbeat = true; ServiceController.Stop(); }, _heartbeatCancelationToken.Token); }); Task.Delay(TimeSpan.FromSeconds(10)).ContinueWith(task => { ServiceController.Stop(); }); container.RegisterSingleton(() => testServer.ConnectionFactory.ToRabbitMqConnectionFactory()); }
public static AmqpTestFramework WithDefaultProtocolHeaderNegotiation(this AmqpTestFramework testFramework) { return(testFramework .On <ProtocolHeader>((connectionId, frame) => testFramework.Send(connectionId, new MethodFrame <Connection.Start>(frame.Channel, new Connection.Start { VersionMajor = Octet.From((byte)frame.Message.Version.Major), VersionMinor = Octet.From((byte)frame.Message.Version.Minor), Locales = Longstr.From(Encoding.UTF8.GetBytes("en_US")), Mechanisms = Longstr.From(Encoding.UTF8.GetBytes("PLAIN")), })))); }
protected override void Given(IServiceContainer container) { var channelClosed = false; void TryStop() { if (channelClosed && _basicPublish.Count == 2) { ServiceController.Stop(); } } var testServer = new AmqpTestFramework(RabbitMq091.ProtocolResolver); testServer .WithDefaultProtocolHeaderNegotiation() .WithDefaultSecurityNegotiation(heartbeatInterval: TimeSpan.FromSeconds(5)) .WithDefaultConnectionOpenNegotiation() .WithHeartbeats(interval: TimeSpan.FromSeconds(5)) .WithDefaultConnectionCloseNegotiation(); testServer.On <Channel.Open, Channel.OpenOk>((connectionId, frame) => new Channel.OpenOk()); testServer.On <Channel.Close, Channel.CloseOk>((connectionId, frame) => new Channel.CloseOk()); testServer.On <Exchange.Declare, Exchange.DeclareOk>((connectionId, frame) => { _exchangeDeclare.Add(frame); return(new Exchange.DeclareOk()); }); testServer.On <Channel.Close>((id, frame) => { channelClosed = true; TryStop(); }); testServer.On <Amqp091.Protocol.Basic.Publish>((connectionId, frame) => { _basicPublish.Add(frame); testServer.Send(connectionId, new MethodFrame <Basic.Ack>(frame.Channel, new Basic.Ack { DeliveryTag = DeliveryTag.From(_basicPublish.Count(methodFrame => methodFrame.Channel == frame.Channel)) })); }); testServer.On <Confirm.Select, Confirm.SelectOk>((connectionId, frame) => { _selectOkSent = true; return(new Confirm.SelectOk()); }); container.RegisterSingleton(() => testServer.ConnectionFactory.ToRabbitMqConnectionFactory()); }
public static AmqpTestFramework WithDefaultSecurityNegotiation(this AmqpTestFramework testFramework, TimeSpan heartbeatInterval = default) { heartbeatInterval = heartbeatInterval == default ? TimeSpan.FromSeconds(DefaultHeartbeatIntervalInSeconds) : heartbeatInterval; return(testFramework .On <Connection.StartOk>((connectionId, frame) => testFramework.Send(connectionId, new MethodFrame <Connection.Secure>(frame.Channel, new Connection.Secure { Challenge = Longstr.From(Encoding.UTF8.GetBytes("challenge")) }))) .On <Connection.SecureOk>((connectionId, frame) => testFramework.Send(connectionId, new MethodFrame <Connection.Tune>(frame.Channel, new Connection.Tune { ChannelMax = Short.From(0), FrameMax = Long.From(0), Heartbeat = Short.From((short)(heartbeatInterval.TotalMilliseconds / 1000)) })))); }
protected override void Given(IServiceContainer container) { var closedChannels = new ConcurrentBag <short>(); void TryStop() { if (closedChannels.Count == NumberOfPublishes && _basicPublish.Count == NumberOfPublishes) { ServiceController.Stop(); } } var testServer = new AmqpTestFramework(Amqp091.Protocol.Amqp091.ProtocolResolver); testServer .WithDefaultProtocolHeaderNegotiation() .WithDefaultSecurityNegotiation(heartbeatInterval: TimeSpan.FromSeconds(5)) .WithDefaultConnectionOpenNegotiation() .WithHeartbeats(interval: TimeSpan.FromSeconds(5)) .WithDefaultConnectionCloseNegotiation(); testServer.On <Channel.Open, Channel.OpenOk>((connectionId, frame) => new Channel.OpenOk()); testServer.On <Channel.Close, Channel.CloseOk>((connectionId, frame) => new Channel.CloseOk()); testServer.On <Exchange.Declare, Exchange.DeclareOk>((connectionId, frame) => { _exchangeDeclare.Add(frame); return(new Exchange.DeclareOk()); }); testServer.On <Channel.Close>((id, frame) => { closedChannels.Add(frame.Channel); TryStop(); }); testServer.On <Basic.Publish>((connectionId, frame) => { _basicPublish.Add(frame); }); container.RegisterSingleton(() => testServer.ConnectionFactory.ToRabbitMqConnectionFactory()); }
public static AmqpTestFramework WithDefaultConnectionCloseNegotiation(this AmqpTestFramework testFramework) { return(testFramework .On <Connection.Close, Connection.CloseOk>((connectionId, frame) => new Connection.CloseOk())); }
public static void Send <T>(this AmqpTestFramework testFramework, ConnectionId connectionId, short channel, T message) where T : class, INonContentMethod, IServerMethod { testFramework.Send <T>(connectionId, new MethodFrame <T>(channel, message)); }
protected override void Given(IServiceContainer container) { var closedChannels = new ConcurrentBag <short>(); void TryStop() { if (closedChannels.Count == Parallelism && _basicPublishes.Count == Parallelism && _acks.Count == Parallelism) { ServiceController.Stop(); } } var testServer = new AmqpTestFramework(Amqp091.Protocol.Amqp091.ProtocolResolver); testServer .WithDefaultProtocolHeaderNegotiation() .WithDefaultSecurityNegotiation(heartbeatInterval: TimeSpan.FromSeconds(5)) .WithDefaultConnectionOpenNegotiation() .WithHeartbeats(interval: TimeSpan.FromSeconds(5)) .WithDefaultConnectionCloseNegotiation(); testServer.On <Channel.Open, Channel.OpenOk>((connectionId, frame) => new Channel.OpenOk()); testServer.On <Channel.Close, Channel.CloseOk>((connectionId, frame) => new Channel.CloseOk()); testServer.On <Exchange.Declare, Exchange.DeclareOk>((connectionId, frame) => { _exchangesDeclared.Add(frame); return(new Exchange.DeclareOk()); }); testServer.On <Queue.Declare, Queue.DeclareOk>((connectionId, frame) => { _queuesDeclared.Add(frame); return(new Queue.DeclareOk()); }); testServer.On <Queue.Bind, Queue.BindOk>((connectionId, frame) => { _queuesBound.Add(frame); return(new Queue.BindOk()); }); testServer.On <Channel.Close>((id, frame) => { closedChannels.Add(frame.Channel); TryStop(); }); testServer.On <Basic.Publish>((connectionId, frame) => { _basicPublishes.Add(frame); }); testServer.On <Basic.Consume>((connectionId, frame) => { var consumerTag = Guid.NewGuid().ToString(); _basicConsumes.Add(frame); // We need to respond with ConsumeOk before we can start delivering messages to the client testServer.Send(connectionId, new MethodFrame <Basic.ConsumeOk>(frame.Channel, new Basic.ConsumeOk { ConsumerTag = ConsumerTag.From(consumerTag) })); Task.Run(() => { var testMessage = new TestMessage("This is sent from server."); var payload = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(testMessage)); testServer.Send <Basic.Deliver, Basic.ContentHeader>(connectionId, new MethodFrame <Basic.Deliver>(frame.Channel, new Basic.Deliver { ConsumerTag = ConsumerTag.From(consumerTag), ContentHeader = new Basic.ContentHeader { BodySize = payload.Length } } .AddContentBodyFragments(new ContentBody { Payload = payload }))); }); }); testServer.On <Basic.Cancel, Basic.CancelOk>((connectionId, frame) => new Basic.CancelOk { ConsumerTag = frame.Message.ConsumerTag }); testServer.On <Basic.Ack>((connectionId, frame) => { _acks.Add(frame); TryStop(); }); ServiceController.OnStopped += code => { testServer.Dispose(); }; container.RegisterSingleton(() => testServer.ConnectionFactory.ToRabbitMqConnectionFactory()); }