IEnumerable <TestScenarioStep> GetCompleteScenario(Func <object> currentMessageFunc, string clientId, string password, CancellationToken cancellationToken) { yield return(TestScenarioStep.Write(new ConnectPacket { ClientId = clientId, CleanSession = false, HasUsername = true, Username = clientId, HasPassword = true, Password = password, KeepAliveInSeconds = 120 })); object message = currentMessageFunc(); var connackPacket = message as ConnAckPacket; if (connackPacket == null) { throw new InvalidOperationException(string.Format("{1}: Expected CONNACK, received {0}", message, clientId)); } else if (connackPacket.ReturnCode != ConnectReturnCode.Accepted) { throw new InvalidOperationException(string.Format("{1}: Expected successful CONNACK, received CONNACK with return code of {0}", connackPacket.ReturnCode, clientId)); } foreach (TestScenarioStep step in this.GetScenario(currentMessageFunc, clientId, cancellationToken)) { yield return(step); } }
protected override IEnumerable <IEnumerable <TestScenarioStep> > GetScenarioNested(Func <object> currentMessageFunc, string clientId, CancellationToken cancellationToken) { yield return(GetSubscribeSteps(currentMessageFunc, clientId)); while (!cancellationToken.IsCancellationRequested) { yield return(GetPublishSteps(currentMessageFunc, clientId, QualityOfService.AtLeastOnce, "devices/{0}/messages/events", 1, 138, 353)); yield return(new[] { TestScenarioStep.Wait(TimeSpan.FromMinutes(1)) }); } }
protected static IEnumerable <TestScenarioStep> GetPublishSteps(Func <object> currentMessageFunc, string clientId, QualityOfService qos, string topicNamePattern, int count, int minPayloadSize, int maxPayloadSize) { Contract.Requires(count > 0); Contract.Requires(qos < QualityOfService.ExactlyOnce); PublishPacket[] publishPackets = Enumerable.Repeat(0, count) .Select(_ => new PublishPacket(qos, false, false) { TopicName = string.Format(topicNamePattern, clientId), PacketId = Random.Next(1, ushort.MaxValue), Payload = GetPayloadBuffer(Random.Next(minPayloadSize, maxPayloadSize)) }) .ToArray(); yield return(TestScenarioStep.Write(qos > QualityOfService.AtMostOnce, publishPackets)); if (qos == QualityOfService.AtMostOnce) { yield break; } int acked = 0; do { object receivedMessage = currentMessageFunc(); var pubackPacket = receivedMessage as PubAckPacket; if (pubackPacket == null || pubackPacket.PacketId != publishPackets[acked].PacketId) { throw new InvalidOperationException(string.Format("{0}: Expected PUBACK({1}), received {2}", clientId, publishPackets[acked].PacketId, receivedMessage)); } if (acked < count - 1) { yield return(TestScenarioStep.ReadMore()); } acked++; }while (acked < count); }
protected static IEnumerable <TestScenarioStep> GetSubscribeSteps(Func <object> currentMessageFunc, string clientId, string topicNamePattern) { int subscribePacketId = Random.Next(1, ushort.MaxValue); yield return(TestScenarioStep.Write( new SubscribePacket( subscribePacketId, new SubscriptionRequest(string.Format(topicNamePattern, clientId), QualityOfService.ExactlyOnce)))); object message = currentMessageFunc(); var subackPacket = message as SubAckPacket; if (subackPacket == null) { throw new InvalidOperationException(string.Format("{1}: Expected SUBACK, received {0}", message, clientId)); } else if (subackPacket.PacketId == subscribePacketId && subackPacket.ReturnCodes[0] > QualityOfService.ExactlyOnce) { throw new InvalidOperationException($"{clientId}: Expected successful SUBACK({subscribePacketId.ToString()}), received SUBACK({subackPacket.PacketId.ToString()}) with QoS={subackPacket.ReturnCodes[0].ToString()}"); } }