コード例 #1
0
        public void Smb2OverRdmaChannel_ReadWriteMultipleBufferDescriptorList()
        {
            InitSmbdConnectionForTestCases(smbdAdapter.TestConfig.TestFileName_LargeFile);
            uint size = smbdAdapter.Smb2MaxReadSize;

            if (size > smbdAdapter.Smb2MaxWriteSize)
            {
                size = smbdAdapter.Smb2MaxWriteSize;
            }
            int  bufferCount  = ushort.MaxValue / SmbdBufferDescriptorV1.SIZE; // SMB2 max support channel info size
            uint bufferLength = (uint)(size / bufferCount + 1);                // buffer length of each buffer descriptor

            byte[]   channelInfo  = new byte[SmbdBufferDescriptorV1.SIZE * bufferCount];
            byte[]   writeContent = Encoding.ASCII.GetBytes(Smb2Utility.CreateRandomStringInByte((int)size));
            byte[]   readContent  = new byte[size];
            NtStatus status;

            #region SMB2 Write file
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 WRITE");
            SmbdBufferDescriptorV1[] writeDescp = new SmbdBufferDescriptorV1[bufferCount];
            for (int i = 0; i < bufferCount; ++i)
            {
                smbdAdapter.SmbdRegisterBuffer(
                    bufferLength,
                    SmbdBufferReadWrite.RDMA_READ_PERMISSION_FOR_WRITE_FILE,
                    out writeDescp[i]);
                byte[] channelInfoBlock = TypeMarshal.ToBytes <SmbdBufferDescriptorV1>(writeDescp[i]);
                Array.Copy(
                    channelInfoBlock,
                    0,
                    channelInfo,
                    SmbdBufferDescriptorV1.SIZE * i,
                    SmbdBufferDescriptorV1.SIZE);
            }
            // copy write content
            for (int index = 0, writeOffset = 0;
                 index < bufferCount && writeOffset < writeContent.Length;
                 ++index, writeOffset += (int)bufferLength)
            {
                int length = (int)bufferLength;
                if (length + writeOffset > writeContent.Length)
                {
                    length = writeContent.Length - writeOffset;
                }
                byte[] buffer = new byte[length];
                Array.Copy(writeContent, writeOffset, buffer, 0, length);
                smbdAdapter.SmbdWriteRegisteredBuffer(buffer, writeDescp[index]);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Write content to file over RDMA.");
            WRITE_Response writeResponse;
            status = (NtStatus)smbdAdapter.Smb2WriteOverRdmaChannel(
                0,
                channelInfo,
                size,
                out writeResponse
                );
            BaseTestSite.Assert.AreEqual <NtStatus>(
                NtStatus.STATUS_SUCCESS,
                status,
                "Status of SMB2 Write File is {0}", status);
            BaseTestSite.Assert.AreEqual <uint>(
                (uint)size,
                writeResponse.Count,
                "DataLength in WRITE response is {0}", writeResponse.Count);

            #endregion


            #region Read file from server
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 WRITE");
            SmbdBufferDescriptorV1[] readDescp = new SmbdBufferDescriptorV1[bufferCount];
            for (int i = 0; i < bufferCount; ++i)
            {
                smbdAdapter.SmbdRegisterBuffer(
                    bufferLength,
                    SmbdBufferReadWrite.RDMA_WRITE_PERMISSION_FOR_READ_FILE,
                    out readDescp[i]);
                byte[] channelInfoBlock = TypeMarshal.ToBytes <SmbdBufferDescriptorV1>(readDescp[i]);
                Array.Copy(
                    channelInfoBlock,
                    0,
                    channelInfo,
                    SmbdBufferDescriptorV1.SIZE * i,
                    SmbdBufferDescriptorV1.SIZE);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Read content from file over RDMA.");
            READ_Response readResponse;
            byte[]        readData;
            status = (NtStatus)smbdAdapter.Smb2ReadOverRdmaChannel(
                0,
                size,
                channelInfo,
                out readResponse,
                out readData
                );
            BaseTestSite.Assert.AreEqual <NtStatus>(
                NtStatus.STATUS_SUCCESS,
                status,
                "Status of SMB2 Read File is {0}", status);
            BaseTestSite.Assert.AreEqual <uint>(
                0,
                readResponse.DataLength,
                "DataLength in READ response is {0}", readResponse.DataLength);
            BaseTestSite.Assert.AreEqual <int>(
                0,
                readData.Length,
                "Data length of content in response is {0}", readData.Length);
            BaseTestSite.Assert.AreEqual <byte>(
                80,
                readResponse.DataOffset,
                "DataOffset in response is {0}", readResponse.DataOffset);
            BaseTestSite.Assert.AreEqual <uint>(
                size,
                readResponse.DataRemaining,
                "DataRemaining in response is {0}", readResponse.DataRemaining);

            // read content
            for (int index = 0, readOffset = 0;
                 index < bufferCount && readOffset < readContent.Length;
                 ++index, readOffset += (int)bufferLength)
            {
                int length = (int)bufferLength;
                if (length + readOffset > readContent.Length)
                {
                    length = writeContent.Length - readOffset;
                }
                byte[] buffer = new byte[length];
                smbdAdapter.SmbdReadRegisteredBuffer(buffer, readDescp[index]);
                Array.Copy(buffer, 0, readContent, readOffset, length);
            }
            #endregion

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Check the read content is same as the one written into the file.");
            BaseTestSite.Assert.IsTrue(
                SmbdUtilities.CompareByteArray(writeContent, readContent),
                "Check content of file");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Close file.");
            smbdAdapter.Smb2CloseFile();
        }