public static void RequestOplock(OplockLevel_Values oplockType) { // OPLOCK_LEVEL_NONE is only initial state, it's meaningless when requesting an Oplock Condition.IsFalse(oplockType == OplockLevel_Values.OPLOCK_LEVEL_NONE); // OPLOCK_LEVEL_LEASE is used when requesting Lease, so it's not applicable for requesting Oplock Condition.IsFalse(oplockType == OplockLevel_Values.OPLOCK_LEVEL_LEASE); if (OplockState == OplockLevel_Values.OPLOCK_LEVEL_NONE && LeaseState == ModelLeaseStateType.Lease_None) { OplockState = oplockType; } }
public static void OplockBreakAcknowledgementRequest(OplockVolatilePortion volatilePortion, OplockPersistentPortion persistentPortion, OplockLevel_Values oplockLevel) { Combination.Isolated(volatilePortion == OplockVolatilePortion.VolatilePortionNotFound); Combination.Isolated(persistentPortion == OplockPersistentPortion.PersistentNotMatchesDurableFileId); // Isolate the values that are not allowed Combination.Isolated(oplockLevel == OplockLevel_Values.OPLOCK_LEVEL_BATCH); Combination.Isolated(oplockLevel == OplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE); Combination.Isolated(oplockLevel == OplockLevel_Values.OPLOCK_LEVEL_LEASE); Condition.IsTrue(State == ModelState.Connected); Condition.IsNull(Request); bool volatilePortionFound = volatilePortion == OplockVolatilePortion.VolatilePortionFound; bool persistentMatchesDurableFileId = persistentPortion == OplockPersistentPortion.PersistentMatchesDurableFileId; Request = new ModelOplockBreakAcknowledgementRequest(volatilePortionFound, persistentMatchesDurableFileId, oplockLevel); }
public void OplockBreakAcknowledgementRequest(OplockVolatilePortion volatilePortion, OplockPersistentPortion persistentPortion, OplockLevel_Values oplockLevel) { bool volatilePortionFound = volatilePortion == OplockVolatilePortion.VolatilePortionFound; bool persistentMatchesDurableFileId = persistentPortion == OplockPersistentPortion.PersistentMatchesDurableFileId; FILEID fileIdRequest = fileId; if(!volatilePortionFound) { fileIdRequest.Volatile = FILEID.Invalid.Volatile; } if(!persistentMatchesDurableFileId) { fileIdRequest.Persistent = FILEID.Invalid.Persistent; } OPLOCK_BREAK_Response? oplockBreakResponse = null; uint status = testClient.OplockAcknowledgement(treeId, fileIdRequest, (OPLOCK_BREAK_Acknowledgment_OplockLevel_Values)oplockLevel, (header, response) => { oplockBreakResponse = response; }); OplockBreakResponse((ModelSmb2Status)status, oplockBreakResponse.Value.OplockLevel, oplockLevelOnOpen); }
public ModelOplockBreakAcknowledgementRequest(bool volatilePortionFound, bool persistentMatchesDurableFileId, OplockLevel_Values oplockLevel) : base(0) { this.VolatilePortionFound = volatilePortionFound; this.PersistentMatchesDurableFileId = persistentMatchesDurableFileId; this.OplockLevel = oplockLevel; }
/// <summary> /// Reset all member variables before running next test case /// </summary> public override void Reset() { if (oplockClient != null) { oplockClient.Disconnect(); oplockClient = null; } if (leaseClient != null) { leaseClient.Disconnect(); leaseClient = null; } fileName = null; breakType = ModelBreakType.NoBreak; treeIdOplock = 0; treeIdLease = 0; alreadyRequested = false; grantedLeaseState = LeaseStateValues.SMB2_LEASE_NONE; grantedOplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE; base.Reset(); }
/// <summary> /// One client requests an Oplock. /// </summary> /// <param name="oplockLevel">Type of the oplock level</param> public void RequestOplock(OplockLevel_Values oplockLevel) { FILEID fileId; Smb2CreateContextResponse[] responses; oplockClient.Create( treeIdOplock, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out responses, (RequestedOplockLevel_Values)oplockLevel, checker: (header, response) => { grantedOplockLevel = response.OplockLevel; }); HandleResult(); }
public void RequestOplockAndOperateFileRequest( RequestedOplockLevel_Values requestedOplockLevel, OplockFileOperation fileOperation, out OplockLevel_Values grantedOplockLevel, out OplockConfig c) { Smb2CreateContextResponse[] serverCreateContexts; string fileName = "OplockMBT_"+ Guid.NewGuid().ToString(); OplockLevel_Values grantedTmp = OplockLevel_Values.OPLOCK_LEVEL_NONE; testClient.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts, requestedOplockLevel_Values: requestedOplockLevel, checker: (header, response) => { grantedTmp = response.OplockLevel; }); Site.Log.Add(LogEntryKind.Debug, "OplockLevel granted by server: {0}", grantedTmp); grantedOplockLevel = grantedTmp; c = oplockConfig; oplockLevelOnOpen = grantedTmp; fileOperationInvoker = new FileOperationDelegate(FileOperation); fileOperationInvoker.BeginInvoke(fileOperation, fileName, null, null); // Assume that notification will arrive in .5 sec if there's any // Without such sleep, OplockBreakNotification would not be expected by SE Thread.Sleep(500); }
public static void OplockBreakResponse(ModelSmb2Status status, OPLOCK_BREAK_Response_OplockLevel_Values oplockLevel, OplockLevel_Values oplockLevelOnOpen) { Condition.IsTrue(State == ModelState.Connected); Condition.IsNotNull(Request); ModelOplockBreakAcknowledgementRequest oplockBreakAckRequest = ModelHelper.RetrieveOutstandingRequest<ModelOplockBreakAcknowledgementRequest>(ref Request); ModelHelper.Log(LogType.Requirement, "3.3.5.22.1 Processing an Oplock Acknowledgment"); if (!oplockBreakAckRequest.VolatilePortionFound || !oplockBreakAckRequest.PersistentMatchesDurableFileId) { ModelHelper.Log(LogType.Requirement, "Next, the server MUST locate the open on which the client is acknowledging an oplock break by performing a lookup in Session.OpenTable " + "using FileId.Volatile of the request as the lookup key. If no open is found, or if Open.DurableFileId is not equal to FileId.Persistent, " + "the server MUST fail the request with STATUS_FILE_CLOSED. "); ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier); if (!oplockBreakAckRequest.VolatilePortionFound) { ModelHelper.Log(LogType.TestInfo, "Open is not found."); } if (!oplockBreakAckRequest.PersistentMatchesDurableFileId) { ModelHelper.Log(LogType.TestInfo, "Open.DurableFileId is not equal to FileId.Persistent."); } Condition.IsTrue(status == ModelSmb2Status.STATUS_FILE_CLOSED); return; } // We need this to avoid Open.OplockLevel being symbolic which will result case exploration failure Condition.IsTrue(Open.OplockLevel == oplockLevelOnOpen); Condition.IsTrue(oplockLevelOnOpen == OplockLevel_Values.OPLOCK_LEVEL_NONE || oplockLevelOnOpen == OplockLevel_Values.OPLOCK_LEVEL_II || oplockLevelOnOpen == OplockLevel_Values.OPLOCK_LEVEL_BATCH); if (oplockBreakAckRequest.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_LEASE) { ModelHelper.Log(LogType.Requirement, "If the OplockLevel in the acknowledgment is SMB2_OPLOCK_LEVEL_LEASE, the server MUST do the following:"); ModelHelper.Log(LogType.TestInfo, "Open.OplockState is {0}.", Open.OplockState); if (Open.OplockState != OplockState.Breaking) { ModelHelper.Log(LogType.Requirement, "If Open.OplockState is not Breaking, stop processing the acknowledgment, " + "and send an error response with STATUS_INVALID_PARAMETER."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER); return; } else { ModelHelper.Log(LogType.Requirement, "If Open.OplockState is Breaking, complete the oplock break request received from the object store as described in section 3.3.4.6, " + "with a new level SMB2_OPLOCK_LEVEL_NONE in an implementation-specific manner,<350> and set Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE, " + "and Open.OplockState to None."); ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE, and Open.OplockState is set to None"); Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE; Open.OplockState = OplockState.None; // Do not assert implementation-specific manner return; } } if ((Open.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE || Open.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_BATCH) && (oplockBreakAckRequest.OplockLevel != OplockLevel_Values.OPLOCK_LEVEL_II && oplockBreakAckRequest.OplockLevel != OplockLevel_Values.OPLOCK_LEVEL_NONE)) { ModelHelper.Log(LogType.Requirement, "If Open.OplockLevel is SMB2_OPLOCK_LEVEL_EXCLUSIVE or SMB2_OPLOCK_LEVEL_BATCH, " + "and if OplockLevel is not SMB2_OPLOCK_LEVEL_II or SMB2_OPLOCK_LEVEL_NONE, the server MUST do the following:"); ModelHelper.Log(LogType.TestInfo, "Open.OplockState is {0}.", Open.OplockState); if (Open.OplockState != OplockState.Breaking) { ModelHelper.Log(LogType.Requirement, "If Open.OplockState is not Breaking, stop processing the acknowledgment, " + "and send an error response with STATUS_INVALID_OPLOCK_PROTOCOL."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_OPLOCK_PROTOCOL); return; } else { ModelHelper.Log(LogType.Requirement, "If Open.OplockState is Breaking, complete the oplock break request received from the object store, " + "as described in section 3.3.4.6, with a new level SMB2_OPLOCK_LEVEL_NONE in an implementation-specific manner," + "<351> and set Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE and Open.OplockState to None."); ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE, and Open.OplockState is set to None"); Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE; Open.OplockState = OplockState.None; // Do not assert implementation-specific manner return; } } if (Open.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II && oplockBreakAckRequest.OplockLevel != OplockLevel_Values.OPLOCK_LEVEL_NONE) { ModelHelper.Log(LogType.Requirement, "If Open.OplockLevel is SMB2_OPLOCK_LEVEL_II, and if OplockLevel is not SMB2_OPLOCK_LEVEL_NONE, " + "the server MUST do the following:"); ModelHelper.Log(LogType.TestInfo, "Open.OplockState is {0}.", Open.OplockState); if (Open.OplockState != OplockState.Breaking) { ModelHelper.Log(LogType.Requirement, "If Open.OplockState is not Breaking, stop processing the acknowledgment, and send an error response with STATUS_INVALID_OPLOCK_PROTOCOL."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_OPLOCK_PROTOCOL); return; } else { ModelHelper.Log(LogType.Requirement, "If Open.OplockState is Breaking, complete the oplock break request received from the object store, " + "as described in section 3.3.4.6, with a new level SMB2_OPLOCK_LEVEL_NONE in an implementation-specific manner," + "<352> and set Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE and Open.OplockState to None."); ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE, and Open.OplockState is set to None"); Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE; Open.OplockState = OplockState.None; // Do not assert implementation-specific manner return; } } if (oplockBreakAckRequest.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II || oplockBreakAckRequest.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_NONE) { ModelHelper.Log(LogType.Requirement, "If OplockLevel is SMB2_OPLOCK_LEVEL_II or SMB2_OPLOCK_LEVEL_NONE, the server MUST do the following:"); ModelHelper.Log(LogType.TestInfo, "Open.OplockState is {0}.", Open.OplockState); if (Open.OplockState != OplockState.Breaking) { ModelHelper.Log(LogType.Requirement, "If Open.OplockState is not Breaking, stop processing the acknowledgment, " + "and send an error response with STATUS_INVALID_DEVICE_STATE."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_DEVICE_STATE); return; } else { ModelHelper.Log(LogType.Requirement, "If Open.OplockState is Breaking, " + "complete the oplock break request received from the object store as described in section 3.3.4.6, " + "with a new level received in OplockLevel in an implementation-specific manner.<353>"); if (status != ModelSmb2Status.STATUS_SUCCESS) { ModelHelper.Log(LogType.Requirement, "If the object store indicates an error, set the Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE, " + "the Open.OplockState to None, and send the error response with the error code received."); ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE, and Open.OplockState is set to None"); Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE; Open.OplockState = OplockState.None; return; } else { ModelHelper.Log(LogType.Requirement, "If the object store indicates success, update Open.OplockLevel and Open.OplockState as follows:"); if (oplockBreakAckRequest.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II) { ModelHelper.Log(LogType.Requirement, "If OplockLevel is SMB2_OPLOCK_LEVEL_II, " + "set Open.OplockLevel to SMB2_OPLOCK_LEVEL_II and Open.OplockState to Held."); ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to OPLOCK_LEVEL_II, and Open.OplockState is set to None"); Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_II; Open.OplockState = OplockState.Held; } if (oplockBreakAckRequest.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_NONE) { ModelHelper.Log(LogType.Requirement, "If OplockLevel is SMB2_OPLOCK_LEVEL_NONE, " + "set Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE and the Open.OplockState to None."); ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE, and Open.OplockState is set to None"); Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE; Open.OplockState = OplockState.None; } } } } ModelHelper.Log(LogType.Requirement, "The server then MUST construct an oplock break response using the syntax specified in section 2.2.25 with the following value:"); ModelHelper.Log(LogType.Requirement, "OplockLevel MUST be set to Open.OplockLevel."); ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is {0}.", Open.OplockLevel); Condition.IsTrue(Open.OplockLevel == (OplockLevel_Values)oplockLevel); Condition.IsTrue(status == ModelSmb2Status.STATUS_SUCCESS); }
public static void RequestOplockAndOperateFileReturn(OplockLevel_Values grantedOplockLevel, OplockConfig c) { Condition.IsTrue(State == ModelState.Connected); Condition.IsNotNull(Request); ModelRequestOplockAndTriggerBreakRequest requestOplockAndTriggerBreakRequest = ModelHelper.RetrieveOutstandingRequest<ModelRequestOplockAndTriggerBreakRequest>(ref Request); Condition.IsTrue(Config.Platform == c.Platform); if (Share_ForceLevel2Oplock && (requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH || requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE)) { ModelHelper.Log(LogType.Requirement, "3.3.5.9: If TreeConnect.Share.ForceLevel2Oplock is TRUE, " + "and RequestedOplockLevel is SMB2_OPLOCK_LEVEL_BATCH or SMB2_OPLOCK_LEVEL_EXCLUSIVE, " + "the server SHOULD<245> set RequestedOplockLevel to SMB2_OPLOCK_LEVEL_II."); if (Config.Platform != Platform.NonWindows) { ModelHelper.Log(LogType.TestInfo, "The SUT platform is Windows."); Condition.IsTrue(grantedOplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II); // Skip following WBN which is for pre-Win8 // <226> Section 3.3.5.9: Windows Vista and Windows Server 2008 do not support the SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK flag // and ignore the TreeConnect.Share.ForceLevel2Oplock value. } } if (ModelUtility.IsSmb3xFamily(Connection_Dialect) && Share_Type_Include_STYPE_CLUSTER_SOFS && requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH) { ModelHelper.Log(LogType.Requirement, "3.3.5.9: If Connection.Dialect belongs to the SMB 3.x dialect family TreeConnect.Share.Type includes STYPE_CLUSTER_SOFS " + "and the RequestedOplockLevel is SMB2_OPLOCK_LEVEL_BATCH, the server MUST set RequestedOplockLevel to SMB2_OPLOCK_LEVEL_II."); // The Oplock acquisition depends on underlying object store implemention specific // we may not garantee level2 would be always granted // Only assert it's not batch ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); Condition.IsTrue(grantedOplockLevel != OplockLevel_Values.OPLOCK_LEVEL_BATCH); } Open = new ModelOplockOpen(); ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE."); Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE; ModelHelper.Log(LogType.TestInfo, "Open.OplockState is set to None."); Open.OplockState = OplockState.None; // Acquire Oplock from underlying object // If the underlying object store grants the oplock, // then Open.OplockState is set to Held and Open.OplockLevel is set to the level of the oplock acquired. if (grantedOplockLevel != OplockLevel_Values.OPLOCK_LEVEL_NONE) { ModelHelper.Log(LogType.TestInfo, "Open.OplockState is set to Held."); Open.OplockState = OplockState.Held; Open.OplockLevel = grantedOplockLevel; } }
public Smb2CreateResponsePacket CreateCreateResponseAsync( Smb2Endpoint endpoint, ulong asyncId, ulong messageId, OplockLevel_Values oplockLevel, CreateAction_Values createAction, _FILETIME creationTime, _FILETIME lastAccessTime, _FILETIME lastWriteTime, _FILETIME changeTime, ulong allocationSize, ulong endofFile, File_Attributes fileAttributes, FILEID fileId, params CREATE_CONTEXT_Values[] contexts ) { Smb2CreateResponsePacket packet = CreateCreateResponse(endpoint, messageId, oplockLevel, createAction, creationTime, lastAccessTime, lastWriteTime, changeTime, allocationSize, endofFile, fileAttributes, fileId, contexts); ModifyAsyncHeader(packet, endpoint, asyncId); packet.Sign(); return packet; }
public Smb2CreateResponsePacket CreateCreateResponse( Smb2Endpoint endpoint, ulong messageId, OplockLevel_Values oplockLevel, CreateAction_Values createAction, _FILETIME creationTime, _FILETIME lastAccessTime, _FILETIME lastWriteTime, _FILETIME changeTime, ulong allocationSize, ulong endofFile, File_Attributes fileAttributes, FILEID fileId, params CREATE_CONTEXT_Values[] createContexts ) { Smb2CreateResponsePacket packet = new Smb2CreateResponsePacket(); SetHeader(packet, endpoint, messageId); packet.PayLoad.StructureSize = CREATE_Response_StructureSize_Values.V1; packet.PayLoad.OplockLevel = oplockLevel; packet.PayLoad.Reserved = 0; packet.PayLoad.CreateAction = createAction; packet.PayLoad.CreationTime = creationTime; packet.PayLoad.LastAccessTime = lastAccessTime; packet.PayLoad.LastWriteTime = lastWriteTime; packet.PayLoad.ChangeTime = changeTime; packet.PayLoad.AllocationSize = allocationSize; packet.PayLoad.EndofFile = endofFile; packet.PayLoad.FileAttributes = fileAttributes; packet.PayLoad.Reserved2 = 0; packet.PayLoad.FileId = fileId; if (createContexts == null) { packet.PayLoad.CreateContextsOffset = 0; packet.PayLoad.CreateContextsLength = 0; packet.PayLoad.Buffer = new byte[0]; } else { packet.PayLoad.CreateContextsOffset = Smb2Consts.CreateContextOffsetInCreateResponse; using (MemoryStream ms = new MemoryStream()) { for (int i = 0; i < createContexts.Length; i++) { byte[] createContext = TypeMarshal.ToBytes(createContexts[i]); if (i != (createContexts.Length - 1)) { int alignedLen = Smb2Utility.AlignBy8Bytes(createContext.Length); byte[] nextValue = BitConverter.GetBytes(alignedLen); Array.Copy(nextValue, createContext, nextValue.Length); ms.Write(createContext, 0, createContext.Length); //write the padding 0; for (int j = 0; j < (alignedLen - createContext.Length); j++) { ms.WriteByte(0); } } else { ms.Write(createContext, 0, createContext.Length); } } packet.PayLoad.Buffer = ms.ToArray(); packet.PayLoad.CreateContextsLength = (uint)packet.PayLoad.Buffer.Length; } } packet.Sign(); return packet; }
public static void Verification(ModelBreakType breakType, OplockLevel_Values grantedOplockType, ModelLeaseStateType grantedLeaseType) { PrintMatrixAndState(); // 1st Client(Oplock) 2nd Client(Lease) OplockBreakExist GrantedLeaseState // ================================================================================ // OPLOCK_LEVEL_II Any Lease No Lease_R // OPLOCK_LEVEL_EXCLUSIVE Any Lease Yes Lease_R // OPLOCK_LEVEL_BATCH Any Lease Yes Lease_R switch (OplockState) { // The first request is not for Oplock case OplockLevel_Values.OPLOCK_LEVEL_NONE: break; case OplockLevel_Values.OPLOCK_LEVEL_II: Condition.IsTrue(breakType == ModelBreakType.NoBreak); Condition.IsTrue(grantedLeaseType == ModelLeaseStateType.Lease_R); break; case OplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE: case OplockLevel_Values.OPLOCK_LEVEL_BATCH: Condition.IsTrue(breakType == ModelBreakType.OplockBreak); Condition.IsTrue(grantedLeaseType == ModelLeaseStateType.Lease_R); break; default: break; } // 1st Client(Lease) 2nd Client(Oplock) LeaseBreakExist GrantedOplockLevel // ================================================================================ // Lease_R Any Oplock No OPLOCK_LEVEL_II // Lease_RH Any Oplock No OPLOCK_LEVEL_NONE // Lease_RW Any Oplock Yes OPLOCK_LEVEL_II // Lease_RWH Any Oplock Yes OPLOCK_LEVEL_NONE switch (LeaseState) { // The first request is not for Lease case ModelLeaseStateType.Lease_None: break; case ModelLeaseStateType.Lease_R: Condition.IsTrue(breakType == ModelBreakType.NoBreak); Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_II); break; case ModelLeaseStateType.Lease_RH: Condition.IsTrue(breakType == ModelBreakType.NoBreak); Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_NONE); break; case ModelLeaseStateType.Lease_RW: Condition.IsTrue(breakType == ModelBreakType.LeaseBreak); Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_II); break; case ModelLeaseStateType.Lease_RWH: Condition.IsTrue(breakType == ModelBreakType.LeaseBreak); Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_NONE); break; default: break; } }
public static void RequestOplockAndOperateFileReturn(OplockLevel_Values grantedOplockLevel, OplockConfig c) { Condition.IsTrue(State == ModelState.Connected); Condition.IsNotNull(Request); ModelRequestOplockAndTriggerBreakRequest requestOplockAndTriggerBreakRequest = ModelHelper.RetrieveOutstandingRequest <ModelRequestOplockAndTriggerBreakRequest>(ref Request); Condition.IsTrue(Config.Platform == c.Platform); if (Share_ForceLevel2Oplock && (requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH || requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE)) { ModelHelper.Log(LogType.Requirement, "3.3.5.9: If TreeConnect.Share.ForceLevel2Oplock is TRUE, " + "and RequestedOplockLevel is SMB2_OPLOCK_LEVEL_BATCH or SMB2_OPLOCK_LEVEL_EXCLUSIVE, " + "the server SHOULD<245> set RequestedOplockLevel to SMB2_OPLOCK_LEVEL_II."); if (Config.Platform != Platform.NonWindows) { ModelHelper.Log(LogType.TestInfo, "The SUT platform is Windows."); Condition.IsTrue(grantedOplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II); // Skip following WBN which is for pre-Win8 // <226> Section 3.3.5.9: Windows Vista and Windows Server 2008 do not support the SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK flag // and ignore the TreeConnect.Share.ForceLevel2Oplock value. } } if (ModelUtility.IsSmb3xFamily(Connection_Dialect) && Share_Type_Include_STYPE_CLUSTER_SOFS && requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH) { ModelHelper.Log(LogType.Requirement, "3.3.5.9: If Connection.Dialect belongs to the SMB 3.x dialect family TreeConnect.Share.Type includes STYPE_CLUSTER_SOFS " + "and the RequestedOplockLevel is SMB2_OPLOCK_LEVEL_BATCH, the server MUST set RequestedOplockLevel to SMB2_OPLOCK_LEVEL_II."); // The Oplock acquisition depends on underlying object store implemention specific // we may not garantee level2 would be always granted // Only assert it's not batch ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); Condition.IsTrue(grantedOplockLevel != OplockLevel_Values.OPLOCK_LEVEL_BATCH); } Open = new ModelOplockOpen(); ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE."); Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE; ModelHelper.Log(LogType.TestInfo, "Open.OplockState is set to None."); Open.OplockState = OplockState.None; // Acquire Oplock from underlying object // If the underlying object store grants the oplock, // then Open.OplockState is set to Held and Open.OplockLevel is set to the level of the oplock acquired. if (grantedOplockLevel != OplockLevel_Values.OPLOCK_LEVEL_NONE) { ModelHelper.Log(LogType.TestInfo, "Open.OplockState is set to Held."); Open.OplockState = OplockState.Held; Open.OplockLevel = grantedOplockLevel; } }