public void Smb2OverRdma_Smb300_Write_SMB2_CHANNEL_RDMA_V1_INVALIDATE() { EstablishConnectionAndOpenFile(fileName, Smb300OnlyDialects); uint writeSize = smbdAdapter.Smb2MaxWriteSize; byte[] fileContent = Smb2Utility.CreateRandomByteArray((int)writeSize); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 WRITE"); SmbdBufferDescriptorV1 descp; NtStatus status = smbdAdapter.SmbdRegisterBuffer( writeSize, SmbdBufferReadWrite.RDMA_READ_PERMISSION_FOR_WRITE_FILE, out descp); BaseTestSite.Assert.AreEqual( NtStatus.STATUS_SUCCESS, status, "Register buffer should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Write content to file over RDMA."); status = Smb2WriteOverRdma(fileName, fileContent, Channel_Values.CHANNEL_RDMA_V1_INVALIDATE, descp); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_INVALID_PARAMETER, status, "SMB2 WRITE over RDMA should fail with STATUS_INVALID_PARAMETER if set Channel CHANNEL_RDMA_V1_INVALIDATE on SMB 3.0 dialect."); }
private bool CheckSMBDReadWrite(DialectRevision[] dialects, Channel_Values channel) { try { using (var client = new SMBDClient(DetectionInfo.ConnectionTimeout)) { var config = DetectionInfo.SMBDClientCapability; RdmaAdapterInfo rdmaAdapterInfo; client.ConnectOverRDMA(DetectionInfo.DriverRdmaNICIPAddress, DetectionInfo.SUTRdmaNICIPAddress, DetectionInfo.SMBDPort, config.MaxReceiveSize, out rdmaAdapterInfo); client.SMBDNegotiate( config.CreditsRequested, config.ReceiveCreditMax, config.PreferredSendSize, config.MaxReceiveSize, config.MaxFragmentedSize ); client.Smb2Negotiate(dialects); client.Smb2SessionSetup(DetectionInfo.Authentication, DetectionInfo.DomainName, DetectionInfo.SUTName, DetectionInfo.UserName, DetectionInfo.Password); string path = Smb2Utility.GetUncPath(DetectionInfo.SUTName, DetectionInfo.ShareFolder); uint treeId; client.Smb2TreeConnect(path, out treeId); FILEID fileId; client.CreateRandomFile(treeId, out fileId); uint length = client.CalculateSMBDMaxReadWriteSize(); var buffer = Smb2Utility.CreateRandomByteArray((int)length); client.SMBDWrite(treeId, fileId, channel, buffer, 0, DetectionInfo.Endian); var readBuffer = new byte[length]; client.SMBDRead(treeId, fileId, channel, out readBuffer, 0, length, DetectionInfo.Endian); if (!Enumerable.SequenceEqual(buffer, readBuffer)) { throw new InvalidOperationException("The data is inconsistent for write and read!"); } return(true); } } catch (Exception ex) { DetectorUtil.WriteLog(String.Format("CheckSMBDReadWrite threw exception: {0}", ex)); return(false); } }
public void Smb2OverRdma_Smb300_Read_SMB2_CHANNEL_RDMA_V1_INVALIDATE() { EstablishConnectionAndOpenFile(fileName, Smb300OnlyDialects); uint fileSize = smbdAdapter.Smb2MaxReadSize; byte[] fileContent = Smb2Utility.CreateRandomByteArray((int)fileSize); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 WRITE"); SmbdBufferDescriptorV1 descp; NtStatus status = smbdAdapter.SmbdRegisterBuffer( fileSize, SmbdBufferReadWrite.RDMA_READ_PERMISSION_FOR_WRITE_FILE, out descp); BaseTestSite.Assert.AreEqual( NtStatus.STATUS_SUCCESS, status, "Register buffer should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Write content to file over RDMA."); status = Smb2WriteOverRdma(fileName, fileContent, Channel_Values.CHANNEL_RDMA_V1, descp); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "SMB2 WRITE over RDMA should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 READ."); smbdAdapter.SmbdRegisterBuffer( fileSize, SmbdBufferReadWrite.RDMA_WRITE_PERMISSION_FOR_READ_FILE, out descp); byte[] channelInfo = TypeMarshal.ToBytes <SmbdBufferDescriptorV1>(descp); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Read content from file over RDMA."); READ_Response readResponse; byte[] readData; status = (NtStatus)smbdAdapter.Smb2ReadOverRdmaChannel( 0, (uint)fileSize, channelInfo, out readResponse, out readData, Channel_Values.CHANNEL_RDMA_V1_INVALIDATE); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_INVALID_PARAMETER, status, "SMB2 READ over RDMA should fail with STATUS_INVALID_PARAMETER if set Channel CHANNEL_RDMA_V1_INVALIDATE on SMB 3.0 dialect."); }
public bool ConnectToShare(string serverIp, string clientIp) { try { using (var client = new SMBDClient(DetectionInfo.ConnectionTimeout)) { client.Connect(IPAddress.Parse(serverIp), IPAddress.Parse(clientIp)); client.Smb2Negotiate(DetectionInfo.SupportedSmbDialects); client.Smb2SessionSetup(DetectionInfo.Authentication, DetectionInfo.DomainName, DetectionInfo.SUTName, DetectionInfo.UserName, DetectionInfo.Password); string path = Smb2Utility.GetUncPath(DetectionInfo.SUTName, DetectionInfo.ShareFolder); uint treeId; client.Smb2TreeConnect(path, out treeId); FILEID fileId; client.CreateRandomFile(treeId, out fileId); uint fileLength = client.CalculateSmb2MaxReadWriteSize(); var buffer = Smb2Utility.CreateRandomByteArray((int)fileLength); client.Smb2Write(treeId, fileId, 0, buffer); byte[] output; client.Smb2Read(treeId, fileId, 0, fileLength, out output); bool result = Enumerable.SequenceEqual(buffer, output); if (!result) { DetectorUtil.WriteLog("The content of read and write is inconsistent."); } return(result); } } catch (Exception ex) { DetectorUtil.WriteLog(String.Format("ConnectToShare threw exception: {0}", ex)); return(false); } }
public void BVT_Smb2OverRdma_Smb302_Write_SMB2_CHANNEL_RDMA_V1_INVALIDATE() { EstablishConnectionAndOpenFile(fileName, Smb302AboveDialects); uint writeSize = smbdAdapter.Smb2MaxWriteSize; byte[] fileContent = Smb2Utility.CreateRandomByteArray((int)writeSize); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 WRITE"); SmbdBufferDescriptorV1 descp; NtStatus status = smbdAdapter.SmbdRegisterBuffer( writeSize, SmbdBufferReadWrite.RDMA_READ_PERMISSION_FOR_WRITE_FILE, out descp); BaseTestSite.Assert.AreEqual( NtStatus.STATUS_SUCCESS, status, "Register buffer should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Write content to file over RDMA."); status = Smb2WriteOverRdma(fileName, fileContent, Channel_Values.CHANNEL_RDMA_V1_INVALIDATE, descp); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "SMB2 WRITE over RDMA should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify file content."); ValidateFileContent(fileContent); try { fileContent = Encoding.ASCII.GetBytes(Smb2Utility.CreateRandomStringInByte((int)writeSize)); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send Smb2 WRITE request using same descriptor which should be invalidated."); status = Smb2WriteOverRdma(fileName, fileContent, Channel_Values.CHANNEL_RDMA_V1_INVALIDATE, descp); } catch { BaseTestSite.Log.Add(LogEntryKind.Debug, "Verify connection is terminated ."); smbdAdapter.WaitRdmaDisconnect(); } BaseTestSite.Assert.IsFalse(smbdAdapter.ClientConnection.Endpoint.IsConnected, "Connection should be terminated when accessing a memory window which is already invalidated."); }
public void Smb2OverRdma_Write_SMB2_CHANNEL_RDMA_V1() { EstablishConnectionAndOpenFile(fileName); uint writeSize = smbdAdapter.Smb2MaxWriteSize; byte[] fileContent = Smb2Utility.CreateRandomByteArray((int)writeSize); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 WRITE"); SmbdBufferDescriptorV1 descp; NtStatus status = smbdAdapter.SmbdRegisterBuffer( writeSize, SmbdBufferReadWrite.RDMA_READ_PERMISSION_FOR_WRITE_FILE, out descp); BaseTestSite.Assert.AreEqual( NtStatus.STATUS_SUCCESS, status, "Register buffer should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Write content to file over RDMA."); status = Smb2WriteOverRdma(fileName, fileContent, Channel_Values.CHANNEL_RDMA_V1, descp); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "SMB2 WRITE over RDMA should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify file content."); ValidateFileContent(fileContent); fileContent = Encoding.ASCII.GetBytes(Smb2Utility.CreateRandomStringInByte((int)writeSize)); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send Smb2 WRITE request using same descriptor."); status = Smb2WriteOverRdma(fileName, fileContent, Channel_Values.CHANNEL_RDMA_V1, descp); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "SMB2 WRITE over RDMA should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify file content."); ValidateFileContent(fileContent); }
private Smb2WriteRequestPacket ConstructRelatedWritePacket() { var writePacket = new Smb2WriteRequestPacket(); writePacket.Header.Command = Smb2Command.WRITE; // For any subsequent requests the client MUST set SMB2_FLAGS_RELATED_OPERATIONS in the Flags field of the SMB2 header to indicate that // it is using the SessionId, TreeId, and FileId supplied in the previous request (or generated by the server in processing that request). // The client SHOULD<93> set SessionId to 0xFFFFFFFFFFFFFFFF and TreeId to 0xFFFFFFFF, // and SHOULD<94> set FileId to { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }. writePacket.Header.Flags = Packet_Header_Flags_Values.FLAGS_RELATED_OPERATIONS; writePacket.Header.SessionId = 0xFFFFFFFFFFFFFFFF; writePacket.Header.TreeId = 0xFFFFFFFF; byte[] content = Smb2Utility.CreateRandomByteArray(1); // Write 1 byte to the file. writePacket.PayLoad.Length = (uint)content.Length; writePacket.PayLoad.Offset = 0; writePacket.PayLoad.FileId = FILEID.Invalid; writePacket.PayLoad.DataOffset = (ushort)writePacket.BufferOffset; writePacket.Buffer = content; return(writePacket); }
private Smb2WriteRequestPacket ConstructRelatedWritePacket(ulong sessionId, uint treeId) { var writePacket = new Smb2WriteRequestPacket(); writePacket.Header.Command = Smb2Command.WRITE; // The client MUST construct the subsequent request as it would do normally. // For any subsequent requests the client MUST set SMB2_FLAGS_RELATED_OPERATIONS in the Flags field of the SMB2 header to indicate that it is using the SessionId, // TreeId, and FileId supplied in the previous request(or generated by the server in processing that request). // For an operation compounded with an SMB2 CREATE request, the FileId field SHOULD be set to { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }. writePacket.Header.Flags = Packet_Header_Flags_Values.FLAGS_RELATED_OPERATIONS; writePacket.Header.SessionId = sessionId; writePacket.Header.TreeId = treeId; byte[] content = Smb2Utility.CreateRandomByteArray(1); // Write 1 byte to the file. writePacket.PayLoad.Length = (uint)content.Length; writePacket.PayLoad.Offset = 0; writePacket.PayLoad.FileId = FILEID.Invalid; writePacket.PayLoad.DataOffset = (ushort)writePacket.BufferOffset; writePacket.Buffer = content; return(writePacket); }
public void BVT_ChangeTracking() { // The log file used in change tracking request must be an existing file. // So create one file before running the case. string logFileName = string.Format("log_{0}.txt", System.Guid.NewGuid()); sutProtocolController.CreateFile(TestConfig.FullPathShareContainingSharedVHD, logFileName, ""); BaseTestSite.Log.Add(LogEntryKind.TestStep, "1. Client opens a shared virtual disk file and expects success."); OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2); BaseTestSite.Log.Add(LogEntryKind.TestStep, "2. Client sends the tunnel operation SVHDX_CHANGE_TRACKING_START_REQUEST to start change tracking."); SVHDX_CHANGE_TRACKING_START_REQUEST request = new SVHDX_CHANGE_TRACKING_START_REQUEST(); request.TransactionId = System.Guid.NewGuid(); request.LogFileId = System.Guid.NewGuid(); request.LogFileNameOffset = 56; request.LogFileName = logFileName; request.LogFileNameLength = (uint)(request.LogFileName.Length + 1) * 2; byte[] payload = client.CreateChangeTrackingStartRequest(request); SVHDX_TUNNEL_OPERATION_HEADER?header; SVHDX_TUNNEL_OPERATION_HEADER?response; //For RSVD_TUNNEL_META_OPERATION_START operation code, the IOCTL code should be FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST uint status = client.TunnelOperation <SVHDX_TUNNEL_OPERATION_HEADER>( false,//true for Async operation, false for non-async operation RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_CHANGE_TRACKING_START, ++RequestIdentifier, payload, out header, out response); BaseTestSite.Assert.AreEqual( (uint)Smb2Status.STATUS_SUCCESS, status, "Ioctl should succeed, actual status: {0}", GetStatus(status)); VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_CHANGE_TRACKING_START, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, RequestIdentifier); BaseTestSite.Log.Add(LogEntryKind.TestStep, "3. Client sends Write request to change the vhds file."); payload = Smb2Utility.CreateRandomByteArray(512); status = client.Write(0, payload); BaseTestSite.Log.Add(LogEntryKind.TestStep, "4. Client sends the tunnel operation RSVD_TUNNEL_CHANGE_TRACKING_GET_PARAMETERS to get the change tracking status."); SVHDX_CHANGE_TRACKING_GET_PARAMETERS_RESPONSE?getParamResponse; status = client.TunnelOperation <SVHDX_CHANGE_TRACKING_GET_PARAMETERS_RESPONSE>( false,//true for Async operation, false for non-async operation RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_CHANGE_TRACKING_GET_PARAMETERS, ++RequestIdentifier, null, out header, out getParamResponse); VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_CHANGE_TRACKING_GET_PARAMETERS, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, RequestIdentifier); BaseTestSite.Assert.AreEqual( RsvdStatus.STATUS_SVHDX_SUCCESS, (RsvdStatus)getParamResponse.Value.ChangeTrackingStatus, "Status of change tracking should be STATUS_SVHDX_SUCCESS."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "5. Client sends the tunnel operation SVHDX_CHANGE_TRACKING_STOP_REQUEST to stop change tracking."); status = client.TunnelOperation <SVHDX_TUNNEL_OPERATION_HEADER>( false,//true for Async operation, false for non-async operation RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_CHANGE_TRACKING_STOP, ++RequestIdentifier, null, out header, out response); VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_CHANGE_TRACKING_STOP, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, RequestIdentifier); BaseTestSite.Log.Add(LogEntryKind.TestStep, "6. Client closes the file."); client.CloseSharedVirtualDisk(); }
public void Smb2OverRdma_Read_SMB2_CHANNEL_RDMA_V1() { EstablishConnectionAndOpenFile(fileName); uint fileSize = smbdAdapter.Smb2MaxReadSize; byte[] fileContent = Smb2Utility.CreateRandomByteArray((int)fileSize); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 WRITE"); SmbdBufferDescriptorV1 descp; NtStatus status = smbdAdapter.SmbdRegisterBuffer( fileSize, SmbdBufferReadWrite.RDMA_READ_PERMISSION_FOR_WRITE_FILE, out descp); BaseTestSite.Assert.AreEqual( NtStatus.STATUS_SUCCESS, status, "Register buffer should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Write content to file over RDMA."); status = Smb2WriteOverRdma(fileName, fileContent, Channel_Values.CHANNEL_RDMA_V1_INVALIDATE, descp); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "SMB2 WRITE over RDMA should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 READ."); status = smbdAdapter.SmbdRegisterBuffer( fileSize, SmbdBufferReadWrite.RDMA_WRITE_PERMISSION_FOR_READ_FILE, out descp); BaseTestSite.Assert.AreEqual( NtStatus.STATUS_SUCCESS, status, "Register buffer should succeed."); byte[] channelInfo = TypeMarshal.ToBytes <SmbdBufferDescriptorV1>(descp); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Read content from file over RDMA."); READ_Response readResponse; byte[] readData; status = (NtStatus)smbdAdapter.Smb2ReadOverRdmaChannel( 0, (uint)fileSize, channelInfo, out readResponse, out readData, Channel_Values.CHANNEL_RDMA_V1); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "SMB2 READ over RDMA should succeed."); byte[] readContent = new byte[fileSize]; smbdAdapter.SmbdReadRegisteredBuffer(readContent, descp); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify the read content same as the original one on server."); BaseTestSite.Assert.IsTrue( SmbdUtilities.CompareByteArray(fileContent, readContent), "Content read should be identical with original on server."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send SMB2 READ using same descriptor."); status = (NtStatus)smbdAdapter.Smb2ReadOverRdmaChannel( 0, (uint)fileSize, channelInfo, out readResponse, out readData, Channel_Values.CHANNEL_RDMA_V1); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "SMB2 READ over RDMA should succeed."); smbdAdapter.SmbdReadRegisteredBuffer(readContent, descp); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify the read content same as the original one on server."); BaseTestSite.Assert.IsTrue( SmbdUtilities.CompareByteArray(fileContent, readContent), "Content read should be identical with original on server."); }
public void BVT_Smb2OverRdma_Smb302_Read_SMB2_CHANNEL_RDMA_V1_INVALIDATE() { EstablishConnectionAndOpenFile(fileName, Smb302AboveDialects); uint fileSize = smbdAdapter.Smb2MaxReadSize; byte[] fileContent = Smb2Utility.CreateRandomByteArray((int)fileSize); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 WRITE"); SmbdBufferDescriptorV1 descp; NtStatus status = smbdAdapter.SmbdRegisterBuffer( fileSize, SmbdBufferReadWrite.RDMA_READ_PERMISSION_FOR_WRITE_FILE, out descp); BaseTestSite.Assert.AreEqual( NtStatus.STATUS_SUCCESS, status, "Register buffer should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Write content to file over RDMA."); status = Smb2WriteOverRdma(fileName, fileContent, Channel_Values.CHANNEL_RDMA_V1_INVALIDATE, descp); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "SMB2 WRITE over RDMA should succeed."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 READ."); status = smbdAdapter.SmbdRegisterBuffer( fileSize, SmbdBufferReadWrite.RDMA_WRITE_PERMISSION_FOR_READ_FILE, out descp); BaseTestSite.Assert.AreEqual( NtStatus.STATUS_SUCCESS, status, "Register buffer should succeed."); byte[] channelInfo = TypeMarshal.ToBytes <SmbdBufferDescriptorV1>(descp); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Read content from file over RDMA."); READ_Response readResponse; byte[] readData; status = (NtStatus)smbdAdapter.Smb2ReadOverRdmaChannel( 0, (uint)fileSize, channelInfo, out readResponse, out readData, Channel_Values.CHANNEL_RDMA_V1_INVALIDATE); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "SMB2 READ over RDMA should succeed."); byte[] readContent = new byte[fileSize]; smbdAdapter.SmbdReadRegisteredBuffer(readContent, descp); BaseTestSite.Assert.IsTrue( SmbdUtilities.CompareByteArray(fileContent, readContent), "Content read should be identical with original on server."); try { status = (NtStatus)smbdAdapter.Smb2ReadOverRdmaChannel( 0, (uint)fileSize, channelInfo, out readResponse, out readData, Channel_Values.CHANNEL_RDMA_V1_INVALIDATE); } catch { BaseTestSite.Log.Add(LogEntryKind.Debug, "Wait for connection to be terminated "); smbdAdapter.WaitRdmaDisconnect(); } BaseTestSite.Assert.IsFalse(smbdAdapter.ClientConnection.Endpoint.IsConnected, "Connection should be terminated when accessing a memory window which is already invalidated."); }
public void BVT_QueryVirtualDiskChanges() { BaseTestSite.Log.Add(LogEntryKind.TestStep, "1. Client opens a shared virtual disk file and expects success."); OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2); Guid snapshotId = Guid.NewGuid(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "2. Client sends the first tunnel operation SVHDX_META_OPERATION_START_REQUEST to create a snapshot."); CreateSnapshot(snapshotId); BaseTestSite.Log.Add(LogEntryKind.TestStep, "3. Client closes the open."); client.CloseSharedVirtualDisk(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "4. Client reopens the shared virtual disk file and expects success."); RequestIdentifier = 0; OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2); BaseTestSite.Log.Add(LogEntryKind.TestStep, "5. Client sends Write request and expects success."); byte[] payload = Smb2Utility.CreateRandomByteArray(512); uint status = client.Write(0, payload); BaseTestSite.Assert.AreEqual( (uint)0, status, "Write Status should be {0}, actual is {1}", GetStatus(0), GetStatus(status)); BaseTestSite.Log.Add(LogEntryKind.TestStep, "6. Client creates another snapshot."); Guid snapshotId2 = Guid.NewGuid(); CreateSnapshot(snapshotId2); BaseTestSite.Log.Add(LogEntryKind.TestStep, "7. Client sends the tunnel operation SVHDX_TUNNEL_QUERY_VIRTUAL_DISK_CHANGES_REQUEST to query the changes since the first snapshot."); SVHDX_TUNNEL_QUERY_VIRTUAL_DISK_CHANGES_REQUEST queryRequest = new SVHDX_TUNNEL_QUERY_VIRTUAL_DISK_CHANGES_REQUEST(); queryRequest.TargetSnapshotId = snapshotId2; queryRequest.LimitSnapshotId = snapshotId; queryRequest.SnapshotType = Snapshot_Type.SvhdxSnapshotTypeVM; queryRequest.ByteOffset = 0; queryRequest.ByteLength = 1024; SVHDX_TUNNEL_OPERATION_HEADER?header; SVHDX_TUNNEL_QUERY_VIRTUAL_DISK_CHANGES_REPLY?response; //For RSVD_TUNNEL_META_OPERATION_START operation code, the IOCTL code should be FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST status = client.TunnelOperation <SVHDX_TUNNEL_QUERY_VIRTUAL_DISK_CHANGES_REPLY>( false,//true for Async operation, false for non-async operation RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_QUERY_VIRTUAL_DISK_CHANGES, ++RequestIdentifier, client.CreateQueryVirtualDiskChangeRequest(queryRequest), out header, out response); VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_QUERY_VIRTUAL_DISK_CHANGES, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, RequestIdentifier); BaseTestSite.Assert.AreEqual((uint)1, response.Value.RangeCount, "RangeCount should be 1"); BaseTestSite.Assert.AreEqual((ulong)0, response.Value.Ranges[0].ByteOffset, "ByteOffset should be 0"); BaseTestSite.Log.Add(LogEntryKind.TestStep, "8. Client deletes the two snapshots."); DeleteSnapshot(snapshotId); DeleteSnapshot(snapshotId2); BaseTestSite.Log.Add(LogEntryKind.TestStep, "9. Client closes the file."); client.CloseSharedVirtualDisk(); }
public void BVT_ApplySnapshot() { BaseTestSite.Log.Add(LogEntryKind.TestStep, "1. Client opens a shared virtual disk file and expects success."); OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2); BaseTestSite.Log.Add(LogEntryKind.TestStep, "2. Client reads 512 bytes and saves it for later comparation."); byte[] byteBeforeChanged = null; uint status = client.Read(0, 512, out byteBeforeChanged); BaseTestSite.Assert.AreEqual( (uint)0, status, "Read Status should be {0}, actual is {1}", GetStatus(0), GetStatus(status)); Guid snapshotId = Guid.NewGuid(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "3. Client creates a snapshot."); CreateSnapshot(snapshotId); BaseTestSite.Log.Add(LogEntryKind.TestStep, "4. Client closes the file."); client.CloseSharedVirtualDisk(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "5. Client reopens the shared virtual disk file and expects success."); RequestIdentifier = 0; OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2); BaseTestSite.Log.Add(LogEntryKind.TestStep, "6. Client sends Write request to change the file and expects success."); byte[] payload = Smb2Utility.CreateRandomByteArray(512); status = client.Write(0, payload); BaseTestSite.Assert.AreEqual( (uint)0, status, "Write Status should be {0}, actual is {1}", GetStatus(0), GetStatus(status)); BaseTestSite.Log.Add(LogEntryKind.TestStep, "7. Client sends Apply Snapshot request to apply the previous snapshot."); SVHDX_APPLY_SNAPSHOT_PARAMS applySnapshot = new SVHDX_APPLY_SNAPSHOT_PARAMS(); applySnapshot.SnapshotID = snapshotId; applySnapshot.SnapshotType = Snapshot_Type.SvhdxSnapshotTypeVM; SVHDX_META_OPERATION_START_REQUEST startRequest = new SVHDX_META_OPERATION_START_REQUEST(); startRequest.TransactionId = Guid.NewGuid(); startRequest.OperationType = Operation_Type.SvhdxMetaOperationTypeApplySnapshot; payload = client.CreateTunnelMetaOperationStartApplySnapshotRequest(startRequest, applySnapshot); SVHDX_TUNNEL_OPERATION_HEADER?header; SVHDX_TUNNEL_OPERATION_HEADER?response; status = client.TunnelOperation <SVHDX_TUNNEL_OPERATION_HEADER>( true, //true for Async operation, false for non-async operation RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START, ++RequestIdentifier, payload, out header, out response); BaseTestSite.Assert.AreEqual( (uint)Smb2Status.STATUS_SUCCESS, status, "Ioctl should succeed, actual status: {0}", GetStatus(status)); VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, RequestIdentifier); BaseTestSite.Log.Add(LogEntryKind.TestStep, "8. Client rereads 512 bytes and compares it with the previously saved bytes."); byte[] byteAfterApplied = null; status = client.Read(0, 512, out byteAfterApplied); BaseTestSite.Assert.AreEqual( (uint)0, status, "Read Status should be {0}, actual is {1}", GetStatus(0), GetStatus(status)); bool equal = ArrayUtility.CompareArrays(byteBeforeChanged, byteAfterApplied); BaseTestSite.Assert.AreEqual( true, equal, "The bytes after snapshot applied should be the same with the original."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "9. Client deletes the snapshot."); DeleteSnapshot(snapshotId); BaseTestSite.Log.Add(LogEntryKind.TestStep, "10. Client closes the file."); client.CloseSharedVirtualDisk(); }