public override void Loop()
        {
            DebugTools.AddEvent("StepperInternalLoop.Loop", "Loop Start. Signalling and waiting on " + (SyncContext?.GetNumberOfRemainingParticipants() - 1) + ". Total participants = " + SyncContext?.GetNumberOfTotalParticipants() + " : " + this.Name);
            SyncContext?.SignalAndWait();
            //DebugTools.AddEvent("StepperInternalLoop.Loop", "Loop Start. Signal received. Continuing: " + this.Name);

            while (true)
            {
                if (CurrentStep + 1 > EndStep)
                {
                    CurrentStep = StartStep;
                    break;
                }
                else
                {
                    CurrentStep++;
                }

                while (PauseForTest)
                {
                    Thread.Sleep(1);
                }

                DebugTools.AddEvent("StepperInternalLoop.Loop", "In While. Signalling and waiting on " + (SyncContext?.GetNumberOfRemainingParticipants() - 1) + ". Total participants = " + SyncContext?.GetNumberOfTotalParticipants() + " : " + this.Name);
                SyncContext?.SignalAndWait();
                //DebugTools.AddEvent("StepperInternalLoop.Loop", "In While. Signal received. Continuing: " + this.Name);
            }

            DebugTools.AddEvent("StepperInternalLoop.Loop", "Loop End. Signalling and waiting on " + (SyncContext?.GetNumberOfRemainingParticipants() - 1) + ". Total participants = " + SyncContext?.GetNumberOfTotalParticipants() + " : " + this.Name);
            SyncContext?.SignalAndWait();
            //DebugTools.AddEvent("StepperInternalLoop.Loop", "Loop End. Signal received. Continuing: " + this.Name);
        }
 /// <summary>
 /// Requests the program to pause when it's at its synchronizable state.
 /// </summary>
 /// <returns></returns>
 public void RequestSyncState()
 {
     lock (SyncStateRequestLock)
     {
         IsSyncStateRequested = true;
         DebugTools.AddEvent("LoopingZoneProgram.RequestSyncState", "IsSyncStateRequested = true: " + Name);
     }
 }
Beispiel #3
0
        public static void Sync_ThreeStepperSyncingWithOne_Consecutive_Works(int numberOfChecks)
        {
            DebugTools.AddEvent("Sync_ThreeStepperSyncingWithOne_Works", "START");

            //create a sync context to conduct the test with
            var testContext = new SyncContext();

            //create two programs to be synced
            var stepperA = new StepperInternalLoop("A");
            var stepperB = new StepperInternalLoop("B");
            var stepperC = new StepperInternalLoop("C");
            var stepperD = new StepperInternalLoop("D");

            IStepper[] steppers = { stepperA, stepperB, stepperC, stepperD };

            //sync and start A
            DebugTools.AddEvent("Sync_ThreeStepperSyncingWithOne_Works", "Sync-Starting Stepper A");
            testContext.Sync(stepperA);
            testContext.SyncFinished.WaitForFire();

            //start BCD in sync with testContext when steppers A is back to the beginning
            DebugTools.AddEvent("Sync_ThreeStepperSyncingWithOne_Works", "Syncing Stepper B");
            testContext.Sync(stepperB);
            testContext.SyncFinished.WaitForFire();
            DebugTools.AddEvent("Sync_ThreeStepperSyncingWithOne_Works", "Syncing Stepper C");
            testContext.Sync(stepperC);
            testContext.SyncFinished.WaitForFire();
            DebugTools.AddEvent("Sync_ThreeStepperSyncingWithOne_Works", "Syncing Stepper D");
            testContext.Sync(stepperD);
            testContext.SyncFinished.WaitForFire();

            int[,] stepperSteps;
            DebugTools.AddEvent("Sync_ThreeStepperSyncingWithOne_Works", "Validating Sync Phases");
            var invalidStepIndex = ValidateStepperSyncPhase(steppers, out stepperSteps, numberOfChecks);
            var result           = invalidStepIndex.Length == 0;

            //cleanup
            DebugTools.AddEvent("Sync_ThreeStepperSyncingWithOne_Works", "Disposing Stepper A");
            stepperA.Dispose(true);
            DebugTools.AddEvent("Sync_ThreeStepperSyncingWithOne_Works", "Disposing Stepper B");
            stepperB.Dispose(true);
            DebugTools.AddEvent("Sync_ThreeStepperSyncingWithOne_Works", "Disposing Stepper C");
            stepperC.Dispose(true);
            DebugTools.AddEvent("Sync_ThreeStepperSyncingWithOne_Works", "Disposing Stepper D");
            stepperD.Dispose(true);
            testContext.Dispose();

            //assert
            if (result)
            {
                Assert.Pass();
            }
            else
            {
                var failStringBuilder = BuildFailString(invalidStepIndex, steppers, stepperSteps);
                Assert.Fail(failStringBuilder.ToString());
            }
        }
        protected override void StopCore(bool force)
        {
            //subclass processing
            PreStop(force);

            DebugTools.AddEvent("LoopingZoneProgram.StopCore", "STOP " + Name);
            //DebugTools.AddEvent("LoopingZoneProgram.StopCore", "Canceling Sync-State on Program " + Name);

            //cancel sync state req and release from sync state
            CancelSyncState();

            //DebugTools.AddEvent("LoopingZoneProgram.Stop", "START Stopping BG Program");

            if (Running)
            {
                //DebugTools.AddEvent("LoopingZoneProgram.Stop", "Running = TRUE");

                if (force)
                {
                    if (RunProgramThread != null)
                    {
                        //DebugTools.AddEvent("LoopingZoneProgram.Stop", "START Force aborting BG Program thread");
                        RunProgramThread.Abort();
                        StopTrigger.WaitForFire();
                        //DebugTools.AddEvent("LoopingZoneProgram.Stop", "END Force aborting BG Program thread");
                    }
                    else
                    {
                        //DebugTools.AddEvent("LoopingZoneProgram.Stop", "RunProgramThread was null");
                        //DebugTools.Print();
                    }
                }
                else
                {
                    LoopCTS.Cancel();
                    if (!StopTrigger.WaitForFire())
                    {
                        //DebugTools.AddEvent("LoopingZoneProgram.Stop", "Loop did not cancel cooperatively.");
                        //DebugTools.Print();
                    }
                }
            }

            PostStop(force);

            //DebugTools.AddEvent("LoopingZoneProgram.Stop", "END Stopping BG Program");

            StopTestingTrigger.Fire(this, null);
        }
