Пример #1
0
        /// <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));
        }
Пример #2
0
        /// <summary>
        /// Returns or forces the next choice to schedule.
        /// </summary>
        /// <param name="next">Next</param>
        /// <param name="choices">Choices</param>
        /// <param name="current">Curent</param>
        /// <returns>Boolean</returns>
        private bool GetNextHelper(ref ISchedulable next, List <ISchedulable> choices, ISchedulable current)
        {
            ++ScheduledSteps;
            switch (Reduction)
            {
            case ReductionStrategy.ForceSchedule:
            {
                var partialOrderChoices =
                    choices
                    .Where(choice => choice.IsEnabled && IsPartialOrderOperation(choice.NextOperationType))
                    .ToList();

                // If we are being forced:
                if (next != null)
                {
                    if (!partialOrderChoices.Contains(next))
                    {
                        // Tell child strategy that we were forced (to do a particular send).
                        ChildStrategy.ForceNext(next, choices, current);
                        return(true);
                    }

                    // We would have forced this choice anyway so don't tell ChildStrategy.
                    return(true);
                }

                // Not being forced:
                if (partialOrderChoices.Count > 0)
                {
                    // Force this non-send but don't tell ChildStrategy.
                    next = partialOrderChoices[0];
                    return(true);
                }

                // Normal schedule:
                return(ChildStrategy.GetNext(out next, choices, current));
            }

            case ReductionStrategy.OmitSchedulingPoints:
            {
                // Otherwise, don't schedule before non-Send.

                bool continueWithCurrent =
                    current.IsEnabled &&
                    IsPartialOrderOperation(current.NextOperationType);

                // We are being forced:
                if (next != null)
                {
                    // ...to do something different than we would have:
                    if (continueWithCurrent && current != next)
                    {
                        // ...so tell child.
                        ChildStrategy.ForceNext(next, choices, current);
                        return(true);
                    }
                    // Otherwise, don't tell child.
                    return(true);
                }

                // Not being forced:

                if (continueWithCurrent)
                {
                    next = current;
                    return(true);
                }

                // Normal schedule:
                return(ChildStrategy.GetNext(out next, choices, current));
            }

            case ReductionStrategy.None:
            {
                // Normal schedule:
                if (next != null)
                {
                    ChildStrategy.ForceNext(next, choices, current);
                    return(true);
                }
                return(ChildStrategy.GetNext(out next, choices, current));
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }