/// <inheritdoc/> internal override bool GetNextOperation(IEnumerable <ControlledOperation> ops, ControlledOperation current, bool isYielding, out ControlledOperation next) { try { if (this.StepCount >= this.ScheduleTrace.Count) { this.ErrorText = this.FormatError("execution is longer than trace"); throw new InvalidOperationException(this.ErrorText); } ScheduleStep nextStep = this.ScheduleTrace[this.StepCount]; if (nextStep.Type != ScheduleStepType.SchedulingChoice) { this.ErrorText = this.FormatError("next step is not a scheduling choice"); throw new InvalidOperationException(this.ErrorText); } next = ops.FirstOrDefault(op => op.Id == nextStep.ScheduledOperationId); if (next is null) { this.ErrorText = this.FormatError($"cannot detect id '{nextStep.ScheduledOperationId}'"); throw new InvalidOperationException(this.ErrorText); } } catch (InvalidOperationException ex) { Error.Report(ex.Message); next = null; return(false); } this.StepCount++; return(true); }
/// <summary> /// Returns the next integer choice. /// </summary> /// <param name="maxValue">Max value</param> /// <param name="next">Next</param> /// <returns>Boolean</returns> public override bool GetNextIntegerChoice(int maxValue, out int next) { CaptureAndCheckProgramState(); if (IsReplayingCycle) { ScheduleStep nextStep = PotentialCycle[CurrentCycleIndex]; if (nextStep.Type != ScheduleStepType.NondeterministicChoice || nextStep.IntegerChoice == null) { Debug.WriteLine("<LivenessDebug> Trace is not reproducible: next step is not a nondeterministic integer choice."); EscapeUnfairCycle(); return(SchedulingStrategy.GetNextIntegerChoice(maxValue, out next)); } Debug.WriteLine("<LivenessDebug> Replaying '{0}' '{1}'.", nextStep.Index, nextStep.IntegerChoice.Value); next = nextStep.IntegerChoice.Value; SchedulingStrategy.ForceNextIntegerChoice(maxValue, next); CurrentCycleIndex++; if (CurrentCycleIndex == PotentialCycle.Count) { CurrentCycleIndex = 0; } return(true); } else { return(SchedulingStrategy.GetNextIntegerChoice(maxValue, out next)); } }
/// <summary> /// Returns the state corresponding to the /// specified schedule step. /// </summary> /// <param name="key">ScheduleStep</param> /// <returns>State</returns> internal State this[ScheduleStep key] { get { return(this.StateMap[key]); } }
/// <summary> /// Returns the next integer choice. /// </summary> /// <param name="maxValue">Max value</param> /// <param name="next">Next</param> /// <returns>Boolean</returns> public virtual bool GetNextIntegerChoice(int maxValue, out int next) { if (this.ExploredSteps >= this.ScheduleTrace.Count) { Error.ReportAndExit("Trace is not reproducible: " + "execution is longer than trace."); } ScheduleStep nextStep = this.ScheduleTrace[this.ExploredSteps]; if (nextStep.Type != ScheduleStepType.NondeterministicChoice) { Error.ReportAndExit("Trace is not reproducible: " + "next step is not a nondeterministic choice."); } if (nextStep.IntegerChoice == null) { Error.ReportAndExit("Trace is not reproducible: " + "next step is not a nondeterministic integer choice."); } next = nextStep.IntegerChoice.Value; this.ExploredSteps++; return(true); }
/// <summary> /// Returns the next integer choice. /// </summary> /// <param name="maxValue">Max value</param> /// <param name="next">Next</param> /// <returns>Boolean</returns> bool ISchedulingStrategy.GetNextIntegerChoice(int maxValue, out int next) { if (this.Runtime.Configuration.EnableCycleReplayingStrategy) { ScheduleStep nextStep = this.PotentialCycle[this.CurrentCycleIndex].Item1; if (nextStep.Type != ScheduleStepType.NondeterministicChoice || nextStep.IntegerChoice == null) { Debug.WriteLine("<LivenessDebug> Trace is not reproducible: next step is " + "not a nondeterministic integer choice."); this.EscapeCycle(); return(this.SchedulingStrategy.GetNextIntegerChoice(maxValue, out next)); } Debug.WriteLine($"<LivenessDebug> Replaying '{nextStep.Index}' '{nextStep.IntegerChoice.Value}'."); next = nextStep.IntegerChoice.Value; this.CurrentCycleIndex++; if (this.CurrentCycleIndex == this.PotentialCycle.Count) { this.CurrentCycleIndex = 0; } } else { next = this.Random.Next(maxValue); } return(true); }
/// <summary> /// Returns the next boolean choice. /// </summary> /// <param name="maxValue">Max value</param> /// <param name="next">Next</param> /// <returns>Boolean</returns> bool ISchedulingStrategy.GetNextBooleanChoice(int maxValue, out bool next) { if (this.Runtime.Configuration.EnableCycleReplayingStrategy) { ScheduleStep nextStep = this.PotentialCycle[this.CurrentCycleIndex].Item1; if (nextStep.Type != ScheduleStepType.NondeterministicChoice || nextStep.BooleanChoice == null) { IO.Debug("<LivenessDebug> Trace is not reproducible: next step is " + "not a nondeterministic boolean choice."); this.EscapeCycle(); return(this.BugFindingSchedulingStrategy.GetNextBooleanChoice(maxValue, out next)); } IO.Debug($"<LivenessDebug> Replaying '{nextStep.Index}' '{nextStep.BooleanChoice.Value}'."); next = nextStep.BooleanChoice.Value; this.CurrentCycleIndex++; if (this.CurrentCycleIndex == this.PotentialCycle.Count) { this.CurrentCycleIndex = 0; } } else { next = false; if (this.Random.Next(maxValue) == 0) { next = true; } } return(true); }
/// <summary> /// Returns the next boolean choice. /// </summary> public override bool GetNextBooleanChoice(int maxValue, out bool next) { this.CaptureAndCheckProgramState(); if (this.IsReplayingCycle) { ScheduleStep nextStep = this.PotentialCycle[this.CurrentCycleIndex]; if ((nextStep.Type == ScheduleStepType.SchedulingChoice) || nextStep.BooleanChoice is null) { Debug.WriteLine("<LivenessDebug> Trace is not reproducible: next step is not a nondeterministic boolean choice."); this.EscapeUnfairCycle(); return(this.SchedulingStrategy.GetNextBooleanChoice(maxValue, out next)); } Debug.WriteLine("<LivenessDebug> Replaying '{0}' '{1}'.", nextStep.Index, nextStep.BooleanChoice.Value); next = nextStep.BooleanChoice.Value; this.SchedulingStrategy.ForceNextBooleanChoice(maxValue, next); this.CurrentCycleIndex++; if (this.CurrentCycleIndex == this.PotentialCycle.Count) { this.CurrentCycleIndex = 0; } return(true); } else { return(this.SchedulingStrategy.GetNextBooleanChoice(maxValue, out next)); } }
/// <summary> /// Constructs a reproducable trace. /// </summary> /// <param name="runtime">BugFindingRuntime</param> /// <param name="logger">InMemoryLogger</param> private void ConstructReproducableTrace(BugFindingRuntime runtime, InMemoryLogger logger) { this.ReadableTrace = logger.ToString(); this.ReadableTrace += this.TestReport.GetText(base.Configuration, "<StrategyLog>"); this.BugTrace = runtime.BugTrace; StringBuilder stringBuilder = new StringBuilder(); if (this.Strategy.IsFair()) { stringBuilder.Append("--fair-scheduling").Append(Environment.NewLine); } if (base.Configuration.CacheProgramState) { stringBuilder.Append("--state-caching").Append(Environment.NewLine); stringBuilder.Append("--liveness-temperature-threshold:" + base.Configuration.LivenessTemperatureThreshold). Append(Environment.NewLine); } else { stringBuilder.Append("--liveness-temperature-threshold:" + base.Configuration.LivenessTemperatureThreshold). Append(Environment.NewLine); } if (!base.Configuration.TestMethodName.Equals("")) { stringBuilder.Append("--test-method:" + base.Configuration.TestMethodName). Append(Environment.NewLine); } for (int idx = 0; idx < runtime.ScheduleTrace.Count; idx++) { ScheduleStep step = runtime.ScheduleTrace[idx]; if (step.Type == ScheduleStepType.SchedulingChoice) { stringBuilder.Append($"{step.ScheduledMachineId.Type}" + $"({step.ScheduledMachineId.Value})"); } else if (step.BooleanChoice != null) { stringBuilder.Append(step.BooleanChoice.Value); } else { stringBuilder.Append(step.IntegerChoice.Value); } if (idx < runtime.ScheduleTrace.Count - 1) { stringBuilder.Append(Environment.NewLine); } } this.ReproducableTrace = stringBuilder.ToString(); }
/// <inheritdoc/> internal override bool GetNextOperation(IEnumerable <AsyncOperation> ops, AsyncOperation current, bool isYielding, out AsyncOperation next) { if (this.IsReplaying) { var enabledOps = ops.Where(op => op.Status is AsyncOperationStatus.Enabled).ToList(); if (enabledOps.Count is 0) { next = null; return(false); } try { if (this.ScheduledSteps >= this.ScheduleTrace.Count) { this.ErrorText = "Trace is not reproducible: execution is longer than trace."; throw new InvalidOperationException(this.ErrorText); } ScheduleStep nextStep = this.ScheduleTrace[this.ScheduledSteps]; if (nextStep.Type != ScheduleStepType.SchedulingChoice) { this.ErrorText = "Trace is not reproducible: next step is not a scheduling choice."; throw new InvalidOperationException(this.ErrorText); } next = enabledOps.FirstOrDefault(op => op.Id == nextStep.ScheduledOperationId); if (next is null) { this.ErrorText = $"Trace is not reproducible: cannot detect id '{nextStep.ScheduledOperationId}'."; throw new InvalidOperationException(this.ErrorText); } } catch (InvalidOperationException ex) { if (this.SuffixStrategy is null) { if (!this.Configuration.DisableEnvironmentExit) { Error.ReportAndExit(ex.Message); } next = null; return(false); } else { this.IsReplaying = false; return(this.SuffixStrategy.GetNextOperation(ops, current, isYielding, out next)); } } this.ScheduledSteps++; return(true); } return(this.SuffixStrategy.GetNextOperation(ops, current, isYielding, out next)); }
/// <summary> /// Returns the next choice to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> public bool GetNext(out ISchedulable next, List <ISchedulable> choices, ISchedulable current) { if (IsReplaying) { var enabledChoices = choices.Where(choice => choice.IsEnabled).ToList(); if (enabledChoices.Count == 0) { next = null; return(false); } try { if (ScheduledSteps >= ScheduleTrace.Count) { ErrorText = "Trace is not reproducible: execution is longer than trace."; throw new InvalidOperationException(ErrorText); } ScheduleStep nextStep = ScheduleTrace[ScheduledSteps]; if (nextStep.Type != ScheduleStepType.SchedulingChoice) { ErrorText = "Trace is not reproducible: next step is not a scheduling choice."; throw new InvalidOperationException(ErrorText); } next = enabledChoices.FirstOrDefault(choice => choice.Id == nextStep.ScheduledMachineId); if (next == null) { ErrorText = $"Trace is not reproducible: cannot detect id '{nextStep.ScheduledMachineId}'."; throw new InvalidOperationException(ErrorText); } } catch (InvalidOperationException ex) { if (SuffixStrategy == null) { if (!Configuration.DisableEnvironmentExit) { Error.ReportAndExit(ex.Message); } next = null; return(false); } else { IsReplaying = false; return(SuffixStrategy.GetNext(out next, choices, current)); } } ScheduledSteps++; return(true); } return(SuffixStrategy.GetNext(out next, choices, current)); }
/// <summary> /// Captures a snapshot of the program state. /// </summary> internal bool CaptureState(out State state, out Fingerprint fingerprint, Dictionary <Fingerprint, List <int> > fingerprintIndexMap, ScheduleStep scheduleStep, List <Monitor> monitors) { fingerprint = this.Runtime.GetProgramState(); var enabledMachineIds = this.Runtime.Scheduler.GetEnabledSchedulableIds(); state = new State(fingerprint, enabledMachineIds, GetMonitorStatus(monitors)); if (Debug.IsEnabled) { if (scheduleStep.Type == ScheduleStepType.SchedulingChoice) { Debug.WriteLine( "<LivenessDebug> Captured program state '{0}' at scheduling choice.", fingerprint.GetHashCode()); } else if (scheduleStep.Type == ScheduleStepType.NondeterministicChoice && scheduleStep.BooleanChoice != null) { Debug.WriteLine( "<LivenessDebug> Captured program state '{0}' at nondeterministic choice '{1}'.", fingerprint.GetHashCode(), scheduleStep.BooleanChoice.Value); } else if (scheduleStep.Type == ScheduleStepType.FairNondeterministicChoice && scheduleStep.BooleanChoice != null) { Debug.WriteLine( "<LivenessDebug> Captured program state '{0}' at fair nondeterministic choice '{1}-{2}'.", fingerprint.GetHashCode(), scheduleStep.NondetId, scheduleStep.BooleanChoice.Value); } else if (scheduleStep.Type == ScheduleStepType.NondeterministicChoice && scheduleStep.IntegerChoice != null) { Debug.WriteLine( "<LivenessDebug> Captured program state '{0}' at nondeterministic choice '{1}'.", fingerprint.GetHashCode(), scheduleStep.IntegerChoice.Value); } } var stateExists = this.Fingerprints.Contains(fingerprint); this.Fingerprints.Add(fingerprint); scheduleStep.State = state; if (!fingerprintIndexMap.ContainsKey(fingerprint)) { var hs = new List <int> { scheduleStep.Index }; fingerprintIndexMap.Add(fingerprint, hs); } else { fingerprintIndexMap[fingerprint].Add(scheduleStep.Index); } return(stateExists); }
/// <summary> /// Constructs a reproducable trace. /// </summary> /// <param name="runtime">BugFindingRuntime</param> private void ConstructReproducableTrace(BugFindingRuntime runtime) { StringBuilder stringBuilder = new StringBuilder(); if (this.Strategy.IsFair()) { stringBuilder.Append("--fair-scheduling").Append(Environment.NewLine); } if (base.Configuration.EnableCycleDetection) { stringBuilder.Append("--cycle-detection").Append(Environment.NewLine); stringBuilder.Append("--liveness-temperature-threshold:" + base.Configuration.LivenessTemperatureThreshold). Append(Environment.NewLine); } else { stringBuilder.Append("--liveness-temperature-threshold:" + base.Configuration.LivenessTemperatureThreshold). Append(Environment.NewLine); } if (!base.Configuration.TestMethodName.Equals("")) { stringBuilder.Append("--test-method:" + base.Configuration.TestMethodName). Append(Environment.NewLine); } for (int idx = 0; idx < runtime.ScheduleTrace.Count; idx++) { ScheduleStep step = runtime.ScheduleTrace[idx]; if (step.Type == ScheduleStepType.SchedulingChoice) { stringBuilder.Append($"({step.ScheduledMachineId})"); } else if (step.BooleanChoice != null) { stringBuilder.Append(step.BooleanChoice.Value); } else { stringBuilder.Append(step.IntegerChoice.Value); } if (idx < runtime.ScheduleTrace.Count - 1) { stringBuilder.Append(Environment.NewLine); } } this.ReproducableTrace = stringBuilder.ToString(); }
/// <summary> /// Returns the next integer choice. /// </summary> /// <param name="maxValue">Max value</param> /// <param name="next">Next</param> /// <returns>Boolean</returns> public bool GetNextIntegerChoice(int maxValue, out int next) { if (IsReplaying) { ScheduleStep nextStep = null; try { if (ScheduledSteps >= ScheduleTrace.Count) { ErrorText = "Trace is not reproducible: execution is longer than trace."; throw new InvalidOperationException(ErrorText); } nextStep = ScheduleTrace[ScheduledSteps]; if (nextStep.Type != ScheduleStepType.NondeterministicChoice) { ErrorText = "Trace is not reproducible: next step is not a nondeterministic choice."; throw new InvalidOperationException(ErrorText); } if (nextStep.IntegerChoice == null) { ErrorText = "Trace is not reproducible: next step is not a nondeterministic integer choice."; throw new InvalidOperationException(ErrorText); } } catch (InvalidOperationException ex) { if (SuffixStrategy == null) { if (!Configuration.DisableEnvironmentExit) { Error.ReportAndExit(ex.Message); } next = 0; return(false); } else { IsReplaying = false; return(SuffixStrategy.GetNextIntegerChoice(maxValue, out next)); } } next = nextStep.IntegerChoice.Value; ScheduledSteps++; return(true); } return(SuffixStrategy.GetNextIntegerChoice(maxValue, out next)); }
/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> bool ISchedulingStrategy.TryGetNext(out MachineInfo next, IEnumerable <MachineInfo> choices, MachineInfo current) { var availableMachines = choices.Where( m => m.IsEnabled && !m.IsWaitingToReceive).ToList(); if (availableMachines.Count == 0) { availableMachines = choices.Where(m => m.IsWaitingToReceive).ToList(); if (availableMachines.Count == 0) { next = null; return(false); } } if (this.Runtime.Configuration.EnableCycleReplayingStrategy) { ScheduleStep nextStep = this.PotentialCycle[this.CurrentCycleIndex].Item1; if (nextStep.Type != ScheduleStepType.SchedulingChoice) { Debug.WriteLine("<LivenessDebug> Trace is not reproducible: next step is not a scheduling choice."); this.EscapeCycle(); return(this.SchedulingStrategy.TryGetNext(out next, choices, current)); } Debug.WriteLine($"<LivenessDebug> Replaying '{nextStep.Index}' '{nextStep.ScheduledMachineId}'."); next = availableMachines.FirstOrDefault(m => m.Machine.Id.Type.Equals( nextStep.ScheduledMachineId.Type) && m.Machine.Id.Value == nextStep.ScheduledMachineId.Value); if (next == null) { Debug.WriteLine("<LivenessDebug> Trace is not reproducible: cannot detect machine with type " + $"'{nextStep.ScheduledMachineId.Type}' and id '{nextStep.ScheduledMachineId.Value}'."); this.EscapeCycle(); return(this.SchedulingStrategy.TryGetNext(out next, choices, current)); } this.CurrentCycleIndex++; if (this.CurrentCycleIndex == this.PotentialCycle.Count) { this.CurrentCycleIndex = 0; } } else { int idx = this.Random.Next(availableMachines.Count); next = availableMachines[idx]; } return(true); }
/// <summary> /// Creates a nondeterministic integer choice schedule step. /// </summary> internal static ScheduleStep CreateNondeterministicIntegerChoice(int index, int choice) { var scheduleStep = new ScheduleStep(); scheduleStep.Index = index; scheduleStep.Type = ScheduleStepType.NondeterministicChoice; scheduleStep.BooleanChoice = null; scheduleStep.IntegerChoice = choice; scheduleStep.Previous = null; scheduleStep.Next = null; return(scheduleStep); }
/// <summary> /// Determines whether the specified System.Object is equal /// to the current System.Object. /// </summary> /// <param name="obj">Object</param> /// <returns>Boolean</returns> public override bool Equals(object obj) { if (obj == null) { return(false); } ScheduleStep step = obj as ScheduleStep; if (step == null) { return(false); } return(this.Index == step.Index); }
/// <summary> /// Returns the next choice to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> public override bool GetNext(out ISchedulable next, List <ISchedulable> choices, ISchedulable current) { CaptureAndCheckProgramState(); if (IsReplayingCycle) { var enabledChoices = choices.Where(choice => choice.IsEnabled).ToList(); if (enabledChoices.Count == 0) { next = null; return(false); } ScheduleStep nextStep = PotentialCycle[CurrentCycleIndex]; if (nextStep.Type != ScheduleStepType.SchedulingChoice) { Debug.WriteLine("<LivenessDebug> Trace is not reproducible: next step is not a scheduling choice."); EscapeUnfairCycle(); return(SchedulingStrategy.GetNext(out next, choices, current)); } Debug.WriteLine("<LivenessDebug> Replaying '{0}' '{1}'.", nextStep.Index, nextStep.ScheduledMachineId); next = enabledChoices.FirstOrDefault(choice => choice.Id == nextStep.ScheduledMachineId); if (next == null) { Debug.WriteLine("<LivenessDebug> Trace is not reproducible: cannot detect machine with id '{0}'.", nextStep.ScheduledMachineId); EscapeUnfairCycle(); return(SchedulingStrategy.GetNext(out next, choices, current)); } SchedulingStrategy.ForceNext(next, choices, current); CurrentCycleIndex++; if (CurrentCycleIndex == PotentialCycle.Count) { CurrentCycleIndex = 0; } return(true); } else { return(SchedulingStrategy.GetNext(out next, choices, current)); } }
/// <summary> /// Creates a fair nondeterministic boolean choice schedule step. /// </summary> /// <param name="index">Index</param> /// <param name="uniqueId">Unique id</param> /// <param name="choice">Choice</param> /// <returns>ScheduleStep</returns> internal static ScheduleStep CreateFairNondeterministicBooleanChoice( int index, string uniqueId, bool choice) { var scheduleStep = new ScheduleStep(); scheduleStep.Index = index; scheduleStep.Type = ScheduleStepType.FairNondeterministicChoice; scheduleStep.NondetId = uniqueId; scheduleStep.BooleanChoice = choice; scheduleStep.IntegerChoice = null; scheduleStep.Previous = null; scheduleStep.Next = null; return(scheduleStep); }
/// <summary> /// Returns the next asynchronous operation to schedule. /// </summary> public override bool GetNext(out IAsyncOperation next, List <IAsyncOperation> ops, IAsyncOperation current) { this.CaptureAndCheckProgramState(); if (this.IsReplayingCycle) { var enabledOperations = ops.Where(op => op.IsEnabled).ToList(); if (enabledOperations.Count == 0) { next = null; return(false); } ScheduleStep nextStep = this.PotentialCycle[this.CurrentCycleIndex]; if (nextStep.Type != ScheduleStepType.SchedulingChoice) { Debug.WriteLine("<LivenessDebug> Trace is not reproducible: next step is not an operation."); this.EscapeUnfairCycle(); return(this.SchedulingStrategy.GetNext(out next, ops, current)); } Debug.WriteLine("<LivenessDebug> Replaying '{0}' '{1}'.", nextStep.Index, nextStep.ScheduledOperationId); next = enabledOperations.FirstOrDefault(choice => choice.SourceId == nextStep.ScheduledOperationId); if (next is null) { Debug.WriteLine("<LivenessDebug> Trace is not reproducible: cannot detect machine with id '{0}'.", nextStep.ScheduledOperationId); this.EscapeUnfairCycle(); return(this.SchedulingStrategy.GetNext(out next, ops, current)); } this.SchedulingStrategy.ForceNext(next, ops, current); this.CurrentCycleIndex++; if (this.CurrentCycleIndex == this.PotentialCycle.Count) { this.CurrentCycleIndex = 0; } return(true); } else { return(this.SchedulingStrategy.GetNext(out next, ops, current)); } }
/// <summary> /// Creates a schedule step. /// </summary> internal static ScheduleStep CreateSchedulingChoice(int index, ulong scheduledActorId) { var scheduleStep = new ScheduleStep(); scheduleStep.Index = index; scheduleStep.Type = ScheduleStepType.SchedulingChoice; scheduleStep.ScheduledOperationId = scheduledActorId; scheduleStep.BooleanChoice = null; scheduleStep.IntegerChoice = null; scheduleStep.Previous = null; scheduleStep.Next = null; return(scheduleStep); }
/// <summary> /// Returns the next choice to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> bool ISchedulingStrategy.TryGetNext(out ISchedulable next, List <ISchedulable> choices, ISchedulable current) { var enabledChoices = choices.Where(choice => choice.IsEnabled).ToList(); if (enabledChoices.Count == 0) { next = null; return(false); } if (this.Runtime.Configuration.EnableCycleReplayingStrategy) { ScheduleStep nextStep = this.PotentialCycle[this.CurrentCycleIndex].Item1; if (nextStep.Type != ScheduleStepType.SchedulingChoice) { Debug.WriteLine("<LivenessDebug> Trace is not reproducible: next step is not a scheduling choice."); this.EscapeCycle(); return(this.SchedulingStrategy.TryGetNext(out next, choices, current)); } Debug.WriteLine($"<LivenessDebug> Replaying '{nextStep.Index}' '{nextStep.ScheduledMachineId}'."); next = enabledChoices.FirstOrDefault(choice => choice.Id == nextStep.ScheduledMachineId); if (next == null) { Debug.WriteLine($"<LivenessDebug> Trace is not reproducible: cannot detect machine with id '{nextStep.ScheduledMachineId}'."); this.EscapeCycle(); return(this.SchedulingStrategy.TryGetNext(out next, choices, current)); } this.CurrentCycleIndex++; if (this.CurrentCycleIndex == this.PotentialCycle.Count) { this.CurrentCycleIndex = 0; } } else { int idx = this.Random.Next(enabledChoices.Count); next = enabledChoices[idx]; } return(true); }
/// <summary> /// Captures a snapshot of the program state. /// </summary> /// <param name="scheduleStep">ScheduleStep</param> internal void CaptureState(ScheduleStep scheduleStep) { var fingerprint = this.Runtime.GetProgramState(); var enabledMachines = this.Runtime.Scheduler.GetEnabledMachines(); var state = new State(fingerprint, enabledMachines, this.Runtime.LivenessChecker.GetMonitorStatus()); if (scheduleStep.Type == ScheduleStepType.SchedulingChoice) { Debug.WriteLine("<LivenessDebug> Captured program state '{0}' at " + "scheduling choice.", fingerprint.GetHashCode()); } else if (scheduleStep.Type == ScheduleStepType.NondeterministicChoice && scheduleStep.BooleanChoice != null) { Debug.WriteLine("<LivenessDebug> Captured program state '{0}' at nondeterministic " + "choice '{1}'.", fingerprint.GetHashCode(), scheduleStep.BooleanChoice.Value); } else if (scheduleStep.Type == ScheduleStepType.FairNondeterministicChoice && scheduleStep.BooleanChoice != null) { Debug.WriteLine("<LivenessDebug> Captured program state '{0}' at fair nondeterministic choice " + "'{1}-{2}'.", fingerprint.GetHashCode(), scheduleStep.NondetId, scheduleStep.BooleanChoice.Value); } else if (scheduleStep.Type == ScheduleStepType.NondeterministicChoice && scheduleStep.IntegerChoice != null) { Debug.WriteLine("<LivenessDebug> Captured program state '{0}' at nondeterministic " + "choice '{1}'.", fingerprint.GetHashCode(), scheduleStep.IntegerChoice.Value); } //var stateExists = this.StateMap.Values.Any(val => val.Fingerprint.Equals(fingerprint)); var stateExists = this.Fingerprints.Any(val => val.Equals(fingerprint)); this.StateMap.Add(scheduleStep, state); this.Fingerprints.Add(fingerprint); if (stateExists) { Debug.WriteLine("<LivenessDebug> Detected potential infinite execution."); this.Runtime.LivenessChecker.CheckLivenessAtTraceCycle(state.Fingerprint); } }
/// <summary> /// Returns the next boolean choice. /// </summary> /// <param name="maxValue">Max value</param> /// <param name="next">Next</param> /// <returns>Boolean</returns> public bool GetNextBooleanChoice(int maxValue, out bool next) { ScheduleStep nextStep = null; try { if (this.ExploredSteps >= this.ScheduleTrace.Count) { this.ErrorText = "Trace is not reproducible: execution is longer than trace."; throw new InvalidOperationException(this.ErrorText); } nextStep = this.ScheduleTrace[this.ExploredSteps]; if (nextStep.Type != ScheduleStepType.NondeterministicChoice) { this.ErrorText = "Trace is not reproducible: next step is not a nondeterministic choice."; throw new InvalidOperationException(this.ErrorText); } if (nextStep.BooleanChoice == null) { this.ErrorText = "Trace is not reproducible: next step is not a nondeterministic boolean choice."; throw new InvalidOperationException(this.ErrorText); } } catch (InvalidOperationException ex) { if (!this.Configuration.DisableEnvironmentExit) { Error.ReportAndExit(ex.Message); } next = false; return(false); } next = nextStep.BooleanChoice.Value; this.ExploredSteps++; return(true); }
/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> public bool TryGetNext(out MachineInfo next, IEnumerable <MachineInfo> choices, MachineInfo current) { var availableMachines = choices.Where( m => m.IsEnabled && !m.IsWaitingToReceive).ToList(); if (availableMachines.Count == 0) { availableMachines = choices.Where(m => m.IsWaitingToReceive).ToList(); if (availableMachines.Count == 0) { next = null; return(false); } } if (this.ExploredSteps >= this.ScheduleTrace.Count) { Error.ReportAndExit("Trace is not reproducible: execution is longer than trace."); } ScheduleStep nextStep = this.ScheduleTrace[this.ExploredSteps]; if (nextStep.Type != ScheduleStepType.SchedulingChoice) { Error.ReportAndExit("Trace is not reproducible: next step is not a scheduling choice."); } next = availableMachines.FirstOrDefault(m => m.Machine.Id.Type.Equals( nextStep.ScheduledMachineId.Type) && m.Machine.Id.Value == nextStep.ScheduledMachineId.Value); if (next == null) { Error.ReportAndExit("Trace is not reproducible: cannot detect machine with type " + $"'{nextStep.ScheduledMachineId.Type}' and id '{nextStep.ScheduledMachineId.Value}'."); } this.ExploredSteps++; return(true); }
/// <summary> /// Initializes a new instance of the <see cref="Schedule"/> class. /// </summary> /// <param name="step">The walk.</param> /// <param name="startDate">The start date.</param> /// <param name="endDate">The end date.</param> public Schedule(ScheduleStep step, DateTime startDate, DateTime endDate) { _currentStart = startDate; _endDate = endDate; // ScheduleStep is converted to ScheduleWalkTo // Done just to maintain clarity when setting up constructor // otherwise caller will have confusion when using this constructor regarding end dates // which are ignored switch (step) { case ScheduleStep.Years: _walk = ScheduleWalkThrough.Years; break; case ScheduleStep.Months: _walk = ScheduleWalkThrough.MonthsInYear; break; case ScheduleStep.Weeks: _walk = ScheduleWalkThrough.WeeksInYear; break; case ScheduleStep.Days: _walk = ScheduleWalkThrough.DaysInYear; break; case ScheduleStep.Hours: _walk = ScheduleWalkThrough.HoursInDay; break; case ScheduleStep.Minutes: _walk = ScheduleWalkThrough.MinutesInHour; break; case ScheduleStep.Seconds: _walk = ScheduleWalkThrough.SecondsInMinute; break; } }
/// <summary> /// Creates a schedule step. /// </summary> /// <param name="index">Index</param> /// <param name="scheduledMachineType">Scheduled machine type</param> /// <param name="scheduledMachineId">Scheduled machine id</param> /// <returns>ScheduleStep</returns> internal static ScheduleStep CreateSchedulingChoice(int index, string scheduledMachineType, int scheduledMachineId) { var scheduleStep = new ScheduleStep(); scheduleStep.Index = index; scheduleStep.Type = ScheduleStepType.SchedulingChoice; scheduleStep.ScheduledMachineType = scheduledMachineType; scheduleStep.ScheduledMachineId = scheduledMachineId; scheduleStep.BooleanChoice = null; scheduleStep.IntegerChoice = null; scheduleStep.Previous = null; scheduleStep.Next = null; return scheduleStep; }
/// <summary> /// Removes the specified schedule step from the cache. /// </summary> /// <param name="scheduleStep">ScheduleStep</param> internal void Remove(ScheduleStep scheduleStep) { this.StateMap.Remove(scheduleStep); }
/// <summary> /// Creates a fair nondeterministic boolean choice schedule step. /// </summary> /// <param name="index">Index</param> /// <param name="uniqueId">Unique id</param> /// <param name="choice">Choice</param> /// <returns>ScheduleStep</returns> internal static ScheduleStep CreateFairNondeterministicBooleanChoice( int index, string uniqueId, bool choice) { var scheduleStep = new ScheduleStep(); scheduleStep.Index = index; scheduleStep.Type = ScheduleStepType.FairNondeterministicChoice; scheduleStep.NondetId = uniqueId; scheduleStep.BooleanChoice = choice; scheduleStep.IntegerChoice = null; scheduleStep.Previous = null; scheduleStep.Next = null; return scheduleStep; }
/// <summary> /// Creates a nondeterministic integer choice schedule step. /// </summary> /// <param name="index">Index</param> /// <param name="choice">Choice</param> /// <returns>ScheduleStep</returns> internal static ScheduleStep CreateNondeterministicIntegerChoice(int index, int choice) { var scheduleStep = new ScheduleStep(); scheduleStep.Index = index; scheduleStep.Type = ScheduleStepType.NondeterministicChoice; scheduleStep.BooleanChoice = null; scheduleStep.IntegerChoice = choice; scheduleStep.Previous = null; scheduleStep.Next = null; return scheduleStep; }
/// <summary> /// Creates a schedule step. /// </summary> /// <param name="index">Index</param> /// <param name="scheduledMachine">Scheduled machine</param> /// <returns>ScheduleStep</returns> internal static ScheduleStep CreateSchedulingChoice(int index, AbstractMachine scheduledMachine) { var scheduleStep = new ScheduleStep(); scheduleStep.Index = index; scheduleStep.Type = ScheduleStepType.SchedulingChoice; scheduleStep.ScheduledMachine = scheduledMachine; scheduleStep.ScheduledMachineType = scheduledMachine.Id.Type; scheduleStep.ScheduledMachineId = scheduledMachine.Id.Value; scheduleStep.BooleanChoice = null; scheduleStep.IntegerChoice = null; scheduleStep.Previous = null; scheduleStep.Next = null; return scheduleStep; }