Beispiel #5
0
        public static void Sync_FourSteppers_Simultaneous_Works(int numberOfChecks)
        {
            DebugTools.AddEvent("Sync_FourSteppers_Works", "START");

            //create a sync context to conduct the test with
            var testContext = new SyncContext();

            //create two programs to be synced
            var stepperA = new Stepper("A");
            var stepperB = new Stepper("B");
            var stepperC = new Stepper("C");
            var stepperD = new Stepper("D");

            IStepper[] steppers = { stepperA, stepperB, stepperC, stepperD };

            //sync and start
            testContext.Sync(stepperA, stepperB, stepperC, stepperD);
            testContext.SyncFinished.WaitForFire();

            int[,] stepperSteps;
            var invalidStepIndex = ValidateStepperSyncPhase(steppers, out stepperSteps, numberOfChecks);
            var result           = invalidStepIndex.Length == 0;

            PrintStepperSteps(steppers, stepperSteps);

            //cleanup
            stepperA.Dispose(true);
            stepperB.Dispose(true);
            stepperC.Dispose(true);
            stepperD.Dispose(true);
            testContext.Dispose();

            //assert
            if (result)
            {
                Assert.Pass();
            }
            else
            {
                var failStringBuilder = BuildFailString(invalidStepIndex, steppers, stepperSteps);
                Assert.Fail(failStringBuilder.ToString());
            }
        }
Beispiel #6
0
        public static void PrintStepperSteps(IStepper[] steppers, int[,] stepperSteps)
        {
            //output stepperSteps
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.Append(Environment.NewLine);
            stringBuilder.Append(Environment.NewLine);

            foreach (var stepper in steppers)
            {
                stringBuilder.Append("   ");
                stringBuilder.Append(((ZoneProgram)stepper).Name);
                stringBuilder.Append("   ");
                stringBuilder.Append("|");
            }

            stringBuilder.Append(Environment.NewLine);
            stringBuilder.Append(Environment.NewLine);

            foreach (var stepper in steppers)
            {
                stringBuilder.Append("--------");
            }

            stringBuilder.Append(Environment.NewLine);
            stringBuilder.Append(Environment.NewLine);

            for (var i = 0; i < stepperSteps.GetLength(0); i++)
            {
                for (var j = 0; j < stepperSteps.GetLength(1); j++)
                {
                    stringBuilder.Append("   ");
                    stringBuilder.Append(stepperSteps[i, j]);
                    stringBuilder.Append("   ");
                    stringBuilder.Append("|");
                }

                stringBuilder.Append(Environment.NewLine);
            }

            DebugTools.AddEvent("Sync_TwoSteppers_Works", stringBuilder.ToString());
        }
