Exemple #1
0
 public ModelCreditOperationRequest(
     ModelMidType midType,
     ModelCreditCharge creditCharge,
     ModelCreditRequestNum creditRequestNum,
     ModelPayloadSize payloadSize,
     ModelPayloadType payloadType)
     : base(0)
 {
     this.midType          = midType;
     this.creditCharge     = creditCharge;
     this.creditRequestNum = creditRequestNum;
     this.payloadSize      = payloadSize;
     this.payloadType      = payloadType;
 }
 public ModelCreditOperationRequest(
     ModelMidType midType,
     ModelCreditCharge creditCharge,
     ModelCreditRequestNum creditRequestNum,
     ModelPayloadSize payloadSize,
     ModelPayloadType payloadType)
     : base(0)
 {
     this.midType = midType;
     this.creditCharge = creditCharge;
     this.creditRequestNum = creditRequestNum;
     this.payloadSize = payloadSize;
     this.payloadType = payloadType;
 }
        public static void CreditOperationRequest(
            ModelMidType midType,
            ModelCreditCharge creditCharge,
            ModelCreditRequestNum creditRequestNum,
            ModelPayloadSize payloadSize,
            ModelPayloadType payloadType)
        {
            Condition.IsTrue(state == ModelState.Connected);
            Condition.IsNull(request);

            Combination.Isolated(midType == ModelMidType.UsedMid);
            Combination.Isolated(midType == ModelMidType.UnavailableMid);
            Combination.Isolated(creditCharge == ModelCreditCharge.CreditChargeExceedBoundary);
            Combination.Isolated(payloadSize == ModelPayloadSize.PayloadSizeLargerThanBoundary);

            //Pairwise the rest parameters
            Combination.NWise(2, creditCharge, creditRequestNum, payloadSize, payloadType);

            request = new ModelCreditOperationRequest(
                midType,
                creditCharge,
                creditRequestNum,
                payloadSize,
                payloadType);

            // NOTE: creditCharge will be ignored if multicredit is not supported
            if (midType == ModelMidType.UsedMid
                || midType == ModelMidType.UnavailableMid
                || (isMultiCreditSupported && creditCharge == ModelCreditCharge.CreditChargeExceedBoundary))
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.2.3: If the server determines that the MessageId or the range of MessageIds for the incoming request is not valid," +
                    " the server SHOULD<202> terminate the connection. Otherwise, the server MUST remove the MessageId or the range of MessageIds from the Connection.CommandSequenceWindow.");
                //Not add Platform!=NonWindows because NonWindows could also drop connection

                if (midType == ModelMidType.UsedMid || midType == ModelMidType.UnavailableMid)
                {
                    ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier);
                }

                if (isMultiCreditSupported && creditCharge == ModelCreditCharge.CreditChargeExceedBoundary)
                {
                    ModelHelper.Log(LogType.TestTag, TestTag.OutOfBoundary);
                }

                expectDisconnection = true;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Test case is expecting server disconnect the connection");
                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.SupportsMultiCredit is set to {0}, messageId type is {1}, creditCharge type is {2}",
                    isMultiCreditSupported, midType, creditCharge);
                return;
            }

            if (!isMultiCreditSupported
                && payloadSize == ModelPayloadSize.PayloadSizeLargerThanBoundary)
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.2: If Connection.SupportsMultiCredit is FALSE and the size of the request is greater than 68*1024 bytes," +
                    " the server SHOULD<200> terminate the connection");
                //Ignore following product behavior as known issue for now
                ModelHelper.Log(
                    LogType.Requirement,
                    "<200> Section 3.3.5.2: Windows 7 without [MSKB-2536275], and Windows Server 2008 R2 without [MSKB-2536275] terminate the connection when the size of the request is greater than 64*1024 bytes." +
                    " Windows Vista SP1 and Windows Server 2008 on Direct TCP transport disconnect the connection if the size of the message exceeds 128*1024 bytes, and Windows Vista SP1 and Windows Server 2008 on NetBIOS over TCP transport will disconnect the connection if the size of the message exceeds 64*1024 bytes");

                ModelHelper.Log(LogType.TestTag, TestTag.OutOfBoundary);

                expectDisconnection = true;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Test case is expecting server to drop the connection");
                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.SupportsMultiCredit is set to {0}, messageId type is {1}, creditCharge type is {2}",
                    isMultiCreditSupported, midType, creditCharge);

            }
        }
        public void CreditOperationRequest(
            ModelMidType midType,
            ModelCreditCharge creditCharge,
            ModelCreditRequestNum creditRequestNum,
            ModelPayloadSize payloadSize,
            ModelPayloadType payloadType)
        {
            #region Customize message id

            ulong smallestAvailableMId = testClient.SequenceWindow.Min;
            ulong largestAvailableMId = testClient.SequenceWindow.Max;
            ulong customizedMId = 0;

            switch (midType)
            {
                case ModelMidType.UnavailableMid:
                    {
                        customizedMId = largestAvailableMId + 1;
                        break;
                    }
                case ModelMidType.UsedMid:
                    {
                        customizedMId = smallestAvailableMId - 1;
                        break;
                    }
                case ModelMidType.ValidMid:
                    {
                        customizedMId = (ulong)(smallestAvailableMId + largestAvailableMId) / 2;
                        break;
                    }
                default:
                    throw new ArgumentException("midType");
            }

            testClient.GenerateMessageId = (sequenceWindow) => customizedMId;

            Site.Log.Add(
                LogEntryKind.Debug,
                "*****customizedMId = {0}", customizedMId);

            #endregion

            #region Customize credit charge

            ushort customizedCreditCharge = 0;
            // Only customize credit charge when midType is valid
            if (midType == ModelMidType.ValidMid)
            {
                switch (creditCharge)
                {
                    case ModelCreditCharge.CreditChargeWithinBoundary:
                        {
                            customizedCreditCharge = (ushort)((largestAvailableMId - customizedMId + 2) / 2);
                            break;
                        }
                    case ModelCreditCharge.CreditChargeExceedBoundary:
                        {
                            customizedCreditCharge = (ushort)(largestAvailableMId - customizedMId + 2);
                            break;
                        }
                    case ModelCreditCharge.CreditChargeSetZero:
                        {
                            customizedCreditCharge = 0;
                            break;
                        }
                    default:
                        {
                            Site.Assume.Fail("Unexpected creditCharge {0}", creditCharge);
                            break;
                        }
                }
            }

            testClient.GenerateCreditCharge = (size) => customizedCreditCharge;

            Site.Log.Add(
                LogEntryKind.Debug,
                "*****customizedCreditCharge = {0}", customizedCreditCharge);

            #endregion

            #region Customize credit request

            ushort customizedCreditRequest = 0;
            switch (creditRequestNum)
            {
                case ModelCreditRequestNum.CreditRequestSetNonZero:
                    {
                        customizedCreditRequest = (ushort)((1 + testClient.CreditGoal) / 2);
                        break;
                    }
                case ModelCreditRequestNum.CreditRequestSetZero:
                    {
                        customizedCreditRequest = 0;
                        break;
                    }
                default:
                    {
                        Site.Assume.Fail("Unexpected creditRequestNum {0}", creditRequestNum);
                        break;
                    }
            }

            testClient.GenerateCreditRequest = (sequeceWindow, creditGoal, charge) => customizedCreditRequest;

            Site.Log.Add(
                LogEntryKind.Debug,
                "*****customizedCreditRequest = {0}", customizedCreditRequest);

            #endregion

            #region Calculate payload size

            int dataLengthInByte = 0;
            switch (payloadSize)
            {
                case ModelPayloadSize.PayloadSizeEqualToBoundary:
                    {
                        if (customizedCreditCharge == 0 && isMultiCreditSupportedOnConnection)
                        {
                            dataLengthInByte = 64 * 1024;
                        }
                        else if (!isMultiCreditSupportedOnConnection)
                        {
                            //3.3.5.2: If Connection.SupportsMultiCredit is FALSE and the size of the request is greater than 68*1024 bytes, the server SHOULD<200> terminate the connection
                            //Note 1. 68*1024 byte is total size of Smb2 packet including header, so need to subtract such overhead to calculate payload size
                            //     2. This case is only for WRITE but here does not distiguish READ and WRITE for simplicity

                            uint maxSize = 0;
                            if (testConfig.UnderlyingTransport == Smb2TransportType.NetBios)
                            {
                                maxSize = MaxNetbiosBufferSize;
                            }
                            else
                            {
                                maxSize = 68 * 1024;
                            }

                            dataLengthInByte = (int)(maxSize - Smb2PacketHeaderSizeInByte - Smb2WriteRequestBodySizeInByte);
                        }
                        else
                        {
                            dataLengthInByte = customizedCreditCharge * 64 * 1024;
                        }
                        break;
                    }
                case ModelPayloadSize.PayloadSizeLargerThanBoundary:
                    {
                        if (customizedCreditCharge == 0 && isMultiCreditSupportedOnConnection)
                        {
                            dataLengthInByte = 64 * 1024 + 1;
                        }
                        else if (!isMultiCreditSupportedOnConnection)
                        {
                            //3.3.5.2: If Connection.SupportsMultiCredit is FALSE and the size of the request is greater than 68*1024 bytes, the server SHOULD<200> terminate the connection
                            //Note 1. 68*1024 byte is total size of Smb2 packet including header, so need to subtract such overhead to calculate payload size
                            //     2. This case is only for WRITE but here does not distiguish READ and WRITE for simplicity

                            uint maxSize = 0;
                            if (testConfig.UnderlyingTransport == Smb2TransportType.NetBios)
                            {
                                maxSize = MaxNetbiosBufferSize;
                            }
                            else
                            {
                                maxSize = 68 * 1024;
                            }
                            dataLengthInByte = (int)(maxSize - Smb2PacketHeaderSizeInByte - Smb2WriteRequestBodySizeInByte + 1);
                        }
                        else
                        {
                            dataLengthInByte = customizedCreditCharge * 64 * 1024 + 1;
                        }
                        break;
                    }
                case ModelPayloadSize.PayloadSizeLessThanBoundary:
                    {
                        if (customizedCreditCharge == 0 && isMultiCreditSupportedOnConnection)
                        {
                            dataLengthInByte = 32 * 1024;
                        }
                        else if (!isMultiCreditSupportedOnConnection)
                        {
                            dataLengthInByte = 34 * 1024;
                        }
                        else
                        {
                            dataLengthInByte = customizedCreditCharge * 32 * 1024;
                        }
                        break;
                    }
                default:
                    {
                        Site.Assume.Fail("Unexpected creditRequestNum {0}", creditRequestNum);
                        break;
                    }
            }

            Site.Log.Add(
                LogEntryKind.Debug,
                "*****dataLengthInByte = {0}", dataLengthInByte);

            #endregion

            #region Send request

            uint status = 0;
            uint creditResponse = 0;

            switch (payloadType)
            {
                case ModelPayloadType.RequestPayload:
                    {
                        try
                        {
                            string contentToWrite = Smb2Utility.CreateRandomStringInByte(dataLengthInByte);

                            testClient.Write(
                                treeId,
                                fileId,
                                contentToWrite,
                                checker: (header, response) =>
                                {
                                    status = header.Status;
                                    creditResponse = header.CreditRequestResponse;
                                });

                            if (dataLengthInByte > testClient.MaxBufferSize
                                && config.Platform != Platform.WindowsServer2008)
                            {
                                // The server MUST validate that the length to write is within its configured maximum write size.
                                // If not, it SHOULD<283> fail the request with STATUS_INVALID_PARAMETER.
                                // <283> Section 3.3.5.13: Windows 7 and Windows Server 2008 R2 fail the request with STATUS_BUFFER_OVERFLOW instead of
                                // STATUS_INVALID_PARAMETER if the Length field is greater than Connection.MaxWriteSize.
                                // Windows Vista SP1 and Windows Server 2008 do not validate the Length field in SMB2 Write Request.
                                if (config.Platform == Platform.WindowsServer2008R2)
                                {
                                    Site.Assert.AreEqual(
                                        ModelSmb2Status.STATUS_BUFFER_OVERFLOW,
                                        (ModelSmb2Status)status,
                                        "Windows 7, Windows Server 2008 R2 fail the request with STATUS_BUFFER_OVERFLOW if exceeds max write size");
                                }
                                else
                                {
                                    Site.Assert.AreNotEqual(
                                        ModelSmb2Status.STATUS_SUCCESS,
                                        (ModelSmb2Status)status,
                                        "Server SHOULD fail the request with STATUS_INVALID_PARAMETER if exceeds max write data");
                                }
                                // Bypass the situation when data length exceeds max size that connection allows
                                CreditOperationResponse(ModelSmb2Status.STATUS_SUCCESS, creditResponse, config);
                            }
                            else
                            {
                                if (config.Platform == Platform.WindowsServer2008
                                    && dataLengthInByte > testClient.MaxBufferSize)
                                {
                                    Site.Assert.AreEqual(
                                        ModelSmb2Status.STATUS_SUCCESS,
                                        (ModelSmb2Status)status,
                                        "Windows Vista SP1 and Windows Server 2008 do not validate the Length field in SMB2 Write Request.");

                                    // Bypass the situation when data length exceeds max size that connection allows
                                    CreditOperationResponse(ModelSmb2Status.STATUS_INVALID_PARAMETER, creditResponse, config);
                                }
                                else
                                {
                                    CreditOperationResponse((ModelSmb2Status)status, creditResponse, config);
                                }
                            }

                            PostOperation();
                        }
                        catch (Exception ex)
                        {
                            // Make sure testClient was set to null during disconnection correctly
                            // In case we catch a timeout exception first
                            // Temp fix for test suite bug 6349 as per discussion

                            // For an SMB2 Write request with an invalid MessageId, Windows 8 and Windows Server 2012 will stop processing
                            // the request and any further requests on that connection.
                            // So Smb2Client will throw a timeout exception instead of disconnect event.
                            // The test case should handle the timeout exception the same with disconnect event.
                            if (ex is TimeoutException || testClient.Smb2Client.IsServerDisconnected)
                            {
                                OnServerDisconnected();
                            }
                            else
                            {
                                throw;
                            }
                            return;
                        }
                        break;
                    }
                case ModelPayloadType.ResponsePayload:
                    {
                        CreateFile(uncSharePath, fileName, dataLengthInByte);

                        try
                        {
                            string contentToRead = null;
                            testClient.Read(
                                treeId,
                                fileId,
                                0,
                                (uint)dataLengthInByte,
                                out contentToRead,
                                (header, response) =>
                                {
                                    status = header.Status;
                                    creditResponse = header.CreditRequestResponse;
                                });

                            if (dataLengthInByte > testClient.MaxBufferSize)
                            {
                                // The server MUST validate that the length to read is within its configured maximum read size.
                                // If not, it SHOULD<277> fail the request with STATUS_INVALID_PARAMETER.
                                // <277> Section 3.3.5.12: Windows 7 and Windows Server 2008 R2 fail the request with STATUS_BUFFER_OVERFLOW if the Length field is greater than Connection.MaxReadSize.
                                // Windows Vista SP1 and Windows Server 2008 will fail the request with STATUS_BUFFER_OVERFLOW if the Length field is greater than 524288(0x80000).
                                if (config.Platform == Platform.WindowsServer2008
                                    || config.Platform == Platform.WindowsServer2008R2)
                                {
                                    if (config.Platform == Platform.WindowsServer2008R2)
                                    {
                                        Site.Assert.AreEqual(
                                            ModelSmb2Status.STATUS_BUFFER_OVERFLOW,
                                            (ModelSmb2Status)status,
                                            "Windows 7, and Windows Server 2008 R2 fail the request with STATUS_BUFFER_OVERFLOW if exceeds max read size");
                                    }
                                    else if (dataLengthInByte > 524288)
                                    {
                                        Site.Assert.AreEqual(
                                            ModelSmb2Status.STATUS_BUFFER_OVERFLOW,
                                            (ModelSmb2Status)status,
                                            "Windows Vista SP1 and Windows Server 2008 will fail the request with STATUS_BUFFER_OVERFLOW if the Length field is greater than 524288");
                                    }
                                }
                                else if (config.Platform == Platform.WindowsServer2012
                                        || config.Platform == Platform.WindowsServer2012R2)
                                {
                                    // The server MUST validate that the length to read is within its configured maximum read size.
                                    // If not, it SHOULD<277> fail the request with STATUS_INVALID_PARAMETER.
                                    Site.Assert.AreEqual(
                                        ModelSmb2Status.STATUS_INVALID_PARAMETER,
                                        (ModelSmb2Status)status,
                                        "The server SHOULD fail the request with STATUS_INVALID_PARAMETER if the length is NOT within its configured maximum size.");
                                }
                                else // NonWindows
                                {
                                    Site.Assert.AreNotEqual(
                                        ModelSmb2Status.STATUS_SUCCESS,
                                        (ModelSmb2Status)status,
                                        "Server SHOULD fail the request with STATUS_INVALID_PARAMETER if exceeds max read size");
                                }
                                // Bypass the situation when data length exceeds max size that connection allows
                                CreditOperationResponse(ModelSmb2Status.STATUS_SUCCESS, creditResponse, config);
                            }
                            else
                            {
                                CreditOperationResponse((ModelSmb2Status)status, creditResponse, config);
                            }

                            PostOperation();
                        }
                        catch (Exception ex)
                        {
                            // Make sure testClient was set to null during disconnection correctly
                            // In case we catch a timeout exception first
                            // Temp fix for test suite bug 6349 as per discussion

                            // For an SMB2 Write request with an invalid MessageId, Windows 8 and Windows Server 2012 will stop processing
                            // the request and any further requests on that connection.
                            // So Smb2Client will throw a timeout exception instead of disconnect event.
                            // The test case should handle the timeout exception the same with disconnect event.
                            if (ex is TimeoutException || testClient.Smb2Client.IsServerDisconnected)
                            {
                                OnServerDisconnected();
                            }
                            else
                            {
                                throw;
                            }
                            return;
                        }
                        break;
                    }
                default:
                    throw new ArgumentException("payloadType");
            }

            #endregion
        }
        public static void CreditOperationRequest(
            ModelMidType midType,
            ModelCreditCharge creditCharge,
            ModelCreditRequestNum creditRequestNum,
            ModelPayloadSize payloadSize,
            ModelPayloadType payloadType)
        {
            Condition.IsTrue(state == ModelState.Connected);
            Condition.IsNull(request);

            Combination.Isolated(midType == ModelMidType.UsedMid);
            Combination.Isolated(midType == ModelMidType.UnavailableMid);
            Combination.Isolated(creditCharge == ModelCreditCharge.CreditChargeExceedBoundary);
            Combination.Isolated(payloadSize == ModelPayloadSize.PayloadSizeLargerThanBoundary);

            //Pairwise the rest parameters
            Combination.NWise(2, creditCharge, creditRequestNum, payloadSize, payloadType);

            request = new ModelCreditOperationRequest(
                midType,
                creditCharge,
                creditRequestNum,
                payloadSize,
                payloadType);

            // NOTE: creditCharge will be ignored if multicredit is not supported
            if (midType == ModelMidType.UsedMid ||
                midType == ModelMidType.UnavailableMid ||
                (isMultiCreditSupported && creditCharge == ModelCreditCharge.CreditChargeExceedBoundary))
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.2.3: If the server determines that the MessageId or the range of MessageIds for the incoming request is not valid," +
                    " the server SHOULD<202> terminate the connection. Otherwise, the server MUST remove the MessageId or the range of MessageIds from the Connection.CommandSequenceWindow.");
                //Not add Platform!=NonWindows because NonWindows could also drop connection

                if (midType == ModelMidType.UsedMid || midType == ModelMidType.UnavailableMid)
                {
                    ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier);
                }

                if (isMultiCreditSupported && creditCharge == ModelCreditCharge.CreditChargeExceedBoundary)
                {
                    ModelHelper.Log(LogType.TestTag, TestTag.OutOfBoundary);
                }

                expectDisconnection = true;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Test case is expecting server disconnect the connection");
                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.SupportsMultiCredit is set to {0}, messageId type is {1}, creditCharge type is {2}",
                    isMultiCreditSupported, midType, creditCharge);
                return;
            }

            if (!isMultiCreditSupported &&
                payloadSize == ModelPayloadSize.PayloadSizeLargerThanBoundary)
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.2: If Connection.SupportsMultiCredit is FALSE and the size of the request is greater than 68*1024 bytes," +
                    " the server SHOULD<200> terminate the connection");
                //Ignore following product behavior as known issue for now
                ModelHelper.Log(
                    LogType.Requirement,
                    "<200> Section 3.3.5.2: Windows 7 without [MSKB-2536275], and Windows Server 2008 R2 without [MSKB-2536275] terminate the connection when the size of the request is greater than 64*1024 bytes." +
                    " Windows Vista SP1 and Windows Server 2008 on Direct TCP transport disconnect the connection if the size of the message exceeds 128*1024 bytes, and Windows Vista SP1 and Windows Server 2008 on NetBIOS over TCP transport will disconnect the connection if the size of the message exceeds 64*1024 bytes");

                ModelHelper.Log(LogType.TestTag, TestTag.OutOfBoundary);

                expectDisconnection = true;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Test case is expecting server to drop the connection");
                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.SupportsMultiCredit is set to {0}, messageId type is {1}, creditCharge type is {2}",
                    isMultiCreditSupported, midType, creditCharge);
            }
        }
