Microsoft.Protocols.TestSuites.MS_OXCNOTIF.S01_ReceivePendingNotifications.MSOXCNOTIF_S01_TC06_VerifyAsyncRpcCall C# (CSharp) Method

MSOXCNOTIF_S01_TC06_VerifyAsyncRpcCall() private method

private MSOXCNOTIF_S01_TC06_VerifyAsyncRpcCall ( ) : void
return void
        public void MSOXCNOTIF_S01_TC06_VerifyAsyncRpcCall()
        {
            this.CheckWhetherSupportMAPIHTTP();
            this.NotificationInitialize();

            // Asynchronous RPC Notification can't be verified when use MAPIHTTP as transport.
            Site.Assume.IsTrue(Common.GetConfigurationPropertyValue("TransportSeq", this.Site).ToLower() != "mapi_http", "Asynchronous RPC Notification can't be verified when use MAPIHTTP as transport.");

            #region Subscribe NewMail event
            this.CNOTIFAdapter.RegisterNotification(NotificationType.NewMail);
            #endregion

            #region Call EcDoAsyncConnectEx to acquire an asynchronous context handle
            IntPtr acxh = this.CNOTIFAdapter.EcDoAsyncConnectEx();
            #endregion

            #region Verify that the server created an asynchronous context handle
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R298");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R298
            this.Site.CaptureRequirementIfAreNotEqual<IntPtr>(
                IntPtr.Zero,
                acxh,
                298,
                @"[In Receiving an EcDoAsyncConnectEx Method Call] When a call to the EcDoAsyncConnectEx RPC, as specified in [MS-OXCRPC] section 3.1.4.4, is received by the server, the server MUST create an asynchronous context handle.");

            if (Common.IsRequirementEnabled(297, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R297");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R297
                this.Site.CaptureRequirementIfAreNotEqual<IntPtr>(
                    IntPtr.Zero,
                    acxh,
                    297,
                    @"[In Appendix A: Product Behavior] Implementation does support the EcDoAsyncConnectEx method call, as specified in [MS-OXCRPC] section 3.1.4.4. ( Exchange 2007 and above follow this behavior).");
            }

            #endregion

            #region Call EcDoAsyncWaitEx with the valid ACXH
            IntPtr asyncHandle;
            this.CNOTIFAdapter.BeginAsyncWait(acxh, out asyncHandle);

            // Get the status of EcDoAsyncWaitEx call.
            // The event has not been triggered yet, so the call should not be completed.
            RPCAsyncStatus status = this.CNOTIFAdapter.QueryAsyncWaitStatus(asyncHandle);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R62");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R62
            // When the client can get a valid handle and the handle can be used in BeginAsyncWait successfully, this requirement can be verified.
            bool isVerifiedR62 = acxh != IntPtr.Zero && status != RPCAsyncStatus.RPC_S_INVALID_ASYNC_HANDLE;

            if (Common.IsRequirementEnabled(62, this.Site))
            {
                this.Site.CaptureRequirementIfIsTrue(
                    isVerifiedR62,
                    62,
                    @"[In Appendix A: Product Behavior] The EcDoAsyncConnectEx RPC method, as specified in [MS-OXCRPC] section 3.1.4.4, is used to acquire an asynchronous context handle on the implementation to use in subsequent EcDoAsyncWaitEx method calls, as specified in [MS-OXCRPC] section 3.3.4.1.  (Exchange 2007 and above follow this behavior.)");
            }

            // Trigger the event
            this.TriggerNewMailEvent();

            // Get the status of EcDoAsyncWaitEx call again.
            // The event has been triggered, so the call should be completed.
            RPCAsyncStatus status2;

            // The times to try getting a completed status.
            int retryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));
            int sleepTime = int.Parse(Common.GetConfigurationPropertyValue("SleepTime", this.Site));
            do
            {
                status2 = this.CNOTIFAdapter.QueryAsyncWaitStatus(asyncHandle);
                Thread.Sleep(sleepTime);
                retryCount--;
            }
            while (status2 != RPCAsyncStatus.RPC_S_OK && retryCount >= 0);
            Site.Assert.AreEqual<RPCAsyncStatus>(RPCAsyncStatus.RPC_S_OK, status2, "RPC status should be completed.");
            #endregion

            #region Verify that the server does not complete the call until there is a notification
            if (Common.IsRequirementEnabled(305, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R305");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R305
                bool isR305Satisfied = (status != RPCAsyncStatus.RPC_S_OK) && (status2 == RPCAsyncStatus.RPC_S_OK);

                this.Site.CaptureRequirementIfIsTrue(
                    isR305Satisfied,
                    305,
                    @"[In Appendix A: Product Behavior] Implementation does not complete the call [EcDoAsyncWaitEx Method Call] until there is a notification for the client session. (Exchange 2007 and above follow this behavior.)");
            }

            #endregion

            #region Complete the EcDoAsyncWaitEx call
            int isPending;
            this.CNOTIFAdapter.EndAsyncWait(asyncHandle, out isPending);
            #endregion

            #region Verify that the server returns the value NotificationPending in the output field pulFlagsOut.

            if (Common.IsRequirementEnabled(302, this.Site))
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R302");

                // The RPC method BeginAsyncWait and EndAsyncWait can run successfully without exception, so this requirement can be verified directly.
                Site.CaptureRequirement(
                302,
                @"[In Appendix A: Product Behavior] Implementation does support the EcDoAsyncWaitEx method call, as specified in [MS-OXCRPC] section 3.3.4.1. (Exchange 2007 and above follow this behavior).");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R310");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R310
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x00000001,
                isPending,
                310,
                @"[In Receiving an EcDoAsyncWaitEx Method Call] If the server completes the outstanding RPC call when there is a notification for the client session, the server MUST return the value NotificationPending in the pulFlagsOut field.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R68");

            if (Common.IsRequirementEnabled(68, this.Site))
            {
                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R68
                this.Site.CaptureRequirementIfAreEqual<int>(
                    0x00000001,
                    isPending,
                    68,
                    @"[In Appendix A: Product Behavior] The EcDoAsyncWaitEx asynchronous RPC method, as specified in [MS-OXCRPC] section 3.3.4.1, is used to inform a client about pending notifications on the implementation. ( Exchange 2007 and above follow this behavior)");
            }

            #endregion

            #region Get notification details.
            IList<IDeserializable> response = this.CNOTIFAdapter.GetNotification(true);
            RopNotifyResponse notifyResponse = (RopNotifyResponse)response.First(x => x is RopNotifyResponse);
            Site.Assert.AreEqual<NotificationType>(NotificationType.NewMail, notifyResponse.NotificationData.NotificationType, "New mail should be returned successfully.");

            bool isSupportRpcNotif = false;
            foreach (IDeserializable resp in response)
            {
                if (resp is RopNotifyResponse)
                {
                    isSupportRpcNotif = true;
                }
            }

            #region Verify that the EcDoAsyncConnectEx and EcDoAsyncConnectEx support asynchronous RPC notifications
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R63");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R63
            // EcDoAsyncConnectEx has been called before getting notification, so if the response contains RopNotifyResponse, this requirement can be verified.
            bool isVerifiedR63 = isSupportRpcNotif;

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR63,
                63,
                @"[In EcDoAsyncConnectEx Method] The EcDoAsyncConnectEx method is used to support asynchronous RPC notifications.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R69");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R69
            // EcDoAsyncWaitEx has been called before getting notification, so if the response contains RopNotifyResponse, this requirement can be verified.
            bool isVerifiedR69 = isSupportRpcNotif;

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR69,
                69,
                @"[In EcDoAsyncWaitEx Method] The EcDoAsyncWaitEx method is used to support asynchronous RPC notifications.");
            #endregion
            #endregion
        }