/// <summary>
        /// Validates that both topics of interest are supported by the DUT. Validates that both topics are correct.
        /// </summary>
        /// <param name="accessRequestTopic">Topic for Request message</param>
        /// <param name="validateAccessRequestTopic">Validation method for Request message topic</param>
        /// <param name="resultTopic">Topic for resulting message</param>
        /// <param name="validateResultTopic">Validation method for Request message topic</param>
        void ValidateTopicsSupport(TopicInfo accessRequestTopic,
                                   Action <XmlElement, TopicInfo> validateAccessRequestTopic,
                                   TopicInfo resultTopic,
                                   Action <XmlElement, TopicInfo> validateResultTopic)
        {
            List <XmlElement> topics = GetAllTopics();

            {
                XmlElement requestTopicElement = GetTopicElement(topics, accessRequestTopic);

                Assert(requestTopicElement != null,
                       string.Format("Topic {0} not supported", accessRequestTopic.GetDescription()),
                       "Check that the event topic is supported");

                XmlElement messageDescription = requestTopicElement.GetMessageDescription();
                validateAccessRequestTopic(messageDescription, accessRequestTopic);
            }

            {
                XmlElement resultTopicElement = GetTopicElement(topics, resultTopic);

                Assert(resultTopicElement != null,
                       string.Format("Topic {0} not supported", resultTopic.GetDescription()),
                       "Check that the event topic is supported");

                XmlElement messageDescription = resultTopicElement.GetMessageDescription();
                validateResultTopic(messageDescription, resultTopic);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Common event test
        /// </summary>
        /// <param name="topicInfo">Topic to be tested</param>
        /// <param name="validateTopic">Method of topic validation</param>
        /// <param name="getDataForValidation">Method for getting additional data for message validation</param>
        /// <param name="validateMessageFunction">Method for message validation</param>
        void CommonEventTest(TopicInfo topicInfo,
                             Action <XmlElement, TopicInfo> validateTopic,
                             Func <object> getDataForValidation,
                             ValidateMessageFunction validateMessageFunction)
        {
            EndpointReferenceType subscriptionReference = null;

            System.DateTime subscribeStarted = System.DateTime.MaxValue;

            int timeout = 60;

            RunTest(
                () =>
            {
                // Get topic description from the DUT.
                XmlElement topicElement = GetTopicElement(topicInfo);

                Assert(topicElement != null,
                       string.Format("Topic {0} not supported", topicInfo.GetDescription()),
                       "Check that the event topic is supported");


                object data = getDataForValidation();

                // Validate topic
                XmlElement messageDescription = topicElement.GetMessageDescription();
                validateTopic(messageDescription, topicInfo);

                // Create filter for test

                FilterInfo filter = CreateFilter(topicInfo, messageDescription);

                // subscribe
                XmlDocument doc       = new XmlDocument();
                Notify notify         = null;
                subscriptionReference = ReceiveMessages(filter, timeout, doc, out notify, out subscribeStarted);

                if (notify != null)
                {
                    ValidateMessages(notify.NotificationMessage, doc, topicInfo, data, validateMessageFunction);
                }
            },
                () =>
            {
                if (subscribeStarted != System.DateTime.MaxValue)
                {
                    if (subscriptionReference != null && _subscriptionManagerClient == null)
                    {
                        CreateSubscriptionManagerClient(subscriptionReference);
                    }
                    TimeSpan diff   = System.DateTime.Now - subscribeStarted;
                    int releaseTime = timeout * 1000 - (int)diff.TotalMilliseconds;
                    ReleaseSubscriptionManager(releaseTime);
                }
            });
        }
Exemplo n.º 3
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);
            });
        }