Exemple #6
0
        public void CreditOperationRequest(
            ModelMidType midType,
            ModelCreditCharge creditCharge,
            ModelCreditRequestNum creditRequestNum,
            ModelPayloadSize payloadSize,
            ModelPayloadType payloadType)
        {
            #region Customize message id

            ulong smallestAvailableMId = testClient.SequenceWindow.Min;
            ulong largestAvailableMId  = testClient.SequenceWindow.Max;
            ulong customizedMId        = 0;

            switch (midType)
            {
            case ModelMidType.UnavailableMid:
            {
                customizedMId = largestAvailableMId + 1;
                break;
            }

            case ModelMidType.UsedMid:
            {
                customizedMId = smallestAvailableMId - 1;
                break;
            }

            case ModelMidType.ValidMid:
            {
                customizedMId = (ulong)(smallestAvailableMId + largestAvailableMId) / 2;
                break;
            }

            default:
                throw new ArgumentException("midType");
            }

            testClient.GenerateMessageId = (sequenceWindow) => customizedMId;

            Site.Log.Add(
                LogEntryKind.Debug,
                "*****customizedMId = {0}", customizedMId);

            #endregion

            #region Customize credit charge

            ushort customizedCreditCharge = 0;
            // Only customize credit charge when midType is valid
            if (midType == ModelMidType.ValidMid)
            {
                switch (creditCharge)
                {
                case ModelCreditCharge.CreditChargeWithinBoundary:
                {
                    customizedCreditCharge = (ushort)((largestAvailableMId - customizedMId + 2) / 2);
                    break;
                }

                case ModelCreditCharge.CreditChargeExceedBoundary:
                {
                    customizedCreditCharge = (ushort)(largestAvailableMId - customizedMId + 2);
                    break;
                }

                case ModelCreditCharge.CreditChargeSetZero:
                {
                    customizedCreditCharge = 0;
                    break;
                }

                default:
                {
                    Site.Assume.Fail("Unexpected creditCharge {0}", creditCharge);
                    break;
                }
                }
            }

            testClient.GenerateCreditCharge = (size) => customizedCreditCharge;

            Site.Log.Add(
                LogEntryKind.Debug,
                "*****customizedCreditCharge = {0}", customizedCreditCharge);

            #endregion

            #region Customize credit request

            ushort customizedCreditRequest = 0;
            switch (creditRequestNum)
            {
            case ModelCreditRequestNum.CreditRequestSetNonZero:
            {
                customizedCreditRequest = (ushort)((1 + testClient.CreditGoal) / 2);
                break;
            }

            case ModelCreditRequestNum.CreditRequestSetZero:
            {
                customizedCreditRequest = 0;
                break;
            }

            default:
            {
                Site.Assume.Fail("Unexpected creditRequestNum {0}", creditRequestNum);
                break;
            }
            }

            testClient.GenerateCreditRequest = (sequeceWindow, creditGoal, charge) => customizedCreditRequest;

            Site.Log.Add(
                LogEntryKind.Debug,
                "*****customizedCreditRequest = {0}", customizedCreditRequest);

            #endregion

            #region Calculate payload size

            int dataLengthInByte = 0;
            switch (payloadSize)
            {
            case ModelPayloadSize.PayloadSizeEqualToBoundary:
            {
                if (customizedCreditCharge == 0 && isMultiCreditSupportedOnConnection)
                {
                    dataLengthInByte = 64 * 1024;
                }
                else if (!isMultiCreditSupportedOnConnection)
                {
                    //3.3.5.2: If Connection.SupportsMultiCredit is FALSE and the size of the request is greater than 68*1024 bytes, the server SHOULD<200> terminate the connection
                    //Note 1. 68*1024 byte is total size of Smb2 packet including header, so need to subtract such overhead to calculate payload size
                    //     2. This case is only for WRITE but here does not distiguish READ and WRITE for simplicity

                    uint maxSize = 0;
                    if (testConfig.UnderlyingTransport == Smb2TransportType.NetBios)
                    {
                        maxSize = MaxNetbiosBufferSize;
                    }
                    else
                    {
                        maxSize = 68 * 1024;
                    }

                    dataLengthInByte = (int)(maxSize - Smb2PacketHeaderSizeInByte - Smb2WriteRequestBodySizeInByte);
                }
                else
                {
                    dataLengthInByte = customizedCreditCharge * 64 * 1024;
                }
                break;
            }

            case ModelPayloadSize.PayloadSizeLargerThanBoundary:
            {
                if (customizedCreditCharge == 0 && isMultiCreditSupportedOnConnection)
                {
                    dataLengthInByte = 64 * 1024 + 1;
                }
                else if (!isMultiCreditSupportedOnConnection)
                {
                    //3.3.5.2: If Connection.SupportsMultiCredit is FALSE and the size of the request is greater than 68*1024 bytes, the server SHOULD<200> terminate the connection
                    //Note 1. 68*1024 byte is total size of Smb2 packet including header, so need to subtract such overhead to calculate payload size
                    //     2. This case is only for WRITE but here does not distiguish READ and WRITE for simplicity

                    uint maxSize = 0;
                    if (testConfig.UnderlyingTransport == Smb2TransportType.NetBios)
                    {
                        maxSize = MaxNetbiosBufferSize;
                    }
                    else
                    {
                        maxSize = 68 * 1024;
                    }
                    dataLengthInByte = (int)(maxSize - Smb2PacketHeaderSizeInByte - Smb2WriteRequestBodySizeInByte + 1);
                }
                else
                {
                    dataLengthInByte = customizedCreditCharge * 64 * 1024 + 1;
                }
                break;
            }

            case ModelPayloadSize.PayloadSizeLessThanBoundary:
            {
                if (customizedCreditCharge == 0 && isMultiCreditSupportedOnConnection)
                {
                    dataLengthInByte = 32 * 1024;
                }
                else if (!isMultiCreditSupportedOnConnection)
                {
                    dataLengthInByte = 34 * 1024;
                }
                else
                {
                    dataLengthInByte = customizedCreditCharge * 32 * 1024;
                }
                break;
            }

            default:
            {
                Site.Assume.Fail("Unexpected creditRequestNum {0}", creditRequestNum);
                break;
            }
            }

            Site.Log.Add(
                LogEntryKind.Debug,
                "*****dataLengthInByte = {0}", dataLengthInByte);

            #endregion

            #region Send request

            uint status         = 0;
            uint creditResponse = 0;

            switch (payloadType)
            {
            case ModelPayloadType.RequestPayload:
            {
                try
                {
                    string contentToWrite = Smb2Utility.CreateRandomStringInByte(dataLengthInByte);

                    testClient.Write(
                        treeId,
                        fileId,
                        contentToWrite,
                        checker: (header, response) =>
                        {
                            status         = header.Status;
                            creditResponse = header.CreditRequestResponse;
                        });

                    if (dataLengthInByte > testClient.MaxBufferSize &&
                        config.Platform != Platform.WindowsServer2008)
                    {
                        // The server MUST validate that the length to write is within its configured maximum write size.
                        // If not, it SHOULD<283> fail the request with STATUS_INVALID_PARAMETER.
                        // <283> Section 3.3.5.13: Windows 7 and Windows Server 2008 R2 fail the request with STATUS_BUFFER_OVERFLOW instead of
                        // STATUS_INVALID_PARAMETER if the Length field is greater than Connection.MaxWriteSize.
                        // Windows Vista SP1 and Windows Server 2008 do not validate the Length field in SMB2 Write Request.
                        if (config.Platform == Platform.WindowsServer2008R2)
                        {
                            Site.Assert.AreEqual(
                                ModelSmb2Status.STATUS_BUFFER_OVERFLOW,
                                (ModelSmb2Status)status,
                                "Windows 7, Windows Server 2008 R2 fail the request with STATUS_BUFFER_OVERFLOW if exceeds max write size");
                        }
                        else
                        {
                            Site.Assert.AreNotEqual(
                                ModelSmb2Status.STATUS_SUCCESS,
                                (ModelSmb2Status)status,
                                "Server SHOULD fail the request with STATUS_INVALID_PARAMETER if exceeds max write data");
                        }
                        // Bypass the situation when data length exceeds max size that connection allows
                        CreditOperationResponse(ModelSmb2Status.STATUS_SUCCESS, creditResponse, config);
                    }
                    else
                    {
                        if (config.Platform == Platform.WindowsServer2008 &&
                            dataLengthInByte > testClient.MaxBufferSize)
                        {
                            Site.Assert.AreEqual(
                                ModelSmb2Status.STATUS_SUCCESS,
                                (ModelSmb2Status)status,
                                "Windows Vista SP1 and Windows Server 2008 do not validate the Length field in SMB2 Write Request.");

                            // Bypass the situation when data length exceeds max size that connection allows
                            CreditOperationResponse(ModelSmb2Status.STATUS_INVALID_PARAMETER, creditResponse, config);
                        }
                        else
                        {
                            CreditOperationResponse((ModelSmb2Status)status, creditResponse, config);
                        }
                    }

                    PostOperation();
                }
                catch (Exception ex)
                {
                    // Make sure testClient was set to null during disconnection correctly
                    // In case we catch a timeout exception first
                    // Temp fix for test suite bug 6349 as per discussion

                    // For an SMB2 Write request with an invalid MessageId, Windows 8 and Windows Server 2012 will stop processing
                    // the request and any further requests on that connection.
                    // So Smb2Client will throw a timeout exception instead of disconnect event.
                    // The test case should handle the timeout exception the same with disconnect event.
                    if (ex is TimeoutException || testClient.Smb2Client.IsServerDisconnected)
                    {
                        OnServerDisconnected();
                    }
                    else
                    {
                        throw;
                    }
                    return;
                }
                break;
            }

            case ModelPayloadType.ResponsePayload:
            {
                CreateFile(uncSharePath, fileName, dataLengthInByte);

                try
                {
                    string contentToRead = null;
                    testClient.Read(
                        treeId,
                        fileId,
                        0,
                        (uint)dataLengthInByte,
                        out contentToRead,
                        (header, response) =>
                        {
                            status         = header.Status;
                            creditResponse = header.CreditRequestResponse;
                        });

                    if (dataLengthInByte > testClient.MaxBufferSize)
                    {
                        // The server MUST validate that the length to read is within its configured maximum read size.
                        // If not, it SHOULD<277> fail the request with STATUS_INVALID_PARAMETER.
                        // <277> Section 3.3.5.12: Windows 7 and Windows Server 2008 R2 fail the request with STATUS_BUFFER_OVERFLOW if the Length field is greater than Connection.MaxReadSize.
                        // Windows Vista SP1 and Windows Server 2008 will fail the request with STATUS_BUFFER_OVERFLOW if the Length field is greater than 524288(0x80000).
                        if (config.Platform == Platform.WindowsServer2008 ||
                            config.Platform == Platform.WindowsServer2008R2)
                        {
                            if (config.Platform == Platform.WindowsServer2008R2)
                            {
                                Site.Assert.AreEqual(
                                    ModelSmb2Status.STATUS_BUFFER_OVERFLOW,
                                    (ModelSmb2Status)status,
                                    "Windows 7, and Windows Server 2008 R2 fail the request with STATUS_BUFFER_OVERFLOW if exceeds max read size");
                            }
                            else if (dataLengthInByte > 524288)
                            {
                                Site.Assert.AreEqual(
                                    ModelSmb2Status.STATUS_BUFFER_OVERFLOW,
                                    (ModelSmb2Status)status,
                                    "Windows Vista SP1 and Windows Server 2008 will fail the request with STATUS_BUFFER_OVERFLOW if the Length field is greater than 524288");
                            }
                        }
                        else if (config.Platform == Platform.WindowsServer2012 ||
                                 config.Platform == Platform.WindowsServer2012R2)
                        {
                            // The server MUST validate that the length to read is within its configured maximum read size.
                            // If not, it SHOULD<277> fail the request with STATUS_INVALID_PARAMETER.
                            Site.Assert.AreEqual(
                                ModelSmb2Status.STATUS_INVALID_PARAMETER,
                                (ModelSmb2Status)status,
                                "The server SHOULD fail the request with STATUS_INVALID_PARAMETER if the length is NOT within its configured maximum size.");
                        }
                        else         // NonWindows
                        {
                            Site.Assert.AreNotEqual(
                                ModelSmb2Status.STATUS_SUCCESS,
                                (ModelSmb2Status)status,
                                "Server SHOULD fail the request with STATUS_INVALID_PARAMETER if exceeds max read size");
                        }
                        // Bypass the situation when data length exceeds max size that connection allows
                        CreditOperationResponse(ModelSmb2Status.STATUS_SUCCESS, creditResponse, config);
                    }
                    else
                    {
                        CreditOperationResponse((ModelSmb2Status)status, creditResponse, config);
                    }

                    PostOperation();
                }
                catch (Exception ex)
                {
                    // Make sure testClient was set to null during disconnection correctly
                    // In case we catch a timeout exception first
                    // Temp fix for test suite bug 6349 as per discussion

                    // For an SMB2 Write request with an invalid MessageId, Windows 8 and Windows Server 2012 will stop processing
                    // the request and any further requests on that connection.
                    // So Smb2Client will throw a timeout exception instead of disconnect event.
                    // The test case should handle the timeout exception the same with disconnect event.
                    if (ex is TimeoutException || testClient.Smb2Client.IsServerDisconnected)
                    {
                        OnServerDisconnected();
                    }
                    else
                    {
                        throw;
                    }
                    return;
                }
                break;
            }

            default:
                throw new ArgumentException("payloadType");
            }

            #endregion
        }