Beispiel #1
0
        /// <summary>
        /// SWN client invoke WitnessrRegister to register for resource state change notifications of a NetName and IPAddress.
        /// </summary>
        /// <param name="Version">The version of the Witness protocol currently in use by the client.</param>
        /// <param name="NetName">Specifies a null-terminated string that specifies the name of the resource for which the client requires notifications.</param>
        /// <param name="IpAddr">Specifies a null-terminated string that specifies the IP address to which the client application connection is established.</param>
        /// <param name="ClientName">Specifies a null-terminated string that is used to identify the Witness client.</param>
        /// <param name="pContext">A context handle to identifies the client on the server. </param>
        /// <returns>Return zero if success, otherwise return nonzero.</returns>
        public int WitnessrRegister(SwnVersion Version, string NetName, string IpAddr, string ClientName, out IntPtr pContext)
        {
            Int3264[] paramList;
            int       retVal = 0;

            SafeIntPtr pNetName    = Marshal.StringToHGlobalUni(NetName);
            SafeIntPtr pIpAddr     = Marshal.StringToHGlobalUni(IpAddr);
            SafeIntPtr pClientName = Marshal.StringToHGlobalUni(ClientName);

            paramList = new Int3264[] {
                IntPtr.Zero,//out param
                (uint)Version,
                pNetName,
                pIpAddr,
                pClientName,
                IntPtr.Zero //return value
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)SWN_OPNUM.WitnessrRegister))
                {
                    pContext = Marshal.ReadIntPtr(outParamList[0]);
                    retVal   = outParamList[paramList.Length - 1].ToInt32();
                }
            }
            finally
            {
                pNetName.Dispose();
                pIpAddr.Dispose();
                pClientName.Dispose();
            }

            return(retVal);
        }