Beispiel #7
0
        public static void CooperativeStop_Works()
        {
            DebugTools.AddEvent("Test.CooperativeStop_Works", "START CooperativeStop_Works Test");

            //arrange
            var zoneScaffolder = new ZoneScaffolder();

            zoneScaffolder.Initialize(ConfigurationManager.AppSettings["TestProgramModuleDirectory"]);

            var leftWing = new FadeCandyZone(FadeCandyController.Instance, "LeftWing");

            leftWing.AddFadeCandyLights(PixelType.FadeCandyWS2812Pixel, 6, 1);

            dynamic scrollDotDictionary = new ISV();

            scrollDotDictionary.DelayTime = 30;
            scrollDotDictionary.DotColor  = (Color?)Color.Red;

            FadeCandyController.Instance.Initialize();                  //needs to be faked somehow

            leftWing.Run(new ScrollDot(), scrollDotDictionary);

            //this is to fix the race condition that sometimes causes this test to fail - since this test
            //is not designed to test race conditions, just whether cooperative stop works in normal conditions
            Thread.Sleep(100);

            //act -- cooperative stop
            leftWing.ZoneProgram.Stop(false);

            //assert
            var result = leftWing.ZoneProgram.StopTestingTrigger.WaitForFire(1000);

            //cleanup
            leftWing.Dispose();
            FadeCandyController.Instance.Dispose();

            DebugTools.AddEvent("Test.CooperativeStop_Works", "END CooperativeStop_Works Test");

            Assert.True(result);
        }
Beispiel #8
0
        public static void Sync_OneStepper_Works(int numberOfChecks)
        {
            DebugTools.AddEvent("Sync_OneStepperSyncingWithThree_Works", "START");

            //create a sync context to conduct the test with
            var testContext = new SyncContext();

            //create two programs to be synced
            var stepperA = new StepperInternalLoop("A");

            IStepper[] steppers = { stepperA };

            //sync and start ABC
            DebugTools.AddEvent("Sync_OneStepperSyncingWithThree_Works", "Sync-Starting Stepper A, B, C");
            testContext.Sync(stepperA);
            testContext.SyncFinished.WaitForFire();

            int[,] stepperSteps;
            var invalidStepIndex = ValidateStepperSyncPhase(steppers, out stepperSteps, numberOfChecks);
            var result           = invalidStepIndex.Length == 0 && stepperSteps.Length != 0;

            //cleanup
            DebugTools.AddEvent("Sync_OneStepperSyncingWithThree_Works", "Disposing Stepper A");
            stepperA.Dispose(true);
            testContext.Dispose();

            if (result)
            {
                Assert.Pass();
            }
            else
            {
                var failStringBuilder = BuildFailString(invalidStepIndex, steppers, stepperSteps);
                Assert.Fail(failStringBuilder.ToString());
            }
        }
        private void SetupRunProgramTask()
        {
            LoopCTS.Dispose();
            LoopCTS = new CancellationTokenSource();
            try
            {
                LoopingTask?.Dispose();
            }
            catch (Exception ex)
            { }
            LoopingTask = new Task(() =>
            {
                try
                {
                    RunProgramThread = Thread.CurrentThread;
                    while (true)
                    {
                        //if sync is requested, go into synchronizable state
                        if (SyncContext != null)
                        {
                            lock (SyncStateRequestLock)
                            {
                                if (IsSyncStateRequested)
                                {
                                    DebugTools.AddEvent("LoopingZoneProgram.LoopingTask", "Entering Sync-State: " + Name);
                                    IsSynchronizable.Fire(this, null);
                                    DebugTools.AddEvent("LoopingZoneProgram.LoopingTask",
                                                        "In Sync-State - Waiting for Signal from SyncContext: " + Name);
                                    WaitForSync.WaitForFire();
                                    DebugTools.AddEvent("LoopingZoneProgram.LoopingTask", "Leaving Sync-State: " + Name);
                                    IsSyncStateRequested = false;
                                    DebugTools.AddEvent("LoopingZoneProgram.LoopingTask", "IsSyncStateRequested = false: " + Name);
                                }
                            }
                        }

                        //this is currently not doing anything
                        LeftSyncTrigger.Fire(this, null);

                        DebugTools.AddEvent("LoopingZoneProgram.LoopingTask", "Starting Loop: " + Name);
                        //start loop
                        Loop();
                        DebugTools.AddEvent("LoopingZoneProgram.LoopingTask", "Finished Loop: " + Name);

                        //if cancellation is requested, break out of loop after setting notification parameters for the consumer
                        if (LoopCTS.IsCancellationRequested)
                        {
                            Running = false;
                            StopTrigger.Fire(this, null);
                            break;
                        }

                        //this makes the CPU consumption way lesser
                        Thread.Sleep(LoopWaitTime);
                    }
                }
                catch (ThreadAbortException ex)
                {
                    //DebugTools.AddEvent("LoopingZoneProgram.LoopingTask.Method", "LoopingTask thread aborted");
                    //DebugTools.AddEvent("LoopingZoneProgram.Stop", "START Setting Running = false");
                    Running = false;
                    StopTrigger.Fire(this, null);
                    //DebugTools.AddEvent("LoopingZoneProgram.Stop", "END Setting Running = false");
                }
                catch (Exception ex)
                {
                    Running = false;
                    StopTrigger.Fire(this, null);
                    DebugTools.AddEvent("LoopingZoneProgram.LoopingTask.Method",
                                        "Unexpected exception in LoopingTask: " + ex.Message + " | StackTrace: " + ex.StackTrace);
                }
            }, LoopCTS.Token);
        }
