static void PrintNotification(RESP_ASYNC_NOTIFY respNotify)
        {
            if ((SwnMessageType)respNotify.MessageType == SwnMessageType.RESOURCE_CHANGE_NOTIFICATION)
            {
                Console.WriteLine("MessageType: SWN_SERVER_MESSAGE_RESOURCE_CHANGE_NOTIFICATION");

                RESOURCE_CHANGE[] resourceChangeList;
                SwnUtility.ParseResourceChange(respNotify, out resourceChangeList);

                foreach (var res in resourceChangeList)
                {
                    Console.WriteLine("Resource name: {0}", res.ResourceName);
                    switch ((SwnResourceChangeType)res.ChangeType)
                    {
                    case SwnResourceChangeType.RESOURCE_STATE_UNKNOWN:
                        Console.WriteLine("Change type: RESOURCE_STATE_UNKNOWN");
                        break;

                    case SwnResourceChangeType.RESOURCE_STATE_AVAILABLE:
                        Console.WriteLine("Change type: RESOURCE_STATE_AVAILABLE");
                        break;

                    case SwnResourceChangeType.RESOURCE_STATE_UNAVAILABLE:
                        Console.WriteLine("Change type: SWN_RESOURCE_STATE_UNAVAILABLE");
                        break;

                    default:
                        Console.WriteLine("Change type: Unknown type {0}", res.ChangeType);
                        break;
                    }
                }
            }
            else if ((SwnMessageType)respNotify.MessageType == SwnMessageType.RESOURCE_MOVE_NOTIFICATION)
            {
                Console.WriteLine("MessageType: SWN_SERVER_MESSAGE_RESOURCE_MOVE_NOTIFICATION");

                MOVE_REQUEST moveRequest;
                SwnUtility.ParseMoveRequest(respNotify, out moveRequest);

                foreach (var ip in moveRequest.IPAddrList)
                {
                    Console.WriteLine("---------------------------------");
                    if (((uint)SwnIPAddrType.MOVE_DST_IPADDR_V4 & ip.Flags) != 0)
                    {
                        Console.WriteLine("IPAddr V4: {0}", ip.IPV4);
                    }
                    if (((uint)SwnIPAddrType.MOVE_DST_IPADDR_V6 & ip.Flags) != 0)
                    {
                        Console.WriteLine("IPAddr V6: {0}", ip.IPV6);
                    }
                }
            }
            else
            {
                Console.WriteLine("MessageType: Unknown type: {0}", respNotify.MessageType);
            }
        }
예제 #2
0
        /// <summary>
        /// Verify RESOURCE_CHANGE_NOTIFICATION in Asynchronous Notification
        /// </summary>
        /// <param name="respNotify">Asynchronous notification</param>
        /// <param name="changeType">State change of the resource</param>
        public static void VerifyResourceChange(RESP_ASYNC_NOTIFY respNotify, SwnResourceChangeType changeType)
        {
            BaseTestSite.Assert.AreEqual <uint>((uint)SwnMessageType.RESOURCE_CHANGE_NOTIFICATION,
                                                respNotify.MessageType, "Expect MessageType is set to RESOURCE_CHANGE_NOTIFICATION");

            RESOURCE_CHANGE[] resourceChangeList;
            SwnUtility.ParseResourceChange(respNotify, out resourceChangeList);
            BaseTestSite.Assert.AreEqual <uint>(0x00000001, respNotify.NumberOfMessages, "Expect NumberOfMessages is set to 1.");

            BaseTestSite.Assert.AreEqual <uint>((uint)changeType, resourceChangeList[0].ChangeType, "Expect ChangeType is set to {0}.", changeType);
        }