Exemplo n.º 4
0
        void CommonDoorPropertyEventStateChangeTest(Func <DoorInfo, bool> doorCapabilitiesTest,
                                                    TopicInfo topicInfo,
                                                    ValidateMessageFunction validateMessageFunction)
        {
            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).
                List <DoorInfo> fullDoorInfosList = GetDoorInfoList();

                //4.	Check that there is at least one Door with Capabilities.[CAPABILITIES FOR THE TEST]= “true”.
                // Otherwise skip other steps and go to the next test.
                List <DoorInfo> doorsList = null;
                if (doorCapabilitiesTest != null)
                {
                    doorsList = fullDoorInfosList.Where(A => doorCapabilitiesTest(A)).ToList();

                    if (doorsList.Count == 0)
                    {
                        LogTestEvent("No Doors with required Capabilities found, exit the test" + Environment.NewLine);
                        return;
                    }
                }
                else
                {
                    doorsList = fullDoorInfosList;
                }

                //5.	ONVIF Client will select one random Door (token = Token1) with
                // Capabilities.DoorMonitor= “true”.
                // ToDo: may be change it to really random selection
                DoorInfo selectedDoor = doorsList[0];

                // filter for current test
                TestTool.Proxies.Event.FilterType filter = CreateSubscriptionFilter(topicInfo);

                //6.	ONVIF Client will invoke SubscribeRequest message with tns1:DoorControl/DoorPhysicalState 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.
                //8.	Test Operator will invoke change of DoorPhysicalState property for Door with token = Token1.
                //9.	Verify that DUT sends Notify message.
                string message =
                    string.Format("{0} event is expected \r\n for the Door with token={{0}}",
                                  topicInfo.GetDescription());

                DoorSelectionData data = new DoorSelectionData();
                data.SelectedToken     = selectedDoor.token;
                data.MessageTemplate   = message;
                data.Doors             = doorsList.Select(
                    D => new DoorSelectionData.DoorShortInfo()
                {
                    Token = D.token, Name = D.Name
                }).ToList();

                Dictionary <NotificationMessageHolderType, XmlElement> notifications = new Dictionary <NotificationMessageHolderType, XmlElement>();

                try
                {
                    subscriptionReference =
                        ReceiveMessages(filter,
                                        timeout,
                                        new Action(() =>
                    {
                        _operator.ShowDoorSelectionMessage(data);
                    }),
                                        1,
                                        (n) => CheckMessagePropertyOperation(n, OnvifMessage.CHANGED),
                                        notifications,
                                        out subscribeStarted);
                }
                finally
                {
                    _operator.HideDoorSelectionMessage();
                }
                Assert(notifications.Count > 0,
                       string.Format("Message with PropertyOperation='Changed' for the door with token='{0}' has not been received", data.SelectedToken),
                       "Check that the message for selected door has been received");


                //10.	Verify received Notify messages (correct value for UTC time, TopicExpression and
                // wsnt:Message).
                //11.	Verify that TopicExpression is equal to [TOPIC] for
                // received Notify message.
                //12.	Verify that notification contains Source.SimpleItem item with Name="DoorToken"
                // and Value= “Token1”.
                //13.	Verify that notification contains Data.SimpleItem item with Name=[ITEMNAME] and
                // Value with type is equal to [TYPE].

                BeginStep("Validate messages");

                XmlNamespaceManager manager = CreateNamespaceManager(notifications.First().Value.OwnerDocument);

                StringBuilder logger = new StringBuilder();
                bool ok = true;

                MessageCheckSettings settings = new MessageCheckSettings();
                settings.Data               = data.SelectedToken;
                settings.ExpectedTopic      = topicInfo;
                settings.RawMessageElements = notifications;
                settings.NamespaceManager   = manager;

                foreach (NotificationMessageHolderType m in notifications.Keys)
                {
                    bool local = validateMessageFunction(m, settings, logger);
                    ok         = ok && local;
                }
                if (!ok)
                {
                    throw new AssertException(logger.ToStringTrimNewLine());
                }

                StepPassed();
            },
                () =>
            {
                _operator.HideDoorSelectionMessage();
                ReleaseSubscription(subscribeStarted, subscriptionReference, timeout);
            });
        }
Exemplo n.º 5
0
        protected bool ValidateNotifications(Dictionary <Proxies.Event.NotificationMessageHolderType, XmlElement> messages, TopicInfo topic, string accessProfileToken, StringBuilder logger)
        {
            var filtered = messages.Where(pair => EventServiceExtensions.NotificationTopicMatch(pair.Key, pair.Value, topic)).Select(k => k.Key);

            if (!filtered.Any())
            {
                logger.AppendLine(string.Format("There is no notification with topic '{0}'", topic.GetDescription()));
                return(false);
            }

            foreach (var msg in filtered)
            {
                var source = msg.Message.GetMessageSourceSimpleItems();

                if (source.Any(s => s.Key == "AccessProfileToken" && s.Value == accessProfileToken))
                {
                    return(true);
                }
            }

            logger.AppendLine(string.Format("There is no notification containing 'Source/SimpleItem' element with Name = 'AccessProfileToken' and Value = '{0}'", accessProfileToken));
            return(false);
        }
