示例#1
0
        public void Transitions()
        {
            var counters = new PipStateCounters();

            PipState?previousState = null;

            foreach (PipState state in s_pipStates)
            {
                if (previousState.HasValue)
                {
                    counters.AccumulateTransition(previousState.Value, state, PipType.Process);
                }
                else
                {
                    counters.AccumulateInitialState(state, PipType.Process);
                }

                previousState = state;
            }

            var snapshot = new PipStateCountersSnapshot();

            counters.CollectSnapshot(s_pipTypes, snapshot);

            int numExpected = 1;

            foreach (PipState state in s_pipStates.Reverse())
            {
                XAssert.AreEqual(numExpected, snapshot[state]);

                // Only the last state should a count. We did (initial A) A -> B -> C, expecting one unit on C.
                numExpected = 0;
            }
        }
示例#2
0
        public void InitialStates()
        {
            var counters = new PipStateCounters();

            int numInitial = 0;

            foreach (PipState state in s_pipStates)
            {
                numInitial++;
                for (int i = 0; i < numInitial; i++)
                {
                    counters.AccumulateInitialState(state, PipType.Process);
                }
            }

            var snapshot = new PipStateCountersSnapshot();

            counters.CollectSnapshot(s_pipTypes, snapshot);

            int numExpected = 0;

            foreach (PipState state in s_pipStates)
            {
                numExpected++;
                XAssert.AreEqual(numExpected, snapshot[state]);
            }
        }
示例#3
0
        public void TransitionsCancellation()
        {
            var counters = new PipStateCounters();

            // Here for various pairs we transition A -> B then B -> A.
            // This cancels out to 'one pips in A and B' since each has one initially.
            PipState?previousState = null;

            foreach (PipState state in s_pipStates)
            {
                counters.AccumulateInitialState(state, PipType.Process);

                if (previousState.HasValue)
                {
                    counters.AccumulateTransition(previousState.Value, state, PipType.Process);
                    counters.AccumulateTransition(state, previousState.Value, PipType.Process);
                }

                previousState = state;
            }

            var snapshot = new PipStateCountersSnapshot();

            counters.CollectSnapshot(s_pipTypes, snapshot);

            foreach (PipState state in s_pipStates)
            {
                XAssert.AreEqual(1, snapshot[state]);
            }
        }
示例#4
0
        public void Empty()
        {
            var counters = new PipStateCounters();
            var snapshot = new PipStateCountersSnapshot();

            counters.CollectSnapshot(s_pipTypes, snapshot);

            foreach (PipState state in s_pipStates)
            {
                XAssert.AreEqual(0, snapshot[state]);
            }
        }
示例#5
0
        public void SnapshotsAreIsolated()
        {
            var counters  = new PipStateCounters();
            var snapshot1 = new PipStateCountersSnapshot();
            var snapshot2 = new PipStateCountersSnapshot();

            counters.CollectSnapshot(s_pipTypes, snapshot1);
            XAssert.AreEqual(0, snapshot1[PipState.Running]);

            counters.AccumulateInitialState(PipState.Running, PipType.Process);
            counters.CollectSnapshot(s_pipTypes, snapshot2);
            XAssert.AreEqual(0, snapshot1[PipState.Running]);
            XAssert.AreEqual(1, snapshot2[PipState.Running]);

            counters.AccumulateInitialState(PipState.Running, PipType.Process);
            XAssert.AreEqual(0, snapshot1[PipState.Running]);
            XAssert.AreEqual(1, snapshot2[PipState.Running]);
        }
示例#6
0
        public void SnapshotStress()
        {
            var counters = new PipStateCounters();

            bool[] exit = { false };

            var transitionThreads = new Thread[4];

            for (int i = 0; i < transitionThreads.Length; i++)
            {
                int threadId = i;
                transitionThreads[i] = new Thread(
                    () =>
                {
                    while (!Volatile.Read(ref exit[0]))
                    {
                        PipState[] orderedStates = s_pipStates.ToArray();
                        Shuffle(new Random(threadId), orderedStates);

                        // Create a new imaginary pip.
                        counters.AccumulateInitialState(PipState.Ignored, PipType.Process);

                        // Transition randomly until it is terminal.
                        var currentState = PipState.Ignored;
                        var priorStates  = new HashSet <PipState> {
                            currentState
                        };
                        int nextCandidateStateIndex = 0;

                        while (!currentState.IsTerminal())
                        {
                            nextCandidateStateIndex    = (nextCandidateStateIndex + 1) % orderedStates.Length;
                            PipState possibleNextState = orderedStates[nextCandidateStateIndex];

                            if (priorStates.Contains(possibleNextState))
                            {
                                // Cycle is possible.
                                break;
                            }

                            if (possibleNextState != currentState && currentState.CanTransitionTo(possibleNextState))
                            {
                                priorStates.Add(possibleNextState);
                                counters.AccumulateTransition(currentState, possibleNextState, PipType.Process);
                                currentState = possibleNextState;
                            }
                        }
                    }
                });
            }

            try
            {
                foreach (Thread t in transitionThreads)
                {
                    t.Start();
                }

                var snapshot = new PipStateCountersSnapshot();

                long sum = 0;
                while (sum < 100 * 1000)
                {
                    counters.CollectSnapshot(s_pipTypes, snapshot);

                    foreach (PipState state in s_pipStates)
                    {
                        XAssert.IsTrue(snapshot[state] >= 0);
                    }

                    long newSum = s_pipStates.Sum(s => snapshot[s]);
                    XAssert.IsTrue(newSum >= sum, "Counters must be (probably non-strictly) monotonic");
                    sum = newSum;
                }
            }
            finally
            {
                Volatile.Write(ref exit[0], true);
            }

            foreach (Thread t in transitionThreads)
            {
                t.Join();
            }
        }