예제 #3
0
        private void FileServerFailoverTest(string server, FileServerType fsType, bool reconnectWithoutFailover = false)
        {
            int       ret    = 0;
            uint      callId = 0;
            IPAddress currentAccessIpAddr            = null;
            WITNESS_INTERFACE_INFO registerInterface = new WITNESS_INTERFACE_INFO();
            WITNESS_INTERFACE_LIST interfaceList     = new WITNESS_INTERFACE_LIST();

            currentAccessIpAddr = SWNTestUtility.GetCurrentAccessIP(server);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Get current file server IP: {0}.", currentAccessIpAddr);

            #region Register SWN witness
            if (witnessType == WitnessType.SwnWitness)
            {
                if (TestConfig.IsWindowsPlatform && fsType == FileServerType.ScaleOutFileServer)
                {
                    // Windows Server: when stopping a non-owner node of ScaleOutFS, no notication will be sent by SMB witness.
                    // So get one IP of the owner node of ScaleOutFS to access.
                    string      resourceOwnerNode = sutController.GetClusterResourceOwner(server);
                    IPAddress[] ownerIpList       = Dns.GetHostEntry(resourceOwnerNode).AddressList;
                    foreach (var ip in ownerIpList)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Owner IP: {0}", ip);
                    }
                    if (!ownerIpList.Contains(currentAccessIpAddr))
                    {
                        currentAccessIpAddr = null;
                        IPAddress[] accessIpList = Dns.GetHostEntry(server).AddressList;
                        foreach (var ip in accessIpList)
                        {
                            if (ownerIpList.Contains(ip))
                            {
                                currentAccessIpAddr = ip;
                                break;
                            }
                        }
                        BaseTestSite.Assert.IsNotNull(currentAccessIpAddr, "IP should not be null.");
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Get the owner IP {0} as file server IP.", currentAccessIpAddr);
                    }

                    DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIpAddr,
                                                                   TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                                                                   TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, resourceOwnerNode), TestConfig.FailoverTimeout,
                                   "Retry BindServer until succeed within timeout span");
                }
                else
                {
                    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");
                }

                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.");

                SWNTestUtility.GetRegisterInterface(interfaceList, out registerInterface);

                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, registerInterface.InterfaceGroupName), TestConfig.FailoverTimeout,
                               "Retry BindServer until succeed within timeout span");

                string clientName = Guid.NewGuid().ToString();

                BaseTestSite.Log.Add(LogEntryKind.Debug, "Register witness:");
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tNetName: {0}", SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server));
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddress: {0}", currentAccessIpAddr.ToString());
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tClient Name: {0}", clientName);

                ret = swnClientForWitness.WitnessrRegister(SwnVersion.SWN_VERSION_1, SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server),
                                                           currentAccessIpAddr.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();

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

            #region Disable accessed node

            if (TestConfig.IsWindowsPlatform)
            {
                AssignCurrentAccessNode(server, fsType, currentAccessIpAddr);
            }


            if (!reconnectWithoutFailover)
            {
                BaseTestSite.Log.Add(
                    LogEntryKind.TestStep,
                    "Disable owner node for general file server or the node currently provides the access for scale-out file server.");
                FailoverServer(currentAccessIpAddr, server, fsType);
            }

            #endregion

            #region Wait for available server
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Wait for available server.");
            if (witnessType == WitnessType.None)
            {
                if (fsType == FileServerType.GeneralFileServer)
                {
                    currentAccessIpAddr = null;
                    IPAddress[] accessIpList = Dns.GetHostEntry(server).AddressList;
                    DoUntilSucceed(() =>
                    {
                        foreach (IPAddress ipAddress in accessIpList)
                        {
                            Smb2FunctionalClient pingClient = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);

                            try
                            {
                                pingClient.ConnectToServerOverTCP(ipAddress);
                                pingClient.Disconnect();
                                pingClient = null;

                                currentAccessIpAddr = ipAddress;
                                return(true);
                            }
                            catch
                            {
                            }
                        }
                        return(false);
                    }, TestConfig.FailoverTimeout, "Retry to ping to server until succeed within timeout span");
                }
                else
                {
                    currentAccessIpAddr = null;

                    IPAddress[] accessIpList = Dns.GetHostEntry(server).AddressList;
                    foreach (IPAddress ipAddress in accessIpList)
                    {
                        if (TestConfig.IsWindowsPlatform)
                        {
                            // When setting failover mode to StopNodeService for Windows, SMB2 servers on two nodes can still be accessed by the client.
                            // So the client needs to get the new node to access it after failover by comparing host name.
                            if (string.Compare(currentAccessNode, Dns.GetHostEntry(ipAddress).HostName, true) == 0)
                            {
                                continue;
                            }
                        }
                        Smb2FunctionalClient pingClient = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);

                        try
                        {
                            pingClient.ConnectToServerOverTCP(ipAddress);
                            pingClient.Disconnect();
                            pingClient = null;

                            currentAccessIpAddr = ipAddress;
                            break;
                        }
                        catch
                        {
                        }
                    }
                }
            }
            else if (witnessType == WitnessType.SwnWitness)
            {
                // Verifying for notification
                RESP_ASYNC_NOTIFY respNotify;
                do
                {
                    // Wait the notification
                    ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
                    BaseTestSite.Assert.AreEqual <SwnErrorCode>(
                        SwnErrorCode.ERROR_SUCCESS,
                        (SwnErrorCode)ret,
                        "ExpectWitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);
                    SWNTestUtility.PrintNotification(respNotify);

                    RESOURCE_CHANGE[] resourceChangeList;
                    SwnUtility.ParseResourceChange(respNotify, out resourceChangeList);
                    BaseTestSite.Assert.AreEqual <uint>(0x00000001, respNotify.NumberOfMessages, "Expect NumberOfMessages is set to 1.");

                    if (resourceChangeList[0].ChangeType == (uint)SwnResourceChangeType.RESOURCE_STATE_AVAILABLE)
                    {
                        // Verify RESP_ASYNC_NOTIFY, the resource is available
                        SWNTestUtility.VerifyResourceChange(respNotify, SwnResourceChangeType.RESOURCE_STATE_AVAILABLE);
                        break;
                    }

                    // Verify RESP_ASYNC_NOTIFY, the resource is unavailable
                    SWNTestUtility.VerifyResourceChange(respNotify, SwnResourceChangeType.RESOURCE_STATE_UNAVAILABLE);

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

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

                if (fsType == FileServerType.ScaleOutFileServer)
                {
                    // For scale-out file server case, retrieve and use another access IP for connection
                    currentAccessIpAddr =
                        (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6);
                }
            }
            #endregion

            #region Read content and close the file
            DoUntilSucceed(() => ReadContentAfterFailover(server, currentAccessIpAddr, uncSharePath, file, content, clientGuid, createGuid),
                           TestConfig.FailoverTimeout,
                           "After failover, retry Read content until succeed within timeout span.");
            #endregion
        }
예제 #4
0
        /// <summary>
        /// Print RESP_ASYNC_NOTIFY
        /// </summary>
        /// <param name="respNotify">Asynchronous notification</param>
        public static void PrintNotification(RESP_ASYNC_NOTIFY respNotify)
        {
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Receive asynchronous notification");
            switch ((SwnMessageType)respNotify.MessageType)
            {
            case SwnMessageType.RESOURCE_CHANGE_NOTIFICATION:
            {
                RESOURCE_CHANGE[] resourceChangeList;
                SwnUtility.ParseResourceChange(respNotify, out resourceChangeList);

                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tRESOURCE_CHANGE");
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tcount: {0}", resourceChangeList.Length);

                foreach (var res in resourceChangeList)
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug, "\t\tResource name: {0}", res.ResourceName.Substring(0, res.ResourceName.Length - 1));
                    switch ((SwnResourceChangeType)res.ChangeType)
                    {
                    case SwnResourceChangeType.RESOURCE_STATE_UNKNOWN:
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "\t\tChange type: RESOURCE_STATE_UNKNOWN");
                        break;

                    case SwnResourceChangeType.RESOURCE_STATE_AVAILABLE:
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "\t\tChange type: RESOURCE_STATE_AVAILABLE");
                        break;

                    case SwnResourceChangeType.RESOURCE_STATE_UNAVAILABLE:
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "\t\tChange type: RESOURCE_STATE_UNAVAILABLE");
                        break;

                    default:
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "\t\tChange type: Unknown type {0}", res.ChangeType);
                        break;
                    }
                }
            }
            break;

            case SwnMessageType.CLIENT_MOVE_NOTIFICATION:
            {
                IPADDR_INFO_LIST IPAddrInfoList;
                SwnUtility.ParseIPAddrInfoList(respNotify, out IPAddrInfoList);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tCLIENT_MOVE");
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tReserved: {0}", IPAddrInfoList.Reserved);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIP address count: {0}", IPAddrInfoList.IPAddrInstances);

                foreach (var ip in IPAddrInfoList.IPAddrList)
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug, "\tFlags: {0}", ip.Flags);
                    if (((uint)SwnIPAddrInfoFlags.IPADDR_V4 & ip.Flags) != 0)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddr V4: {0}", (new IPAddress(ip.IPV4)).ToString());
                    }
                    if (((uint)SwnIPAddrInfoFlags.IPADDR_V6 & ip.Flags) != 0)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddr V6: {0}", ConvertIPV6(ip.IPV6).ToString());
                    }
                }
            }
            break;

            case SwnMessageType.SHARE_MOVE_NOTIFICATION:
            {
                IPADDR_INFO_LIST IPAddrInfoList;
                SwnUtility.ParseIPAddrInfoList(respNotify, out IPAddrInfoList);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tSHARE_MOVE");
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tReserved: {0}", IPAddrInfoList.Reserved);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIP address count: {0}", IPAddrInfoList.IPAddrInstances);

                foreach (var ip in IPAddrInfoList.IPAddrList)
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug, "\tFlags: {0}", ip.Flags);
                    if (((uint)SwnIPAddrInfoFlags.IPADDR_V4 & ip.Flags) != 0)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddr V4: {0}", (new IPAddress(ip.IPV4)).ToString());
                    }
                    if (((uint)SwnIPAddrInfoFlags.IPADDR_V6 & ip.Flags) != 0)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddr V6: {0}", ConvertIPV6(ip.IPV6).ToString());
                    }
                }
            }
            break;

            case SwnMessageType.IP_CHANGE_NOTIFICATION:
            {
                IPADDR_INFO_LIST IPAddrInfoList;
                SwnUtility.ParseIPAddrInfoList(respNotify, out IPAddrInfoList);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIP_CHANGE");
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tReserved: {0}", IPAddrInfoList.Reserved);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIP address count: {0}", IPAddrInfoList.IPAddrInstances);

                foreach (var ip in IPAddrInfoList.IPAddrList)
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug, "\tFlags: {0}", ip.Flags);
                    if (((uint)SwnIPAddrInfoFlags.IPADDR_V4 & ip.Flags) != 0)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddr V4: {0}", (new IPAddress(ip.IPV4)).ToString());
                    }
                    if (((uint)SwnIPAddrInfoFlags.IPADDR_V6 & ip.Flags) != 0)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddr V6: {0}", ConvertIPV6(ip.IPV6).ToString());
                    }
                }
            }
            break;

            default:
                BaseTestSite.Assert.Fail("\t\tMessage type: Unknown type {0}", respNotify.MessageType);
                break;
            }
        }