Exemplo n.º 6
0
        bool messageFilterBase(Proxies.Event.NotificationMessageHolderType msg, TopicInfo topicInfo, string expectedPropertyOperation, string expectedAccessProfileToken, Func <StringBuilder, bool> action)
        {
            var invalidFlag = false;
            var log         = new StringBuilder();

            try
            {
                if (!EventServiceExtensions.NotificationTopicMatch(msg, topicInfo))
                {
                    log.AppendLine(string.Format("Received notification has unexpected topic '{0}' while the expected one should have with topic '{1}'",
                                                 EventServiceExtensions.GetTopicInfo(msg).GetDescription(), topicInfo.GetDescription()));
                    invalidFlag = true;
                }

                if (null != expectedPropertyOperation)
                {
                    if (!msg.Message.HasAttribute(OnvifMessage.PROPERTYOPERATIONTYPE))
                    {
                        log.AppendLine("Received notification has no 'PropertyOperation' field");
                        invalidFlag = true;
                    }
                    else
                    {
                        XmlAttribute propertyOperationType = msg.Message.Attributes[OnvifMessage.PROPERTYOPERATIONTYPE];
                        //Skip non-changed messages
                        if (propertyOperationType.Value != expectedPropertyOperation)
                        {
                            log.AppendLine(string.Format("Received notification has 'PropertyOperation' field with value = '{0}' but value = '{1}' is expected", propertyOperationType.Value, expectedPropertyOperation));
                            invalidFlag = true;
                        }
                    }
                }

                var source = msg.Message.GetMessageSourceSimpleItems();
                if (!source.ContainsKey("AccessProfileToken"))
                {
                    log.AppendLine("Received notification has no Source/SimpleItem with Name = 'AccessProfileToken'");
                    invalidFlag = true;
                }
                else
                {
                    var token = source["AccessProfileToken"];
                    if (token != expectedAccessProfileToken)
                    {
                        log.AppendLine(string.Format("Received notification has Source/SimpleItem with Name = 'AccessProfileToken' and Value = '{0}' but notification for AccessProfile item with token = '{1}' is expected", token, expectedAccessProfileToken));
                        invalidFlag = true;
                    }
                }

                if (null != action && action(log))
                {
                    invalidFlag = true;
                }

                return(true);
            }
            finally
            {
                Assert(!invalidFlag, log.ToStringTrimNewLine(), "Validation of received notification");
            }
        }
        void ConfigurationEventTest(
            TopicInfo topicInfo,
            Action <XmlElement, TopicInfo> validateTopic,
            ValidateConfigurationMessageFunction validateMessageFunction,
            string sourceTokenSimpleItem,
            Action <string> validateConfigurationFunction)
        {
            EndpointReferenceType subscriptionReference = null;

            System.DateTime subscribeStarted = System.DateTime.MaxValue;

            int timeout = 60;

            RunTest(
                () =>
            {
                // Get topic description from the DUT.
                XmlElement topicElement = GetTopicElement(topicInfo);

                BeginStep("Check if the event topic is supported");
                if (topicElement == null)
                {
                    LogStepEvent(string.Format("Topic {0} not supported", topicInfo.GetDescription()));
                }
                StepPassed();

                if (topicElement == null)
                {
                    return;
                }

                XmlElement messageDescription = topicElement.GetMessageDescription();
                validateTopic(messageDescription, topicInfo);

                // filter for current test
                TestTool.Proxies.Event.FilterType filter = CreateSubscriptionFilter(topicInfo);

                string message = string.Format("{0}  event is expected!", topicInfo.GetDescription());

                Notify notify   = null;
                XmlDocument doc = new XmlDocument();
                try
                {
                    subscriptionReference =
                        ReceiveMessages(filter,
                                        timeout,
                                        () => Operator.ShowMessage(message),
                                        doc,
                                        out notify,
                                        out subscribeStarted);
                }
                finally
                {
                    Operator.HideMessage();
                }

                Assert(notify.NotificationMessage.Length == 1,
                       string.Format("{0} messages received - unable to check actual configuration", notify.NotificationMessage.Length),
                       "Check that exactly one notification is received");

                BeginStep("Validate message");

                XmlNamespaceManager manager = CreateNamespaceManager(doc);
                Dictionary <NotificationMessageHolderType, XmlElement> notifications = GetRawElements(notify.NotificationMessage, doc, manager, true);

                StringBuilder logger = new StringBuilder();
                bool ok = true;

                MessageCheckSettings settings = new MessageCheckSettings();
                settings.ExpectedTopic        = topicInfo;
                settings.RawMessageElements   = notifications;
                settings.NamespaceManager     = manager;

                NotificationMessageHolderType m = notify.NotificationMessage[0];
                ok = validateMessageFunction(m, notifications[m], manager, logger);

                if (!ok)
                {
                    throw new AssertException(logger.ToStringTrimNewLine());
                }

                StepPassed();

                // validateMessageFunction should return false, if this simple item is missing
                string token = m.Message.GetMessageSourceSimpleItems()[sourceTokenSimpleItem];
                validateConfigurationFunction(token);
            },
                () =>
            {
                Operator.HideMessage();
                ReleaseSubscription(subscribeStarted, subscriptionReference, timeout);
            });
        }
        void ConfigurationEventTestBis(
            TopicInfo topicInfo,
            Action <XmlElement, TopicInfo> validateTopic,
            ValidateConfigurationMessageFunction validateMessageFunction,
            string sourceTokenSimpleItem,
            Action <string> validateConfigurationFunction)
        {
            int actualTerminationTime = 60;

            if (_eventSubscriptionTimeout != 0)
            {
                actualTerminationTime = _eventSubscriptionTimeout;
            }
            int timeout = _operationDelay / 1000;

            RunTest(
                () =>
            {
                // Get topic description from the DUT.
                XmlElement topicElement = GetTopicElement(topicInfo);

                Assert(null != topicElement,
                       string.Format("Topic {0} not supported", topicInfo.GetDescription()),
                       "Check if the event topic is supported");

                XmlElement messageDescription = topicElement.GetMessageDescription();
                validateTopic(messageDescription, topicInfo);

                // filter for current test
                TestTool.Proxies.Event.FilterType filter = CreateSubscriptionFilter(topicInfo);

                string message = string.Format("{0}  event is expected!", topicInfo.GetDescription());
                bool UseNotify = UseNotifyToGetEvents;

                Dictionary <NotificationMessageHolderType, XmlElement> notifications = null;
                SubscriptionHandler Handler = null;
                try
                {
                    Handler = new SubscriptionHandler(this, UseNotify, GetEventServiceAddress());
                    Handler.Subscribe(filter, actualTerminationTime);

                    Operator.ShowMessage(message);

                    var pullingCondition = new SubscriptionHandler.WaitFirstNotificationPollingCondition(timeout);
                    Handler.WaitMessages(1, pullingCondition, out notifications);
                }
                finally
                {
                    Operator.HideMessage();
                    SubscriptionHandler.Unsubscribe(Handler);
                }
                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");
                Assert(notifications.Count == 1,
                       string.Format("{0} messages received - unable to check actual configuration", notifications.Count),
                       "Check that exactly one notification is received");

                BeginStep("Validate message");

                XmlNamespaceManager manager = CreateNamespaceManager(notifications.First().Value.OwnerDocument);
                StringBuilder logger        = new StringBuilder();
                bool ok = true;

                MessageCheckSettings settings = new MessageCheckSettings();
                settings.ExpectedTopic        = topicInfo;
                settings.RawMessageElements   = notifications;
                settings.NamespaceManager     = manager;

                NotificationMessageHolderType m = notifications.Keys.First();
                ok = validateMessageFunction(m, notifications[m], manager, logger);

                if (!ok)
                {
                    throw new AssertException(logger.ToStringTrimNewLine());
                }

                StepPassed();

                // validateMessageFunction should return false, if this simple item is missing
                string token = m.Message.GetMessageSourceSimpleItems()[sourceTokenSimpleItem];
                validateConfigurationFunction(token);
            },
                () =>
            {
            });
        }
        void CommonDoorPropertyEventStateChangeTestBis(Func <DoorInfo, bool> doorCapabilitiesTest,
                                                       TopicInfo topicInfo,
                                                       ValidateMessageFunction validateMessageFunction)
        {
            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).
                List <DoorInfo> fullDoorInfosList = GetDoorInfoList();

                //4.	Check that there is at least one Door with Capabilities.[CAPABILITIES FOR THE TEST]= “true”.
                // Otherwise skip other steps and go to the next test.
                List <DoorInfo> doorsList = null;
                if (doorCapabilitiesTest != null)
                {
                    doorsList = fullDoorInfosList.Where(A => doorCapabilitiesTest(A)).ToList();
                }
                else
                {
                    doorsList = fullDoorInfosList;
                }

                Assert(doorsList.Any(),
                       "No Doors with required Capabilities found, exit the test.",
                       "Check there is appropriate door for test");

                //5.	ONVIF Client will select one random Door (token = Token1) with
                // Capabilities.DoorMonitor= “true”.
                // ToDo: may be change it to really random selection
                DoorInfo selectedDoor = doorsList[0];

                // filter for current test
                Proxies.Event.FilterType filter = CreateSubscriptionFilter(topicInfo);

                //6.	ONVIF Client will invoke SubscribeRequest message with tns1:DoorControl/DoorPhysicalState 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.
                //8.	Test Operator will invoke change of DoorPhysicalState property for Door with token = Token1.
                //9.	Verify that DUT sends Notify message.
                string message = string.Format("{0} event is expected \r\n for the Door with token={{0}}",
                                               topicInfo.GetDescription());

                DoorSelectionData data = new DoorSelectionData
                {
                    SelectedToken   = selectedDoor.token,
                    MessageTemplate = message,
                    Doors           = doorsList.Select(D => new DoorSelectionData.DoorShortInfo()
                    {
                        Token = D.token, Name = D.Name
                    }).ToList()
                };

                string Message = string.Format("{0} event is expected \r\n for the Door with token = '{1}'",
                                               topicInfo.GetDescription(), selectedDoor.token);

                bool UseNotify = UseNotifyToGetEvents;

                Dictionary <NotificationMessageHolderType, XmlElement> notifications = null;
                CurrentSubsciption = null;
                try
                {
                    CurrentSubsciption = new SubscriptionHandler(this, UseNotify, GetEventServiceAddress());
                    CurrentSubsciption.Subscribe(filter, actualTerminationTime);

                    Operator.ShowMessage(Message);
//                        Handler.WaitMessages(
//                            timeout,
//                            (n) => CheckMessagePropertyOperation(n, OnvifMessage.CHANGED),
//                            SubscriptionHandler.WaitCondition.WC_ALL,
//                            out notifications);
                    var pullingCondition = new SubscriptionHandler.WaitFirstNotificationPollingCondition(timeout)
                    {
                        Filter = msg => CheckMessagePropertyOperation(msg, OnvifMessage.CHANGED)
                    };
                    CurrentSubsciption.WaitMessages(1, pullingCondition, out notifications);
                }
                finally
                {
                    Operator.HideMessage();
                    UnsubscribeCurrentSubsciption();
                }

                Assert(null != notifications && notifications.Any(),
                       string.Format("Message with PropertyOperation='Changed' for the door with token='{0}' has not been received.{1}WARNING: may be Operation delay is too low",
                                     data.SelectedToken, Environment.NewLine),
                       "Check that the message for selected door has been received");


                //10.	Verify received Notify messages (correct value for UTC time, TopicExpression and
                // wsnt:Message).
                //11.	Verify that TopicExpression is equal to [TOPIC] for
                // received Notify message.
                //12.	Verify that notification contains Source.SimpleItem item with Name="DoorToken"
                // and Value= “Token1”.
                //13.	Verify that notification contains Data.SimpleItem item with Name=[ITEMNAME] and
                // Value with type is equal to [TYPE].

                BeginStep("Validate messages");

                XmlNamespaceManager manager = CreateNamespaceManager(notifications.First().Value.OwnerDocument);

                StringBuilder logger = new StringBuilder();
                bool ok = true;

                MessageCheckSettings settings = new MessageCheckSettings();
                settings.Data               = data.SelectedToken;
                settings.ExpectedTopic      = topicInfo;
                settings.RawMessageElements = notifications;
                settings.NamespaceManager   = manager;

                foreach (NotificationMessageHolderType m in notifications.Keys)
                {
                    bool local = validateMessageFunction(m, settings, logger);
                    ok         = ok && local;
                }
                if (!ok)
                {
                    throw new AssertException(logger.ToStringTrimNewLine());
                }

                StepPassed();
            },
                () =>
            {
                Operator.HideMessage();
                //Operator.HideDoorSelectionMessage();
            });
        }
        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");
                }
            },
                () =>
            {
            });
        }
        /// <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);
        }
        void ExternalAuthorizationTimeoutTest(
            Func <AccessPointInfo, bool> accessPointCapabilitiesTest,
            TopicInfo accessRequestTopic,
            Action <XmlElement, TopicInfo> validateAccessRequestTopic,
            ValidateMessageFunction validateRequestMessageFunction,
            TopicInfo resultTopic,
            Action <XmlElement, TopicInfo> validateResultTopic,
            ValidateMessageFunction validateResultMessageFunction)
        {
            EndpointReferenceType subscriptionReference = null;

            System.DateTime subscribeStarted = System.DateTime.MaxValue;

            int timeout = 60;

            RunTest(
                () =>
            {
                //3.	Get complete list of access points from the DUT (see Annex A.1).
                List <AccessPointInfo> fullAccessPointsList = GetAccessPointInfoList();

                //4.	Check that there is at least one Access Point with required Capabilities

                List <AccessPointInfo> accessPointsList = null;
                if (accessPointCapabilitiesTest != null)
                {
                    accessPointsList = fullAccessPointsList.Where(A => accessPointCapabilitiesTest(A)).ToList();

                    if (accessPointsList.Count == 0)
                    {
                        LogTestEvent("No AccessPoints with required Capabilities found, exit the test." + Environment.NewLine);
                        return;
                    }
                }
                else
                {
                    accessPointsList = fullAccessPointsList;
                }

                // Get topic description from the DUT and check topics support

                ValidateTopicsSupport(accessRequestTopic, validateAccessRequestTopic,
                                      resultTopic, validateResultTopic);

                // filter for current test
                TestTool.Proxies.Event.FilterType filter = CreateSubscriptionFilter(new TopicInfo[] { accessRequestTopic, resultTopic });

                // create notification listener and subscription
                Utils.NotifyServer server = new NotifyServer(_nic);
                SetupNotifyServer(server);
                string notificationsUri = server.GetNotificationUri();
                subscriptionReference   = CreateSubscription(filter, timeout, notificationsUri, out subscribeStarted);

                // get access request message
                string credentialsToken      = string.Empty;
                string credentialsHolderName = string.Empty;
                string accessPointToken      = GetAccessRequestMessage(server,
                                                                       timeout,
                                                                       accessRequestTopic,
                                                                       validateRequestMessageFunction,
                                                                       fullAccessPointsList,
                                                                       accessPointsList,
                                                                       ref credentialsToken,
                                                                       ref credentialsHolderName);
                RemoveHandlers(server);

                // receive events
                {
                    EnsureNotificationProducerClientCreated();

                    LogTestEvent(string.Format("Wait for {0} event{1}", resultTopic.GetDescription(), Environment.NewLine));

                    Utils.NotifyAsyncServer asyncServer = new NotifyAsyncServer(_nic);
                    SetupNotifyServer2(asyncServer);
                    asyncServer.StartCollecting(_semaphore.StopEvent);

                    AutoResetEvent received           = new AutoResetEvent(false);
                    asyncServer.NotificationReceived +=
                        new Action <byte[]>((data) => { received.Set(); });

                    Renew request           = new Renew();
                    request.TerminationTime = "PT60S";

                    // use 50 second instead of 60
                    int subscriptionGuaranteedTimeLeft = (int)(subscribeStarted.AddSeconds(50) - System.DateTime.Now).TotalMilliseconds;
                    if (subscriptionGuaranteedTimeLeft < 0)
                    {
                        subscriptionGuaranteedTimeLeft = 0;
                    }
                    System.DateTime exitTime = System.DateTime.Now.AddMilliseconds(_messageTimeout);

                    try
                    {
                        while (true)
                        {
                            // check if we are still waiting the message
                            int waitTimeLeft = (int)(exitTime - System.DateTime.Now).TotalMilliseconds;
                            if (waitTimeLeft <= 0)
                            {
                                break;
                            }

                            // compute time for next wait
                            int waitTime = Math.Min(subscriptionGuaranteedTimeLeft, waitTimeLeft);
                            int res      = WaitHandle.WaitAny(new WaitHandle[] { received, _semaphore.StopEvent }, waitTime);

                            if (res == WaitHandle.WaitTimeout)
                            {
                                // no notification received
                                if (System.DateTime.Now < exitTime)
                                {
                                    Renew(request);
                                    subscriptionGuaranteedTimeLeft = 50000;
                                    subscribeStarted = System.DateTime.Now;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else if (res == 1)
                            {
                                asyncServer.StopCollecting();
                                // Stop event received
                                throw new StopEventException();
                            }
                            else
                            {
                                // Notification received
                                break;
                            }
                        }
                    }
                    catch (Exception exc)
                    {
                        throw;
                    }
                    finally
                    {
                        asyncServer.StopCollecting();
                        RemoveHandlers2(asyncServer);
                    }

                    Dictionary <Notify, byte[]> messages = asyncServer.Get();

                    Assert(messages.Count > 0, "No notifications received", "Check if the DUT sent notifications");

                    Notify notify  = messages.Keys.First();
                    byte[] rawData = messages[notify];

                    ValidateNotificationsPacket(rawData);

                    ValidateNotifyNotEmpty(notify);

                    NotificationMessageHolderType theMessage = notify.NotificationMessage[0];

                    ValidateResultMessage(notify,
                                          theMessage,
                                          rawData,
                                          resultTopic,
                                          validateResultMessageFunction,
                                          accessPointToken,
                                          credentialsToken,
                                          credentialsHolderName);
                }
            },
                () =>
            {
                _operator.HideMessage();
                ReleaseSubscription(subscribeStarted, subscriptionReference, timeout);
            });
        }
        public void AccessPointEnabledEventTest()
        {
            EndpointReferenceType subscriptionReference = null;

            System.DateTime subscribeStarted = System.DateTime.MaxValue;

            int timeout = 60;

            RunTest(
                () =>
            {
                // Topic for current test
                // tns1:AccessPoint/State/Enabled
                TopicInfo topicInfo = ConstructTopic(new string[] { "AccessPoint", "State", "Enabled" });

                //3.	Get complete list of access points from the DUT (see Annex A.1).
                List <AccessPointInfo> fullAccessPointsList = GetAccessPointInfoList();

                List <AccessPointInfo> accessPoints =
                    fullAccessPointsList.Where(A => A.Capabilities != null && A.Capabilities.DisableAccessPoint).ToList();

                //4.	ONVIF Client will invoke GetEventPropertiesRequest message to retrieve all events supported by the DUT.
                //5.	Verify the GetEventPropertiesResponse message from the DUT.
                //6.	Check if there is an event with Topic tns1:AccessControl/AccessPoint/Enabled. If there is no event with such Topic skip other steps, fail the test and go to the next test.
                // Get topic description from the DUT.
                XmlElement topicElement = GetTopicElement(topicInfo);

                Assert(topicElement != null,
                       string.Format("Topic {0} not supported", topicInfo.GetDescription()),
                       "Check that the event topic is supported");

                //7.	Check that this event is a Property event (MessageDescription.IsProperty="true").
                //8.	Check that this event contains Source.SimpleItemDescription item with Name="AccessPointToken" and Type="pt:ReferenceToken".
                //9.	Check that this event contains Data.SimpleItemDescription item with Name="Enabled" and Type=" xs:boolean".
                //10.	Check that this event contains Data.SimpleItemDescription item with Name="Reason" and Type=" xs:string".

                XmlElement messageDescription = topicElement.GetMessageDescription();
                ValidateAccessPointEnabledTopic(messageDescription, topicInfo);

                FilterInfo filter = CreateFilter(topicInfo, messageDescription);

                //11.	ONVIF Client will invoke SubscribeRequest message with tns1:AccessControl/AccessPoint/Enabled 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)

                Dictionary <NotificationMessageHolderType, XmlElement> notifications = new Dictionary <NotificationMessageHolderType, XmlElement>();

                subscriptionReference =
                    ReceiveMessages(filter.Filter,
                                    timeout,
                                    new Action(() => { }),
                                    fullAccessPointsList.Count,
                                    notifications,
                                    out subscribeStarted);

                //14.	Verify received Notify messages  (correct value for UTC time, TopicExpression and wsnt:Message).
                //15.	Verify that TopicExpression is equal to tns1:AccessControl/AccessPoint/Enabled
                // for all received Notify messages.
                //16.	Verify that each notification contains Source.SimpleItem item with Name="AccessPointToken"
                // and Value is equal to one of existing Access Point Tokens (e.g. complete list of access points contains Access Point with the same token). Verify that there are Notification messages for each Access Point.
                //17.	Verify that each notification contains Data.SimpleItem item with Name="Enabled" and
                // Value with type is equal to xs:boolean.
                //18.	Verify that each notification which contains Data.SimpleItem item with Name="Reason" contains
                // Value with type is equal to xs:string.
                //19.	Verify that Notify PropertyOperation="Initialized".

                ValidateMessages(notifications, topicInfo, OnvifMessage.INITIALIZED, accessPoints, ValidateAccessPointEnabledMessage);

                Dictionary <string, NotificationMessageHolderType> accessPointsMessages = new Dictionary <string, NotificationMessageHolderType>();
                ValidateMessagesSet(notifications.Keys, accessPoints, accessPointsMessages);

                //20.	ONVIF Client will invoke GetAccessPointStateRequest message for each Access Point
                // with corresponding tokens.
                //21.	Verify the GetAccessPointStateResponse messages from the DUT. Verify that Data.SimpleItem
                // item with Name="Enabled" from Notification message has the same value with Enabled elements
                // from corresponding GetAccessPointStateResponse messages for each AccessPoint.

                foreach (string accessPointToken in accessPointsMessages.Keys)
                {
                    AccessPointState state = GetAccessPointState(accessPointToken);

                    string expectedState = state.Enabled.ToString().ToLower();

                    XmlElement messageElement = accessPointsMessages[accessPointToken].Message;

                    // Simple Items must be OK by that moment
                    Dictionary <string, string> dataSimpleItems = messageElement.GetMessageDataSimpleItems();

                    string notificationState = dataSimpleItems["State"];

                    Assert(expectedState == notificationState,
                           string.Format("State is different ({0} in GetAccessPointStateResponse, {1} in Notification)", expectedState, notificationState),
                           "Check that state is the same in Notification and in GetAccessPointStateResponse");
                }
            },
                () =>
            {
                ReleaseSubscription(subscribeStarted, subscriptionReference, timeout);
            });
        }
        public void AccessPointTamperingTest()
        {
            EndpointReferenceType subscriptionReference = null;

            System.DateTime subscribeStarted = System.DateTime.MaxValue;

            int timeout = 60;

            RunTest(
                () =>
            {
                //3.	Get complete list of access points from the DUT (see Annex A.1).
                List <AccessPointInfo> fullAccessPointsList = GetAccessPointInfoList();

                //4.	Check that there is at least one Access Point with Capabilities.Tamper = “true”.
                // Otherwise skip other steps and go to the next test.

                List <AccessPointInfo> accessPointsList =
                    fullAccessPointsList.Where(A => A.Capabilities != null && A.Capabilities.TamperSpecified && A.Capabilities.Tamper).ToList();

                if (accessPointsList.Count == 0)
                {
                    LogTestEvent("No AccessPoints with required Capabilities found, exit the test." + Environment.NewLine);
                    return;
                }

                // Topic for current test
                // tns1:AccessPoint/State/Tampering
                TopicInfo topicInfo = ConstructTopic(new string[] { "AccessPoint", "State", "Tampering" });

                //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 tns1:AccessControl/AccessPoint/Tampering. If there is no event with such Topic skip other steps, fail the test and go to the next test.
                XmlElement topicElement = GetTopicElement(topicInfo);

                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="AccessPointToken" and Type="pt:ReferenceToken".
                //10.	Check that this event contains Data.SimpleItemDescription item with Name="Active"
                // and Type=" xs:boolean".
                //11.	Check that this event contains Data.SimpleItemDescription item with Name="Reason"
                // and Type=" xs:string".

                XmlElement messageDescription = topicElement.GetMessageDescription();
                ValidateAccessPointTamperingTopic(messageDescription, topicInfo);

                //12.	ONVIF Client will invoke SubscribeRequest message with tns1:AccessControl/AccessPoint/Tampering Topic as Filter and an InitialTerminationTime of 60s to ensure that the SubscriptionManager is deleted after one minute.
                //13.	Verify that the DUT sends a SubscribeResponse message.
                //14.	Verify that DUT sends Notify message(s)

                FilterInfo filter = CreateFilter(topicInfo, messageDescription);

                Dictionary <NotificationMessageHolderType, XmlElement> notifications = new Dictionary <NotificationMessageHolderType, XmlElement>();

                subscriptionReference =
                    ReceiveMessages(filter.Filter,
                                    timeout,
                                    new Action(() => { }),
                                    fullAccessPointsList.Count,
                                    notifications,
                                    out subscribeStarted);

                //15.	Verify received Notify messages (correct value for UTC time, TopicExpression and
                // wsnt:Message).
                //16.	Verify that TopicExpression is equal to tns1:AccessControl/AccessPoint/Tampering
                // for all received Notify messages.
                //17.	Verify that each notification contains Source.SimpleItem item with Name="AccessPointToken"
                // and Value is equal to one of existing Access Point Tokens with Capabilities.Tamper = “true”
                // (e.g. complete list of access points contains Access Point with the same token). Verify that
                // there are Notification messages for each Access Point with Capabilities.Tamper = “true”.
                // Verify that there are no Notification messages for each Access Point with Capabilities.Tamper
                // = “false”.
                //18.	Verify that each notification contains Data.SimpleItem item with Name="Active" and Value
                // with type is equal to xs:boolean.
                //19.	Verify that each notification which contains Data.SimpleItem item with Name="Reason"
                // contains Value with type is equal to xs:boolean.
                //20.	Verify that Notify PropertyOperation="Initialized".

                ValidateMessages(notifications,
                                 topicInfo,
                                 OnvifMessage.INITIALIZED,
                                 accessPointsList,
                                 ValidateAccessPointTamperingMessage);

                // check that there is a notification for each access point
                Dictionary <string, NotificationMessageHolderType> accessPointsMessages = new Dictionary <string, NotificationMessageHolderType>();
                ValidateMessagesSet(notifications.Keys, accessPointsList, accessPointsMessages);
            },
                () =>
            {
                ReleaseSubscription(subscribeStarted, subscriptionReference, timeout);
            });
        }