Beispiel #2
0
 /// <summary>
 /// Check SWN version
 /// </summary>
 /// <param name="expectedVersion">The expected SWN Version.</param>
 /// <param name="actualVersion">The actual SWN Version.</param>
 public static void CheckVersion(SwnVersion expectedVersion, SwnVersion actualVersion)
 {
     if ((uint)actualVersion < (uint)expectedVersion)
     {
         // If server's actual SWN version is less than the expected version to run this test case, set it as inconclusive.
         BaseTestSite.Assert.Inconclusive("Test case is not applicable to servers that support SWN Version 0x{0:x8}.", (uint)actualVersion);
     }
 }
 /// <summary>
 /// Check SWN version
 /// </summary>
 /// <param name="expectedVersion">The expected SWN Version.</param>
 /// <param name="actualVersion">The actual SWN Version.</param>
 public static void CheckVersion(SwnVersion expectedVersion, SwnVersion actualVersion)
 {
     if ((uint)actualVersion < (uint)expectedVersion)
     {
         // If server's actual SWN version is less than the expected version to run this test case, set it as inconclusive.
         BaseTestSite.Assert.Inconclusive("Test case is not applicable to servers that support SWN Version 0x{0:x8}.", (uint)actualVersion);
     }
 }
        private void SWNRegister(SwnRegisterType registerType, SwnVersion expectedVersion)
        {
            WITNESS_INTERFACE_INFO registerInterface;
            IntPtr pDuplicateContext = IntPtr.Zero;
            swnClientForInterface = new SwnClient();
            swnClientForWitness = new SwnClient();
            string server = TestConfig.ClusteredFileServerName;

            IPAddress currentAccessIpAddr = SWNTestUtility.GetCurrentAccessIP(server);

            #region Get SWN witness interface list
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Get SWN witness interface list.");

            DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIpAddr,
                TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, server), TestConfig.FailoverTimeout,
                "Retry BindServer until succeed within timeout span");

            int ret;
            WITNESS_INTERFACE_LIST interfaceList = new WITNESS_INTERFACE_LIST();

            DoUntilSucceed(() =>
            {
                ret = swnClientForInterface.WitnessrGetInterfaceList(out interfaceList);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrGetInterfaceList returns with result code = 0x{0:x8}", ret);
                return SWNTestUtility.VerifyInterfaceList(interfaceList, TestConfig.Platform);
            }, TestConfig.FailoverTimeout, "Retry to call WitnessrGetInterfaceList until succeed within timeout span");

            swnClientForInterface.SwnUnbind(TestConfig.Timeout);
            swnClientForInterface = null;

            SWNTestUtility.GetRegisterInterface(interfaceList, out registerInterface);

            SWNTestUtility.CheckVersion(expectedVersion, (SwnVersion)registerInterface.Version);
            #endregion

            #region Register SWN witness
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register SWN witness with {0}.", registerType.ToString());

            DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForWitness,
                (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6),
                TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout), TestConfig.FailoverTimeout,
                "Retry BindServer until succeed within timeout span");

            SwnVersion registerVersion;
            if (SwnVersion.SWN_VERSION_2 == expectedVersion)
                registerVersion = (registerType == SwnRegisterType.InvalidVersion ? SwnVersion.SWN_VERSION_1 : SwnVersion.SWN_VERSION_2);
            else
                registerVersion = (registerType == SwnRegisterType.InvalidVersion ? SwnVersion.SWN_VERSION_2 : SwnVersion.SWN_VERSION_1);
            string registerNetName =
                (registerType == SwnRegisterType.InvalidNetName ? "XXXXInvalid.contoso.comXXXX" : SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server));
            string accessIpAddr =
                (registerType == SwnRegisterType.InvalidIpAddress ? "255.255.255.255" : currentAccessIpAddr.ToString());
            string registerClientName = Guid.NewGuid().ToString();
            string shareName =
                (registerType == SwnRegisterType.InvalidShareName ? "XXXXInvalidShareNameXXXX" : TestConfig.ClusteredFileShare);
            uint keepAliveTimout =
                (registerType == SwnRegisterType.KeepAliveTimeout ? (uint)10 : (uint)120);

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Register witness:");
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tVersion: {0:x8}", (uint)registerVersion);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tNetName: {0}", registerNetName);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tShareName: {0}", shareName);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIpAddress: {0}", accessIpAddr);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tClientName: {0}", registerClientName);
            if (SwnVersion.SWN_VERSION_2 == expectedVersion)
            {
                ret = swnClientForWitness.WitnessrRegisterEx(registerVersion,
                    registerNetName,
                    shareName,
                    accessIpAddr,
                    registerClientName,
                    WitnessrRegisterExFlagsValue.WITNESS_REGISTER_NONE,
                    keepAliveTimout,
                    out pContext);
            }
            else
            {
                ret = swnClientForWitness.WitnessrRegister(registerVersion,
                    registerNetName,
                    accessIpAddr,
                    registerClientName,
                    out pContext);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify server response for WitnessrRegister request.");

            // TDI to be filed, original fix for TDI 66777 and 69401 is not accurate, need clarify in new TDI
            // Windows server won't fail the request if the target resource being monitored is ScaleOut FS share when request containst invalid IP address or invalid share name
            // TODO: Test case should have ability to choose different server, otherwise we do not need such condition
            bool isScaleOutFsShare = ShareContainsSofs(server, Smb2Utility.GetUncPath(server, TestConfig.ClusteredFileShare));

            if (registerType == SwnRegisterType.InvalidNetName)
            {
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_INVALID_PARAMETER, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }
            else if (registerType == SwnRegisterType.InvalidVersion)
            {
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_REVISION_MISMATCH, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }
            else if (registerType == SwnRegisterType.InvalidIpAddress)
            {
                if (!isScaleOutFsShare)
                {
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
                else
                {
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_INVALID_STATE, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
            }
            else if (registerType == SwnRegisterType.InvalidShareName)
            {
                if (!isScaleOutFsShare)
                {
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
                else
                {
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_INVALID_STATE, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
            }
            else
            {
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }

            if (registerType == SwnRegisterType.InvalidUnRegister)
            {
                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);

                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                if (TestConfig.Platform == Platform.WindowsServer2012)
                {
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_NOT_FOUND, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);
                }
                else
                {
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_INVALID_PARAMETER, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);
                }
                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            }

            if (registerType == SwnRegisterType.InvalidRequest)
            {
                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);

                uint callId;
                callId = swnClientForWitness.WitnessrAsyncNotify(pContext);
                BaseTestSite.Assert.AreNotEqual<uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId);

                RESP_ASYNC_NOTIFY respNotify;
                ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_NOT_FOUND, (SwnErrorCode)ret, "ExpectWitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);

                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            }

            if (registerType == SwnRegisterType.KeepAliveTimeout)
            {
                uint callId;
                callId = swnClientForWitness.WitnessrAsyncNotify(pContext);
                BaseTestSite.Assert.AreNotEqual<uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId);

                RESP_ASYNC_NOTIFY respNotify;
                ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_TIMEOUT, (SwnErrorCode)ret, "ExpectWitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);

                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            }
            #endregion

            #region Cleanup
            pContext = IntPtr.Zero;
            swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            swnClientForWitness = null;
            #endregion
        }
        /// <summary>
        /// Test CLIENT_MOVE_NOTIFICATION.
        /// </summary>
        /// <param name="expectedVersion">SwnVersion.SWN_VERSION_2 indicates that register with WitnessrRegisterEx, SwnVersion.SWN_VERSION_1 indicates that register with WitnessrRegister.</param>
        private void SWNAsyncNotification_ClientMove(SwnVersion expectedVersion)
        {
            int  ret    = 0;
            uint callId = 0;
            WITNESS_INTERFACE_INFO registerInterface;
            string server = TestConfig.ClusteredScaleOutFileServerName;

            #region Get the file server to access it through SMB2

            IPAddress currentAccessIp = SWNTestUtility.GetCurrentAccessIP(server);
            BaseTestSite.Assert.AreNotEqual(null, currentAccessIp, "IP address of the file server should NOT be empty");
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Got the IP {0} to access the file server", currentAccessIp.ToString());

            #endregion

            #region Get register interface

            DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIp,
                                                           TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                                                           TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, server), TestConfig.FailoverTimeout,
                           "Retry BindServer until succeed within timeout span");

            WITNESS_INTERFACE_LIST interfaceList = new WITNESS_INTERFACE_LIST();

            DoUntilSucceed(() =>
            {
                ret = swnClientForInterface.WitnessrGetInterfaceList(out interfaceList);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrGetInterfaceList returns with result code = 0x{0:x8}", ret);
                return(SWNTestUtility.VerifyInterfaceList(interfaceList, TestConfig.Platform));
            }, TestConfig.FailoverTimeout, "Retry to call WitnessrGetInterfaceList until succeed within timeout span");

            swnClientForInterface.SwnUnbind(TestConfig.Timeout);

            SWNTestUtility.GetRegisterInterface(interfaceList, out registerInterface);

            SWNTestUtility.CheckVersion(expectedVersion, (SwnVersion)registerInterface.Version);
            #endregion

            #region Register SWN witness

            DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForWitness,
                                                           (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6),
                                                           TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                                                           TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, server), TestConfig.FailoverTimeout,
                           "Retry BindServer until succeed within timeout span");

            string clientName = Guid.NewGuid().ToString();
            string netName    = SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server);

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Register witness:");
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tNetName: {0}", netName);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddress: {0}", currentAccessIp.ToString());
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tClient Name: {0}", clientName);

            if (SwnVersion.SWN_VERSION_2 == expectedVersion)
            {
                ret = swnClientForWitness.WitnessrRegisterEx(SwnVersion.SWN_VERSION_2,
                                                             netName,
                                                             null,
                                                             currentAccessIp.ToString(),
                                                             clientName,
                                                             WitnessrRegisterExFlagsValue.WITNESS_REGISTER_IP_NOTIFICATION,
                                                             120,
                                                             out pContext);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegisterEx returns with result code = 0x{0:x8}", ret);
            }
            else
            {
                ret = swnClientForWitness.WitnessrRegister(SwnVersion.SWN_VERSION_1,
                                                           netName,
                                                           currentAccessIp.ToString(),
                                                           clientName,
                                                           out pContext);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }
            BaseTestSite.Assert.IsNotNull(pContext, "Expect pContext is not null.");

            callId = swnClientForWitness.WitnessrAsyncNotify(pContext);
            BaseTestSite.Assert.AreNotEqual <uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId);

            #endregion

            #region Create a file and write content

            string         uncSharePath  = Smb2Utility.GetUncPath(server, TestConfig.ClusteredFileShare);
            string         content       = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);
            string         testDirectory = CreateTestDirectory(uncSharePath);
            string         file          = Path.Combine(testDirectory, Guid.NewGuid().ToString());
            Guid           clientGuid    = Guid.NewGuid();
            Guid           createGuid    = Guid.NewGuid();
            FileServerType fsType        = FileServerType.ScaleOutFileServer;

            DoUntilSucceed(() => WriteContentBeforeFailover(fsType, server, currentAccessIp, uncSharePath, file, content, clientGuid, createGuid),
                           TestConfig.FailoverTimeout,
                           "Before failover, retry Write content until succeed within timeout span.");

            #endregion

            #region Move resource node

            // Move resource node to trigger CLIENT_MOVE_NOTIFICATION
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Move resource to interface {0} to trigger CLIENT_MOVE_NOTIFICATION", registerInterface.InterfaceGroupName);
            sutController.MoveSmbWitnessClient(clientName,
                                               SWNTestUtility.GetPrincipleName(TestConfig.DomainName, registerInterface.InterfaceGroupName));

            #endregion

            #region Wait CLIENT_MOVE_NOTIFICATION

            RESP_ASYNC_NOTIFY respNotify;
            // Wait the CLIENT_MOVE_NOTIFICATION
            ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
            BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);
            SWNTestUtility.PrintNotification(respNotify);

            // Verify RESP_ASYNC_NOTIFY
            SWNTestUtility.VerifyClientMoveShareMoveAndIpChange(respNotify, SwnMessageType.CLIENT_MOVE_NOTIFICATION, (uint)SwnIPAddrInfoFlags.IPADDR_V4, TestConfig.Platform);
            #endregion

            #region Get the new IpAddr
            IPADDR_INFO_LIST ipAddrInfoList;
            SwnUtility.ParseIPAddrInfoList(respNotify, out ipAddrInfoList);
            currentAccessIp = (ipAddrInfoList.IPAddrList[0].Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(ipAddrInfoList.IPAddrList[0].IPV4) : SWNTestUtility.ConvertIPV6(ipAddrInfoList.IPAddrList[0].IPV6);
            #endregion

            #region Unregister SWN Witness

            ret = swnClientForWitness.WitnessrUnRegister(pContext);
            BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);
            pContext = IntPtr.Zero;
            swnClientForWitness.SwnUnbind(TestConfig.Timeout);

            #endregion

            #region Make sure Cluster Share is available
            DoUntilSucceed(() => sutProtocolController.CheckIfShareIsAvailable(uncSharePath),
                           testConfig.Timeout,
                           "Make sure cluster share is available.");
            #endregion

            #region Read content and close the file
            DoUntilSucceed(() => ReadContentAfterFailover(server, currentAccessIp, uncSharePath, file, content, clientGuid, createGuid),
                           TestConfig.FailoverTimeout,
                           "Retry Read content until succeed within timeout span.");
            #endregion
        }
Beispiel #6
0
        private void SWNRegister(SwnRegisterType registerType, SwnVersion expectedVersion)
        {
            WITNESS_INTERFACE_INFO registerInterface;
            IntPtr pDuplicateContext = IntPtr.Zero;

            swnClientForInterface = new SwnClient();
            swnClientForWitness   = new SwnClient();
            string server = TestConfig.ClusteredFileServerName;

            IPAddress currentAccessIpAddr = SWNTestUtility.GetCurrentAccessIP(server);

            #region Get SWN witness interface list
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Get SWN witness interface list.");

            DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIpAddr,
                                                           TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                                                           TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, server), TestConfig.FailoverTimeout,
                           "Retry BindServer until succeed within timeout span");

            int ret;
            WITNESS_INTERFACE_LIST interfaceList = new WITNESS_INTERFACE_LIST();

            DoUntilSucceed(() =>
            {
                ret = swnClientForInterface.WitnessrGetInterfaceList(out interfaceList);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrGetInterfaceList returns with result code = 0x{0:x8}", ret);
                return(SWNTestUtility.VerifyInterfaceList(interfaceList, TestConfig.Platform));
            }, TestConfig.FailoverTimeout, "Retry to call WitnessrGetInterfaceList until succeed within timeout span");

            swnClientForInterface.SwnUnbind(TestConfig.Timeout);
            swnClientForInterface = null;

            SWNTestUtility.GetRegisterInterface(interfaceList, out registerInterface);

            SWNTestUtility.CheckVersion(expectedVersion, (SwnVersion)registerInterface.Version);
            #endregion

            #region Register SWN witness
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register SWN witness with {0}.", registerType.ToString());

            DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForWitness,
                                                           (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6),
                                                           TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                                                           TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout), TestConfig.FailoverTimeout,
                           "Retry BindServer until succeed within timeout span");

            SwnVersion registerVersion;
            if (SwnVersion.SWN_VERSION_2 == expectedVersion)
            {
                registerVersion = (registerType == SwnRegisterType.InvalidVersion ? SwnVersion.SWN_VERSION_1 : SwnVersion.SWN_VERSION_2);
            }
            else
            {
                registerVersion = (registerType == SwnRegisterType.InvalidVersion ? SwnVersion.SWN_VERSION_2 : SwnVersion.SWN_VERSION_1);
            }
            string registerNetName =
                (registerType == SwnRegisterType.InvalidNetName ? "XXXXInvalid.contoso.comXXXX" : SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server));
            string accessIpAddr =
                (registerType == SwnRegisterType.InvalidIpAddress ? "255.255.255.255" : currentAccessIpAddr.ToString());
            string registerClientName = Guid.NewGuid().ToString();
            string shareName          =
                (registerType == SwnRegisterType.InvalidShareName ? "XXXXInvalidShareNameXXXX" : TestConfig.ClusteredFileShare);
            uint keepAliveTimout =
                (registerType == SwnRegisterType.KeepAliveTimeout ? (uint)10 : (uint)120);

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Register witness:");
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tVersion: {0:x8}", (uint)registerVersion);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tNetName: {0}", registerNetName);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tShareName: {0}", shareName);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIpAddress: {0}", accessIpAddr);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tClientName: {0}", registerClientName);
            if (SwnVersion.SWN_VERSION_2 == expectedVersion)
            {
                ret = swnClientForWitness.WitnessrRegisterEx(registerVersion,
                                                             registerNetName,
                                                             shareName,
                                                             accessIpAddr,
                                                             registerClientName,
                                                             WitnessrRegisterExFlagsValue.WITNESS_REGISTER_NONE,
                                                             keepAliveTimout,
                                                             out pContext);
            }
            else
            {
                ret = swnClientForWitness.WitnessrRegister(registerVersion,
                                                           registerNetName,
                                                           accessIpAddr,
                                                           registerClientName,
                                                           out pContext);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify server response for WitnessrRegister request.");

            // TDI to be filed, original fix for TDI 66777 and 69401 is not accurate, need clarify in new TDI
            // Windows server won't fail the request if the target resource being monitored is ScaleOut FS share when request containst invalid IP address or invalid share name
            // TODO: Test case should have ability to choose different server, otherwise we do not need such condition
            bool isScaleOutFsShare = ShareContainsSofs(server, Smb2Utility.GetUncPath(server, TestConfig.ClusteredFileShare));

            if (registerType == SwnRegisterType.InvalidNetName)
            {
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_INVALID_PARAMETER, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }
            else if (registerType == SwnRegisterType.InvalidVersion)
            {
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_REVISION_MISMATCH, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }
            else if (registerType == SwnRegisterType.InvalidIpAddress)
            {
                if (!isScaleOutFsShare)
                {
                    BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
                else
                {
                    BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_INVALID_STATE, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
            }
            else if (registerType == SwnRegisterType.InvalidShareName)
            {
                if (!isScaleOutFsShare)
                {
                    BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
                else
                {
                    BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_INVALID_STATE, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
            }
            else
            {
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }

            if (registerType == SwnRegisterType.InvalidUnRegister)
            {
                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);

                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                if (TestConfig.Platform == Platform.WindowsServer2012)
                {
                    BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_NOT_FOUND, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);
                }
                else
                {
                    BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_INVALID_PARAMETER, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);
                }
                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            }

            if (registerType == SwnRegisterType.InvalidRequest)
            {
                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);

                uint callId;
                callId = swnClientForWitness.WitnessrAsyncNotify(pContext);
                BaseTestSite.Assert.AreNotEqual <uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId);

                RESP_ASYNC_NOTIFY respNotify;
                ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_NOT_FOUND, (SwnErrorCode)ret, "ExpectWitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);

                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            }

            if (registerType == SwnRegisterType.KeepAliveTimeout)
            {
                uint callId;
                callId = swnClientForWitness.WitnessrAsyncNotify(pContext);
                BaseTestSite.Assert.AreNotEqual <uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId);

                RESP_ASYNC_NOTIFY respNotify;
                ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_TIMEOUT, (SwnErrorCode)ret, "ExpectWitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);

                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            }
            #endregion

            #region Cleanup
            pContext = IntPtr.Zero;
            swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            swnClientForWitness = null;
            #endregion
        }
        /// <summary>
        /// Test CLIENT_MOVE_NOTIFICATION.
        /// </summary>
        /// <param name="expectedVersion">SwnVersion.SWN_VERSION_2 indicates that register with WitnessrRegisterEx, SwnVersion.SWN_VERSION_1 indicates that register with WitnessrRegister.</param>
        private void SWNAsyncNotification_ClientMove(SwnVersion expectedVersion)
        {
            int ret = 0;
            uint callId = 0;
            WITNESS_INTERFACE_INFO registerInterface;
            string server = TestConfig.ClusteredScaleOutFileServerName;

            #region Get the file server to access it through SMB2

            IPAddress currentAccessIp = SWNTestUtility.GetCurrentAccessIP(server);
            BaseTestSite.Assert.AreNotEqual(null, currentAccessIp, "IP address of the file server should NOT be empty");
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Got the IP {0} to access the file server", currentAccessIp.ToString());

            #endregion

            #region Get register interface

            DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIp,
                TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, server), TestConfig.FailoverTimeout,
                "Retry BindServer until succeed within timeout span");

            WITNESS_INTERFACE_LIST interfaceList = new WITNESS_INTERFACE_LIST();

            DoUntilSucceed(() =>
            {
                ret = swnClientForInterface.WitnessrGetInterfaceList(out interfaceList);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrGetInterfaceList returns with result code = 0x{0:x8}", ret);
                return SWNTestUtility.VerifyInterfaceList(interfaceList, TestConfig.Platform);
            }, TestConfig.FailoverTimeout, "Retry to call WitnessrGetInterfaceList until succeed within timeout span");

            swnClientForInterface.SwnUnbind(TestConfig.Timeout);

            SWNTestUtility.GetRegisterInterface(interfaceList, out registerInterface);

            SWNTestUtility.CheckVersion(expectedVersion, (SwnVersion)registerInterface.Version);
            #endregion

            #region Register SWN witness

            DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForWitness,
                (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6),
                TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, server), TestConfig.FailoverTimeout,
                "Retry BindServer until succeed within timeout span");

            string clientName = Guid.NewGuid().ToString();
            string netName = SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server);

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Register witness:");
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tNetName: {0}", netName);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddress: {0}", currentAccessIp.ToString());
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tClient Name: {0}", clientName);

            if (SwnVersion.SWN_VERSION_2 == expectedVersion)
            {
                ret = swnClientForWitness.WitnessrRegisterEx(SwnVersion.SWN_VERSION_2,
                    netName,
                    null,
                    currentAccessIp.ToString(),
                    clientName,
                    WitnessrRegisterExFlagsValue.WITNESS_REGISTER_IP_NOTIFICATION,
                    120,
                    out pContext);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegisterEx returns with result code = 0x{0:x8}", ret);
            }
            else
            {
                ret = swnClientForWitness.WitnessrRegister(SwnVersion.SWN_VERSION_1,
                netName,
                currentAccessIp.ToString(),
                clientName,
                out pContext);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }
            BaseTestSite.Assert.IsNotNull(pContext, "Expect pContext is not null.");

            callId = swnClientForWitness.WitnessrAsyncNotify(pContext);
            BaseTestSite.Assert.AreNotEqual<uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId);

            #endregion

            #region Create a file and write content

            string uncSharePath = Smb2Utility.GetUncPath(server, TestConfig.ClusteredFileShare);
            string content = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);
            string testDirectory = CreateTestDirectory(uncSharePath);
            string file = Path.Combine(testDirectory, Guid.NewGuid().ToString());
            Guid clientGuid = Guid.NewGuid();
            Guid createGuid = Guid.NewGuid();
            FileServerType fsType = FileServerType.ScaleOutFileServer;

            DoUntilSucceed(() => WriteContentBeforeFailover(fsType, server, currentAccessIp, uncSharePath, file, content, clientGuid, createGuid),
                    TestConfig.FailoverTimeout,
                    "Before failover, retry Write content until succeed within timeout span.");

            #endregion

            #region Move resource node

            // Move resource node to trigger CLIENT_MOVE_NOTIFICATION
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Move resource to interface {0} to trigger CLIENT_MOVE_NOTIFICATION", registerInterface.InterfaceGroupName);
            sutController.MoveSmbWitnessClient(clientName,
                SWNTestUtility.GetPrincipleName(TestConfig.DomainName, registerInterface.InterfaceGroupName));

            #endregion

            #region Wait CLIENT_MOVE_NOTIFICATION

            RESP_ASYNC_NOTIFY respNotify;
            // Wait the CLIENT_MOVE_NOTIFICATION
            ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
            BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);
            SWNTestUtility.PrintNotification(respNotify);

            // Verify RESP_ASYNC_NOTIFY
            SWNTestUtility.VerifyClientMoveShareMoveAndIpChange(respNotify, SwnMessageType.CLIENT_MOVE_NOTIFICATION, (uint)SwnIPAddrInfoFlags.IPADDR_V4, TestConfig.Platform);
            #endregion

            #region Get the new IpAddr
            IPADDR_INFO_LIST ipAddrInfoList;
            SwnUtility.ParseIPAddrInfoList(respNotify, out ipAddrInfoList);
            currentAccessIp = (ipAddrInfoList.IPAddrList[0].Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(ipAddrInfoList.IPAddrList[0].IPV4) : SWNTestUtility.ConvertIPV6(ipAddrInfoList.IPAddrList[0].IPV6);
            #endregion

            #region Unregister SWN Witness

            ret = swnClientForWitness.WitnessrUnRegister(pContext);
            BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);
            pContext = IntPtr.Zero;
            swnClientForWitness.SwnUnbind(TestConfig.Timeout);

            #endregion

            #region Make sure Cluster Share is available
            DoUntilSucceed(() => sutProtocolController.CheckIfShareIsAvailable(uncSharePath),
                testConfig.Timeout,
                "Make sure cluster share is available.");
            #endregion

            #region Read content and close the file
            DoUntilSucceed(() => ReadContentAfterFailover(server, currentAccessIp, uncSharePath, file, content, clientGuid, createGuid),
                    TestConfig.FailoverTimeout,
                    "Retry Read content until succeed within timeout span.");
            #endregion
        }
        /// <summary>
        /// SWN client invoke WitnessrRegisterEx to register for resource state change notifications of a NetName and IPAddress.
        /// </summary>
        /// <param name="Version">The version of the Witness protocol currently in use by the client.</param>
        /// <param name="NetName">Specifies a null-terminated string that specifies the name of the resource for which the client requires notifications.</param>
        /// <param name="ShareName">Specifies a null-terminated string that specifies the name of the share resource for which the client requires notifications.</param>
        /// <param name="IpAddr">Specifies a null-terminated string that specifies the IP address to which the client application connection is established.</param>
        /// <param name="ClientName">Specifies a null-terminated string that is used to identify the Witness client.</param>
        /// <param name="Flags">Specifies the type of Witness registration.</param>
        /// <param name="KeepAliveTimout">Specifies the maximum number of milliseconds for any notification response from the server.</param>
        /// <param name="pContext">A context handle to identifies the client on the server. </param>
        /// <returns>Return zero if success, otherwise return nonzero.</returns>
        public int WitnessrRegisterEx(SwnVersion Version, string NetName, string ShareName, string IpAddr, string ClientName, WitnessrRegisterExFlagsValue Flags, uint KeepAliveTimout, out IntPtr pContext)
        {
            Int3264[] paramList;
            int retVal = 0;

            SafeIntPtr pNetName = Marshal.StringToHGlobalUni(NetName);
            SafeIntPtr pShareName = Marshal.StringToHGlobalUni(ShareName);
            SafeIntPtr pIpAddr = Marshal.StringToHGlobalUni(IpAddr);
            SafeIntPtr pClientName = Marshal.StringToHGlobalUni(ClientName);

            paramList = new Int3264[] {
                IntPtr.Zero,//out param
                (uint)Version,
                pNetName,
                pShareName,
                pIpAddr,
                pClientName,
                (uint)Flags,
                KeepAliveTimout,
                IntPtr.Zero //return value
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)SWN_OPNUM.WitnessrRegisterEx))
                {
                    pContext = Marshal.ReadIntPtr(outParamList[0]);
                    retVal = outParamList[paramList.Length - 1].ToInt32();
                }
            }
            finally
            {
                pNetName.Dispose();
                pShareName.Dispose();
                pIpAddr.Dispose();
                pClientName.Dispose();
            }

            return retVal;
        }