PeekMessages(Utils.NotifyAsyncServer eventServer, int timeout, System.DateTime messageTimeLimit, int totalLimit, Func<NotificationMessageHolderType, bool> messageCheck) { Dictionary<NotificationMessageHolderType, XmlElement> result = new Dictionary<NotificationMessageHolderType, XmlElement>(); int messagesCount = 0; while (true) { Dictionary<Notify, byte[]> notifications = eventServer.Peek(timeout, _semaphore.StopEvent); foreach (Notify notify in notifications.Keys) { LogNotificationStep(notifications[notify]); if (notify.NotificationMessage != null) { messagesCount += notify.NotificationMessage.Length; } if (messagesCount>=totalLimit) { break; } } Dictionary<NotificationMessageHolderType, XmlElement> messages = GetRawElements(notifications); Dictionary<NotificationMessageHolderType, XmlElement> filtered = GetFilteredList(messages, messageCheck); foreach (NotificationMessageHolderType key in filtered.Keys) { result.Add(key, filtered[key]); } if ((messagesCount >= totalLimit) || (messageTimeLimit < System.DateTime.Now)) { break; } } return result; }
public void AccessDoorTest() { EndpointReferenceType subscriptionReference = null; System.DateTime subscribeStarted = System.DateTime.MaxValue; int timeout = _eventSubscriptionTimeout; Utils.NotifyAsyncServer eventServer = null; RunTest( () => { // 3. Get complete list of doors from the DUT (see Annex A.1). List<DoorInfo> fullDoorsList = GetDoorInfoList(); //4. ONVIF Client selects one door from the complete list of doors at step // 3 with DoorInfo.Capabilities.Access equal to true. If there is no such Door, // skip other steps and go to the next test. List<DoorInfo> doorInfos = fullDoorsList.Where( D => D.Capabilities != null && D.Capabilities.AccessSpecified && D.Capabilities.Access).ToList(); if (doorInfos.Count == 0) { LogTestEvent("No Doors with required Capabilities found, exit the test."); return; } //5. Test Operator puts Door in state when AccessDoor command will be accepted // with state change. // ToDo : discuss with customer if there are better methods to select Door // which will be convenient for operator List<DoorSelectionData.DoorShortInfo> tokens = doorInfos.Select( D => new DoorSelectionData.DoorShortInfo() { Token = D.token, Name = D.Name }).ToList(); string selectedToken = tokens.First().Token; string message ="Put the Door with token '{0}' into state which allows 'Access' operation"; Definitions.Data.DoorSelectionData data = new TestTool.Tests.Definitions.Data.DoorSelectionData(); data.Doors = tokens; data.SelectedToken = selectedToken; data.MessageTemplate = message; WaitHandle formHandle = _operator.ShowCountdownMessage(_messageTimeout, data); try { Sleep(_messageTimeout, new WaitHandle[] { formHandle }); } finally { _operator.HideCountdownMessage(); } selectedToken = data.SelectedToken; LogTestEvent(string.Format("Door with token '{0}' will be used for test{1}", selectedToken, Environment.NewLine)); TopicInfo topic = ConstructTopic(new string[] { "Door", "State", "DoorMode" }); TestTool.Proxies.Event.FilterType filter = CreateSubscriptionFilter(topic); Func<NotificationMessageHolderType, bool> messageCheck = (n) => CheckDoorEventSource(n, selectedToken); // Subscribe eventServer = new TestTool.Tests.TestCases.Utils.NotifyAsyncServer(_nic); //SetupNotifyServer2(eventServer); string notificationsUri = eventServer.GetNotificationUri(); BeginStep("Begin listening"); eventServer.StartCollecting(_semaphore.StopEvent); StepPassed(); //6. ONVIF Client will invoke SubscribeRequest message with tns1:DoorControl/DoorMode // Topic as Filter and an InitialTerminationTime of 60s to ensure that the SubscriptionManager // is deleted after one minute. //7. Verify that the DUT sends a SubscribeResponse message. subscriptionReference = CreateSubscription(filter, timeout, notificationsUri, out subscribeStarted); LogTestEvent(string.Format("Wait until message for Door with token='{0}' is received", selectedToken)+Environment.NewLine); System.DateTime messageTimeLimit = System.DateTime.Now.AddMilliseconds(_operationDelay); string initialMode = string.Empty; //8. Verify that DUT sends Notify message for selected Door with current state // (Notifications for other Doors will be ignored for this test case). //9. Verify received Notify message (correct value for UTC time, TopicExpression and // wsnt:Message). //10. Verify that PropertyOperation="Initialized". //11. Verify that TopicExpression is equal to tns1:DoorControl/DoorMode. //12. Verify that notification contains Source.SimpleItem item with Name="DoorToken" // and Value is equal to selected Door Token. //13. Verify that notification contains Data.SimpleItem item with Name="DoorMode" // and Value with type is equal to tdc:DoorMode. { System.Diagnostics.Debug.WriteLine("Wait for messages with PropertyOperation=INITIALIZED"); Dictionary<NotificationMessageHolderType, XmlElement> initialMessages = PeekMessages(eventServer, _messageTimeout, messageTimeLimit, fullDoorsList.Count, messageCheck); Assert(initialMessages.Count > 0, string.Format("Message for the door with token='{0}' has not been received", selectedToken ), "Check that the message for selected door has been received"); // validate ValidateMessages(initialMessages, topic, OnvifMessage.INITIALIZED, selectedToken, ValidateDoorModeMessage); NotificationMessageHolderType receivedMessage = initialMessages.Keys.First(); XmlElement dataElement = receivedMessage.Message.GetMessageData(); Dictionary<string, string> dataSimpleItems = dataElement.GetMessageElementSimpleItems(); initialMode = dataSimpleItems["State"]; } //14. ONVIF Client will invoke AccessDoorRequest message (Token = [selected Door token]) // to change door state. //15. Verify the AccessDoorResponse message from the DUT. AccessDoor(selectedToken, null, null, null, null, null); messageTimeLimit = System.DateTime.Now.AddSeconds(_operationDelay/1000); LogTestEvent("Wait until message with PropertyOperation=\"Changed\" is received" + Environment.NewLine); //16. Verify that DUT sends Notify message for selected Door with current state // (Notifications for other Doors will be ignored for this test case). //17. Verify received Notify message (correct value for UTC time, TopicExpression and // wsnt:Message). //18. Verify that PropertyOperation="Changed". //19. Verify that TopicExpression is equal to tns1:DoorControl/DoorMode. //20. Verify that notification contains Source.SimpleItem item with Name="DoorToken" // and Value is equal to selected Door Token. //21. Verify that notification contains Data.SimpleItem item with Name="DoorMode" // and Value equal to “Accessed”. { System.Diagnostics.Debug.WriteLine("Wait for first 'CHANGED' message"); Dictionary<NotificationMessageHolderType, XmlElement> doorModeChangedMessages = PeekMessages(eventServer, _messageTimeout, messageTimeLimit, 1, messageCheck); Assert(doorModeChangedMessages.Count > 0, string.Format("Message for the door with token='{0}' has not been received", selectedToken), "Check that the message for selected door has been received"); // validate ValidateMessages(doorModeChangedMessages, topic, selectedToken, ValidateDoorModeMessage); NotificationMessageHolderType receivedMessage = doorModeChangedMessages.Keys.First(); ValidateDoorModeSimpleItem(receivedMessage, DoorMode.Accessed); } LogTestEvent("Wait until message with PropertyOperation=\"Changed\" is received" + Environment.NewLine); //22. ONVIF Client will wait for next Notification for selected Door. //23. Verify that DUT sends Notify message for selected Door with current state // (Notifications for other Doors will be ignored for this test case). //24. Verify received Notify message (correct value for UTC time, TopicExpression // and wsnt:Message). //25. Verify that PropertyOperation="Changed". //26. Verify that TopicExpression is equal to tns1:DoorControl/DoorMode. //27. Verify that notification contains Source.SimpleItem item with Name="DoorToken" // and Value is equal to selected Door Token. //28. Verify that notification contains Data.SimpleItem item with Name="DoorMode" and // Value equal to previous state (previous state was received with Notification from step 8). { System.Diagnostics.Debug.WriteLine("Wait for second 'CHANGED' message"); messageTimeLimit = System.DateTime.Now.AddSeconds(_messageTimeout / 1000); // ToDo: should we wait for "_operationDelay" ? Dictionary<NotificationMessageHolderType, XmlElement> doorModeChangedMessages = PeekMessages(eventServer, _messageTimeout, messageTimeLimit, 1, messageCheck); Assert(doorModeChangedMessages.Count > 0, string.Format("Message for the door with token='{0}' has not been received", selectedToken), "Check that the message for selected door has been received"); // validate ValidateMessages(doorModeChangedMessages, topic, selectedToken, ValidateDoorModeMessage); NotificationMessageHolderType receivedMessage = doorModeChangedMessages.Keys.First(); ValidateDoorModeSimpleItem(receivedMessage, initialMode); } eventServer.StopCollecting(); }, () => { _operator.HideCountdownMessage(); if (eventServer != null) { eventServer.StopCollecting(); } ReleaseSubscription(subscribeStarted, subscriptionReference, timeout); }); }