Beispiel #10
0
        /// <summary>
        /// Checks to make sure that the steppers provided are in within 1 step of each other.
        /// </summary>
        /// <returns>Array of steps that were out of sync.</returns>
        public static int[] ValidateStepperSyncPhase(IStepper[] steppers, out int[,] stepperSteps, int numberOfChecks = 30, int msToWaitBeforeStart = 10, int msToWaitBetweenChecks = 1)
        {
            //sleep cuz we want the programs to get going
            Thread.Sleep(msToWaitBeforeStart);

            DebugTools.AddEvent("ValidateStepperSyncPhase", "START");

            List <int> invalidStepIndex = new List <int>();

            stepperSteps = new int[numberOfChecks, steppers.Length];

            for (var i = 0; i < numberOfChecks; i++)
            {
                for (var j = 0; j < steppers.Length; j++)
                {
                    stepperSteps[i, j] = 0;
                }
            }

            //every time we check the step, it should be within 1 for both programs
            //because they should have been synced and then started - one program may be ahead of
            //another because this test may read in between the transactions (since this test is not
            //aware of the sync itself, it's reading values intermittently, so being off by one
            //does not imply that the programs are out of sync. if the programs do go out of sync,
            //with enough repetitions they will go out of sync even more, which means their steps
            //will eventually differ by more than 1, which is what this for loop is testing. therefore,
            //the higher the number of checks, the higher the chance of failure if the programs are out of sync, OR
            //if the sync algorithm has a race condition or some other kind of flaw.
            for (var i = 0; i < numberOfChecks; i++)
            {
                foreach (var stepper in steppers)
                {
                    stepper.PauseForTest = true;
                }
                for (var j = 0; j < steppers.Length; j++)
                {
                    stepperSteps[i, j] = steppers[j].CurrentStep;
                }
                foreach (var stepper in steppers)
                {
                    stepper.PauseForTest = false;
                }

                //check to make sure the difference in steps in no more than 1 (and check for wrapping)
                for (int comparisonSource = 0; comparisonSource < steppers.Length; comparisonSource++)
                {
                    for (int comparisonTarget = 0; comparisonTarget < steppers.Length; comparisonTarget++)
                    {
                        if (Math.Abs(stepperSteps[i, comparisonSource] - stepperSteps[i, comparisonTarget]) > 1 &&
                            !(stepperSteps[i, comparisonSource] == steppers[comparisonSource].EndStep &&
                              stepperSteps[i, comparisonTarget] == steppers[comparisonTarget].StartStep) &&
                            !(stepperSteps[i, comparisonSource] == steppers[comparisonSource].EndStep &&
                              stepperSteps[i, comparisonTarget] == steppers[comparisonTarget].StartStep + 1) &&
                            !(stepperSteps[i, comparisonSource] == steppers[comparisonSource].StartStep &&
                              stepperSteps[i, comparisonTarget] == steppers[comparisonTarget].EndStep) &&
                            !(stepperSteps[i, comparisonSource] == steppers[comparisonSource].StartStep + 1 &&
                              stepperSteps[i, comparisonTarget] == steppers[comparisonTarget].EndStep))
                        {
                            if (!invalidStepIndex.Contains(i))
                            {
                                invalidStepIndex.Add(i);
                            }
                        }
                    }
                }

                //sleep cuz we want some cycles to execute
                if (msToWaitBetweenChecks > 0)
                {
                    Thread.Sleep(msToWaitBetweenChecks);
                }
            }

            DebugTools.AddEvent("ValidateStepperSyncPhase", "END result: " + (!invalidStepIndex.Any()));

            return(invalidStepIndex.ToArray());
        }