/// <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); }
/// <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 }
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; }