void CommonDoorPropertyEventTest(Func <DoorInfo, bool> doorCapabilitiesTest, TopicInfo topicInfo, Action <XmlElement, TopicInfo> validateTopic, ValidateMessageFunction validateMessageFunction, Func <DoorState, string> stateValueSelector, string stateSimpleItemName) { EndpointReferenceType subscriptionReference = null; System.DateTime subscribeStarted = System.DateTime.MaxValue; int timeout = 60; RunTest( () => { //3. Get complete list of doors from the DUT (see Annex A.1). //4. Check that there is at least one Door with [DOOR CAPABILITIES TEST]= “true”. // Otherwise skip other steps and go to the next test. List <DoorInfo> fullList = GetDoorInfoList(); List <DoorInfo> doors = fullList.Where(D => doorCapabilitiesTest(D)).ToList(); if (doors.Count == 0) { LogTestEvent("No Doors with required Capabilities found, exit the test" + Environment.NewLine); return; } //5. ONVIF Client will invoke GetEventPropertiesRequest message to retrieve // all events supported by the DUT. //6. Verify the GetEventPropertiesResponse message from the DUT. //7. Check if there is an event with Topic [TOPIC]. If there is no event with // such Topic skip other steps, fail the test and go to the next test. XmlElement topicElement = GetTopicElement(topicInfo); // if only one topic should be checked //ValidateTopicXml(topicElement); Assert(topicElement != null, string.Format("Topic {0} not supported", topicInfo.GetDescription()), "Check that the event topic is supported"); //8. Check that this event is a Property event (MessageDescription.IsProperty="true"). //9. Check that this event contains Source.SimpleItemDescription item with // Name="DoorToken" and Type="pt:ReferenceToken". //10. Check that this event contains Data.SimpleItemDescription item with Name=[NAME] // and Type=[TYPE]. XmlElement messageDescription = topicElement.GetMessageDescription(); validateTopic(messageDescription, topicInfo); FilterInfo filter = CreateFilter(topicInfo, messageDescription); Dictionary <NotificationMessageHolderType, XmlElement> notifications = new Dictionary <NotificationMessageHolderType, XmlElement>(); //11. 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. //12. Verify that the DUT sends a SubscribeResponse message. //13. Verify that DUT sends Notify message(s) //14. Verify received Notify messages (correct value for UTC time, TopicExpression and wsnt:Message). //15. Verify that TopicExpression is equal to tns1:DoorControl/DoorMode for all received Notify messages. //16. Verify that each notification contains Source.SimpleItem item with Name="DoorToken" and Value is equal to one of existing Door Tokens (e.g. complete list of doors contains Door with the same token). Verify that there are Notification messages for each Door. //17. Verify that each notification contains Data.SimpleItem item with Name="DoorMode" and Value with type is equal to tdc:DoorMode. //18. Verify that Notify PropertyOperation="Initialized". subscriptionReference = ReceiveMessages(filter.Filter, timeout, new Action(() => { }), fullList.Count, notifications, out subscribeStarted); EntityListInfo <DoorInfo> data = new EntityListInfo <DoorInfo>(); data.FullList = fullList; data.FilteredList = doors; ValidateMessages(notifications, topicInfo, OnvifMessage.INITIALIZED, data, validateMessageFunction); Dictionary <string, NotificationMessageHolderType> doorsMessages = new Dictionary <string, NotificationMessageHolderType>(); ValidateMessagesSet(notifications.Keys, doors, doorsMessages); //19. ONVIF Client will invoke GetDoorStateRequest message for each Door // with corresponding tokens. //20. Verify the GetDoorStateResponse messages from the DUT. Verify that // Data.SimpleItem item with Name=[SIMPLEITEMNAME] from Notification message has the // same value with [ELEMENT SELECTION] elements from corresponding GetDoorStateResponse // messages for each Door. foreach (string doorToken in doorsMessages.Keys) { DoorState state = GetDoorState(doorToken); string expectedState = stateValueSelector(state); XmlElement dataElement = doorsMessages[doorToken].Message.GetMessageData(); Dictionary <string, string> dataSimpleItems = dataElement.GetMessageElementSimpleItems(); string notificationState = dataSimpleItems[stateSimpleItemName]; Assert(expectedState == notificationState, string.Format("State is different ({0} in GetDoorStateResponse, {1} in Notification)", expectedState, notificationState), "Check that state is the same in Notification and in GetDoorStateResponse"); } }, () => { ReleaseSubscription(subscribeStarted, subscriptionReference, timeout); }); }
void CommonDoorPropertyEventTestBis(Func <DoorInfo, bool> doorCapabilitiesTest, TopicInfo topicInfo, Action <XmlElement, TopicInfo> validateTopic, ValidateMessageFunction validateMessageFunction, Func <DoorState, string> stateValueSelector, string stateSimpleItemName) { int actualTerminationTime = 60; if (_eventSubscriptionTimeout != 0) { actualTerminationTime = _eventSubscriptionTimeout; } int timeout = _operationDelay / 1000; RunTest( () => { //3. Get complete list of doors from the DUT (see Annex A.1). //4. Check that there is at least one Door with [DOOR CAPABILITIES TEST]= “true”. // Otherwise skip other steps and go to the next test. List <DoorInfo> fullList = GetDoorInfoList(); List <DoorInfo> doors = fullList.Where(D => doorCapabilitiesTest(D)).ToList(); Assert(doors.Any(), "No Doors with required Capabilities found, exit the test.", "Check there is appropriate door for test"); //5. ONVIF Client will invoke GetEventPropertiesRequest message to retrieve // all events supported by the DUT. //6. Verify the GetEventPropertiesResponse message from the DUT. //7. Check if there is an event with Topic [TOPIC]. If there is no event with // such Topic skip other steps, fail the test and go to the next test. XmlElement topicElement = GetTopicElement(topicInfo); // if only one topic should be checked //ValidateTopicXml(topicElement); Assert(topicElement != null, string.Format("Topic {0} not supported", topicInfo.GetDescription()), "Check that the event topic is supported"); //8. Check that this event is a Property event (MessageDescription.IsProperty="true"). //9. Check that this event contains Source.SimpleItemDescription item with // Name="DoorToken" and Type="pt:ReferenceToken". //10. Check that this event contains Data.SimpleItemDescription item with Name=[NAME] // and Type=[TYPE]. XmlElement messageDescription = topicElement.GetMessageDescription(); validateTopic(messageDescription, topicInfo); FilterInfo filter = CreateFilter(topicInfo, messageDescription); //11. 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. //12. Verify that the DUT sends a SubscribeResponse message. //13. Verify that DUT sends Notify message(s) //14. Verify received Notify messages (correct value for UTC time, TopicExpression and wsnt:Message). //15. Verify that TopicExpression is equal to tns1:DoorControl/DoorMode for all received Notify messages. //16. Verify that each notification contains Source.SimpleItem item with Name="DoorToken" and Value is equal to one of existing Door Tokens (e.g. complete list of doors contains Door with the same token). Verify that there are Notification messages for each Door. //17. Verify that each notification contains Data.SimpleItem item with Name="DoorMode" and Value with type is equal to tdc:DoorMode. //18. Verify that Notify PropertyOperation="Initialized". bool UseNotify = UseNotifyToGetEvents; Dictionary <NotificationMessageHolderType, XmlElement> notifications = null; CurrentSubsciption = null; bool Timeout = false; try { // Handler = new SubscriptionHandler(this, UseNotify); // Handler.SetPolicy(new EventsVerifyPolicy(UseNotify)); // EnsureServiceAddressNotEmpty(); // Handler.SetAddress(_eventServiceAddress); // Handler.Subscribe(filter.Filter, actualTerminationTime); // int MessagesCount = 0; // // Timeout = !Handler.WaitMessages( // timeout, // (n) => { return ++MessagesCount >= doors.Count; }, // SubscriptionHandler.WaitCondition.WC_AllExit, // out notifications); CurrentSubsciption = new SubscriptionHandler(this, UseNotify, GetEventServiceAddress()); CurrentSubsciption.Subscribe(filter.Filter, actualTerminationTime); var pullingCondition = new WaitNotificationsForAllDoorsPollingCondition(timeout, doors.Select(e => e.token)); Timeout = !CurrentSubsciption.WaitMessages(1, pullingCondition, out notifications); } finally { UnsubscribeCurrentSubsciption(); } Assert(null != notifications && notifications.Any(), string.Format("No notification messages are received.{0}WARNING: may be Operation delay is too low", Environment.NewLine), "Check that DUT sent any notification messages"); if (Timeout && notifications.Count() < doors.Count()) { LogTestEvent(string.Format("Not enough notification messages are received:{0}" + "received {1} notifications while there exist {2} doors.{0}" + "WARNING: may be Operation delay is too low{0}", Environment.NewLine, notifications.Count(), doors.Count())); } EntityListInfo <DoorInfo> data = new EntityListInfo <DoorInfo>(); data.FullList = fullList; data.FilteredList = doors; ValidateMessages(notifications, topicInfo, OnvifMessage.INITIALIZED, data, validateMessageFunction); Dictionary <string, NotificationMessageHolderType> doorsMessages = new Dictionary <string, NotificationMessageHolderType>(); ValidateMessagesSet(notifications.Keys, doors, doorsMessages); //19. ONVIF Client will invoke GetDoorStateRequest message for each Door // with corresponding tokens. //20. Verify the GetDoorStateResponse messages from the DUT. Verify that // Data.SimpleItem item with Name=[SIMPLEITEMNAME] from Notification message has the // same value with [ELEMENT SELECTION] elements from corresponding GetDoorStateResponse // messages for each Door. foreach (string doorToken in doorsMessages.Keys) { DoorState state = GetDoorState(doorToken); string expectedState = stateValueSelector(state); XmlElement dataElement = doorsMessages[doorToken].Message.GetMessageData(); Dictionary <string, string> dataSimpleItems = dataElement.GetMessageElementSimpleItems(); string notificationState = dataSimpleItems[stateSimpleItemName]; Assert(expectedState == notificationState, string.Format("State is different ({0} in GetDoorStateResponse, {1} in Notification)", expectedState, notificationState), "Check that state is the same in Notification and in GetDoorStateResponse"); } }, () => { }); }
bool ValidateDoorEventSource(XmlElement messageElement, XmlNamespaceManager manager, object data, StringBuilder logger) { List <DoorInfo> doors = data as List <DoorInfo>; string token = data as string; EntityListInfo <DoorInfo> entityInfo = data as EntityListInfo <DoorInfo>; bool ok = true; XmlElement sourceElement = messageElement.GetMessageSource(); if (sourceElement == null) { logger.AppendLine(" Message Source element is missing"); ok = false; } else { bool success; string err; Dictionary <string, string> sourceSimpleItems = messageElement.GetMessageSourceSimpleItems(out success, out err); if (success) { if (sourceSimpleItems.ContainsKey(DOORTOKENSIMPLEITEM)) { string value = sourceSimpleItems[DOORTOKENSIMPLEITEM]; // check value StringBuilder error = new StringBuilder(); if (doors != null) { DoorInfo found = doors.Where(I => I.token == value).FirstOrDefault(); if (found == null) { ok = false; logger.Append(string.Format(" Door with token '{0}' not found", value)); } } else if (entityInfo != null) { DoorInfo found = entityInfo.FullList.Where(I => I.token == value).FirstOrDefault(); if (found == null) { ok = false; logger.Append(string.Format(" Door with token '{0}' not found", value)); } else { found = entityInfo.FilteredList.Where(I => I.token == value).FirstOrDefault(); if (found == null) { ok = false; logger.Append(string.Format(" Door with token '{0}' does not have required capabilities", value)); } } } else { if (value != token) { ok = false; logger.Append(string.Format(" Token is incorrect. Expected '{0}', actual '{1}'", token, value)); } } } else { logger.AppendLine(" 'DoorToken' SimpleItem is missing in Source"); ok = false; } } else { logger.AppendLine(" " + err); ok = false; } } return(ok); }
/// <summary> /// Receives and validates request message /// </summary> /// <param name="server">Notification listening server</param> /// <param name="timeout">Waiting timeout</param> /// <param name="accessRequestTopic">Topic for request message</param> /// <param name="validateRequestMessageFunction">Validation method for request message</param> /// <param name="fullAccessPointsList">Full list of access points</param> /// <param name="accessPointsList">Filtered list of access points</param> /// <param name="credentialsToken">[out parameter]CredentialToken, if such SimpleItem is present /// (if not present and this item is mandatory, validation will fail)</param> /// <param name="credentialsHolderName">[out parameter]CredentialHolderName, if /// such SimpleItem is present</param> /// <returns></returns> string GetAccessRequestMessage(Utils.NotifyServer server, int timeout, TopicInfo accessRequestTopic, ValidateMessageFunction validateRequestMessageFunction, List <AccessPointInfo> fullAccessPointsList, List <AccessPointInfo> accessPointsList, ref string credentialsToken, ref string credentialsHolderName) { credentialsToken = string.Empty; string accessPointToken = null; string message = string.Format("{0} event is expected!", accessRequestTopic.GetDescription()); Action eventInitiationAction = new Action(() => { StepPassed(); _operator.ShowMessage(message); }); // receive request event { BeginStep("Start listening"); Notify notify = null; try { notify = server.WaitForNotify(eventInitiationAction, timeout * 1000, _semaphore.StopEvent); } finally { _operator.HideMessage(); } ValidateNotificationsPacket(server.RawData); ValidateNotifyNotEmpty(notify); if (notify.NotificationMessage.Length > 1) { LogTestEvent("DUT sent more than one notification. Test will be performed for token from the first notification"); } NotificationMessageHolderType notification = notify.NotificationMessage[0]; BeginStep("Validate message"); XmlDocument doc = new XmlDocument(); string soapRawPacket = System.Text.Encoding.UTF8.GetString(server.RawData); doc.LoadXml(soapRawPacket); XmlNamespaceManager manager = CreateNamespaceManager(doc); Dictionary <NotificationMessageHolderType, XmlElement> rawElements = GetRawElements(notify.NotificationMessage, doc, manager, true); MessageCheckSettings settings = new MessageCheckSettings(); settings.NamespaceManager = manager; settings.ExpectedPropertyOperation = null; settings.ExpectedTopic = accessRequestTopic; settings.RawMessageElements = rawElements; EntityListInfo <AccessPointInfo> info = new EntityListInfo <AccessPointInfo>(); info.FilteredList = accessPointsList; info.FullList = fullAccessPointsList; settings.Data = info; StringBuilder logger = new StringBuilder(); bool ok = true; ok = validateRequestMessageFunction(notification, settings, logger); XmlElement messageElement = notification.Message; if (ok) { // if names are duplicated, OK will be false by this moment Dictionary <string, string> sourceSimpleItems = messageElement.GetMessageSourceSimpleItems(); accessPointToken = sourceSimpleItems[ACCESSPOINTTOKENSIMPLEITEM]; } if (!ok) { throw new AssertException(logger.ToStringTrimNewLine()); } StepPassed(); // simple items must be OK by that moment Dictionary <string, string> dataSimpleItems = messageElement.GetMessageDataSimpleItems(); if (dataSimpleItems.ContainsKey(CREDENTIALSTOKENSIMPLEITEM)) { credentialsToken = dataSimpleItems[CREDENTIALSTOKENSIMPLEITEM]; } if (dataSimpleItems.ContainsKey(CREDENTIALSHOLDERNAMESIMPLEITEM)) { credentialsHolderName = dataSimpleItems[CREDENTIALSHOLDERNAMESIMPLEITEM]; } } return(accessPointToken); }