Exemplo n.º 1
0
        public void ShouldCreateNewContextObjectForEachTestCase()
        {
            _runner.ContextFactoryFunc = () => new DummyImmutableRef();
            var lastSetContextObject = new AtomicRef <DummyImmutableRef>(null);
            var testCase             = CreateNewTestCase(ctx => lastSetContextObject.Set(ctx));

            _runner.ExecuteCustomTestCase(testCase);
            var firstContextObj = lastSetContextObject.Value;

            _runner.ExecuteCustomTestCase(testCase);
            Assert.AreNotEqual(firstContextObj, lastSetContextObject.Value);
        }
Exemplo n.º 2
0
        public void EquatableMappedTryExchange()
        {
            const int NumIterations = 100_000;

            var equatableRunner = _equatableRefRunnerFactory.NewRunner(new DummyEquatableRef(0L));

            // Test: Return value of method is always consistent
            equatableRunner.ExecuteFreeThreadedTests(
                atomicRef => {
                var curValue = atomicRef.Value;
                var(wasSet, prevValue, CurrentValue) = atomicRef.TryExchange(c => new DummyEquatableRef(c.LongProp + 1L), curValue);
                if (wasSet)
                {
                    Assert.AreEqual(curValue, prevValue);
                    Assert.AreEqual(new DummyEquatableRef(prevValue.LongProp + 1L), CurrentValue);
                }
                else
                {
                    Assert.AreNotEqual(curValue, prevValue);
                }
            },
                NumIterations
                );

            // Test: Method does what is expected and is safe from race conditions
            equatableRunner.AllThreadsTearDown = atomicRef => Assert.AreEqual(NumIterations, atomicRef.Value.LongProp);
            equatableRunner.ExecuteFreeThreadedTests(
                atomicRef => {
                while (true)
                {
                    var curValue = atomicRef.Value;
                    if (curValue.LongProp == NumIterations)
                    {
                        return;
                    }
                    var(wasSet, prevValue, CurrentValue) = atomicRef.TryExchange(c => new DummyEquatableRef(c.LongProp + 1L), curValue);
                    if (wasSet)
                    {
                        Assert.AreEqual(curValue, prevValue);
                        Assert.AreEqual(new DummyEquatableRef(prevValue.LongProp + 1L), CurrentValue);
                    }
                    else
                    {
                        Assert.AreNotEqual(curValue, prevValue);
                    }
                }
            }
                );
            equatableRunner.AllThreadsTearDown = null;

            // Test: Method always exhibits coherency for consecutive reads from external threads
            equatableRunner.ExecuteContinuousCoherencyTests(
                atomicRef => {
                var curValue = atomicRef.Value;
                atomicRef.TryExchange(c => new DummyEquatableRef(c.LongProp + 1L), curValue);
            },
                NumIterations,
                atomicRef => atomicRef.Value,
                (prev, cur) => Assert.True(cur.LongProp >= prev.LongProp)
                );

            // Test: Custom equality is used for types that provide it
            var dummyImmutableA = new DummyImmutableRef("Xenoprimate Rules");
            var dummyImmutableB = new DummyImmutableRef("Xenoprimate Rules");
            var dummyEquatableA = new DummyEquatableRef("Xenoprimate Rules");
            var dummyEquatableB = new DummyEquatableRef("Xenoprimate Rules");
            var atomicImmutable = new AtomicRef <DummyImmutableRef>();
            var atomicEquatable = new AtomicRef <DummyEquatableRef>();

            atomicImmutable.Set(dummyImmutableA);
            Assert.AreEqual(false, atomicImmutable.TryExchange(c => new DummyImmutableRef(), dummyImmutableB).ValueWasSet);
            atomicEquatable.Set(dummyEquatableA);
            Assert.AreEqual(true, atomicEquatable.TryExchange(c => new DummyEquatableRef(), dummyEquatableB).ValueWasSet);
        }
