Beispiel #1
0
        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);
        }