Exemplo n.º 3
0
        public void FastTryExchangeRefOnly()
        {
            const int NumIterations = 100_000;

            var runner = _equatableRefRunnerFactory.NewRunner(new DummyEquatableRef(0L));

            // Test: Return value of method is always consistent
            runner.ExecuteFreeThreadedTests(
                atomicRef => {
                var curValue  = atomicRef.Value;
                var newValue  = new DummyEquatableRef(curValue.LongProp + 1L);
                var prevValue = atomicRef.FastTryExchangeRefOnly(newValue, curValue);
                var wasSet    = ReferenceEquals(prevValue, curValue);
                var setValue  = wasSet ? newValue : prevValue;
                if (wasSet)
                {
                    Assert.True(ReferenceEquals(curValue, prevValue));
                    Assert.True(ReferenceEquals(newValue, setValue));
                }
                else
                {
                    Assert.False(ReferenceEquals(curValue, prevValue));
                    Assert.True(ReferenceEquals(setValue, prevValue));
                }
            },
                NumIterations
                );

            // Test: Method does what is expected and is safe from race conditions
            runner.AllThreadsTearDown = atomicRef => Assert.AreEqual(NumIterations, atomicRef.Value.LongProp);
            runner.ExecuteFreeThreadedTests(
                atomicRef => {
                while (true)
                {
                    var curValue = atomicRef.Value;
                    if (curValue.LongProp == NumIterations)
                    {
                        return;
                    }
                    var newValue  = new DummyEquatableRef(curValue.LongProp + 1L);
                    var prevValue = atomicRef.FastTryExchangeRefOnly(newValue, curValue);
                    var wasSet    = ReferenceEquals(prevValue, curValue);
                    var setValue  = wasSet ? newValue : prevValue;
                    if (wasSet)
                    {
                        Assert.True(ReferenceEquals(curValue, prevValue));
                        Assert.True(ReferenceEquals(newValue, setValue));
                    }
                    else
                    {
                        Assert.False(ReferenceEquals(curValue, prevValue));
                        Assert.True(ReferenceEquals(setValue, prevValue));
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // Test: Method always exhibits coherency for consecutive reads from external threads
            runner.ExecuteContinuousCoherencyTests(
                atomicRef => {
                var curValue = atomicRef.Value;
                var newValue = new DummyEquatableRef(curValue.LongProp + 1L);
                atomicRef.FastTryExchangeRefOnly(newValue, curValue);
            },
                NumIterations,
                atomicRef => atomicRef.Value,
                (prev, cur) => Assert.True(cur.LongProp >= prev.LongProp)
                );

            // Test: Custom equality is used for types that provide it
            var dummyImmutableA = new DummyImmutableRef("Xenoprimate Rules");
            var dummyImmutableB = new DummyImmutableRef("Xenoprimate Rules");
            var dummyEquatableA = new DummyEquatableRef("Xenoprimate Rules");
            var dummyEquatableB = new DummyEquatableRef("Xenoprimate Rules");
            var atomicImmutable = new AtomicRef <DummyImmutableRef>();
            var atomicEquatable = new AtomicRef <DummyEquatableRef>();

            atomicImmutable.Set(dummyImmutableA);
            atomicImmutable.FastTryExchangeRefOnly(new DummyImmutableRef(), dummyImmutableB);
            Assert.AreEqual(dummyImmutableA, atomicImmutable.Value);
            atomicEquatable.Set(dummyEquatableA);
            var newVal = new DummyEquatableRef();

            atomicEquatable.FastTryExchangeRefOnly(newVal, dummyEquatableB);
            Assert.AreEqual(dummyEquatableA, atomicEquatable.Value);
        }
Exemplo n.º 4
0
        public void API_CombineRemoveRemoveAll()
        {
            var lastRecordedInput = new AtomicRef <string>();
            Func <string, string> initialValue = s => { lastRecordedInput.Set(s); return(s.ToUpper()); };

            var target = new AtomicDelegate <Func <string, string> >(initialValue);

            var combineRes = target.Combine(s => s.ToLower());

            Assert.AreEqual(initialValue, combineRes.PreviousValue);
            Assert.AreEqual("TEST", combineRes.PreviousValue("Test"));
            Assert.AreEqual("test", combineRes.CurrentValue("Test"));

            Assert.AreEqual("Test", lastRecordedInput.Value);

            target.TryInvoke("Input");
            Assert.AreEqual("Input", lastRecordedInput.Value);

            combineRes = target.Combine(s => s + s);
            Assert.AreEqual("abcabc", target.Value("abc"));
            Assert.AreEqual("abc", lastRecordedInput.Value);
            Assert.AreEqual(combineRes.CurrentValue, target.Value);

            var removeRes = target.Remove(initialValue);

            Assert.AreEqual("qwertyqwerty", removeRes.PreviousValue("qwerty"));
            Assert.AreEqual("qwerty", lastRecordedInput.Value);
            Assert.AreEqual("ijklijkl", removeRes.CurrentValue("ijkl"));
            Assert.AreEqual("qwerty", lastRecordedInput.Value);
            Assert.AreEqual(removeRes.CurrentValue, target.Value);

            removeRes = target.Remove(c => "this delegate was never added");
            Assert.AreEqual(removeRes.CurrentValue, removeRes.PreviousValue);
            Assert.AreEqual(target.Value, removeRes.PreviousValue);

            var invocationCounter = new AtomicInt();
            Func <string, string> CurrentValue = s => { invocationCounter.Increment(); return(s[0].ToString()); };

            target.Combine(CurrentValue);
            target.Combine(CurrentValue);
            target.Combine(CurrentValue);

            Assert.AreEqual((true, "r"), target.TryInvoke("rrrrr"));
            Assert.AreEqual(3, invocationCounter.Value);

            target.Remove(CurrentValue);
            Assert.AreEqual((true, "r"), target.TryInvoke("rrrrr"));
            Assert.AreEqual(5, invocationCounter.Value);

            removeRes = target.RemoveAll(CurrentValue);
            Assert.AreEqual((true, "rrrrrrrrrr"), target.TryInvoke("rrrrr"));
            Assert.AreEqual(5, invocationCounter.Value);
            Assert.AreEqual("rrrrrrrrrr", removeRes.CurrentValue("rrrrr"));
            Assert.AreEqual("r", removeRes.PreviousValue("rrrrr"));

            removeRes = target.RemoveAll(CurrentValue);
            Assert.AreEqual((true, "rrrrrrrrrr"), target.TryInvoke("rrrrr"));
            Assert.AreEqual(7, invocationCounter.Value);
            Assert.AreEqual("rrrrrrrrrr", removeRes.CurrentValue("rrrrr"));
            Assert.AreEqual(removeRes.CurrentValue, removeRes.PreviousValue);
        }