예제 #1
0
        public void WhenConstructorFailsVersionIsNotIncremented()
        {
            bool firstConstructorInvocation = true;
            var  reloader = new Reloader <int>(
                constructor: () =>
            {
                if (!firstConstructorInvocation)
                {
                    throw new NotImplementedException();
                }

                firstConstructorInvocation = false;
                return(42);
            });

            // constructor not called yet --> current version 0
            XAssert.AreEqual(0, reloader.CurrentVersion);

            // constructor called the first time --> doesn't throw --> version incremented
            reloader.Reload(0);
            XAssert.AreEqual(1, reloader.CurrentVersion);

            // constructor called the second time --> throws --> version stays the same
            Assert.Throws <NotImplementedException>(() => reloader.Reload(1));
            XAssert.AreEqual(1, reloader.CurrentVersion);
        }
예제 #2
0
        public void DestructorNotCalledBeforeReloaderIsDisposed()
        {
            int constructorCnt = 0;
            int destructorCnt  = 0;

            // create reloader and assert constructor was called
            var reloader = new Reloader <int>(
                constructor: () => Interlocked.Increment(ref constructorCnt),
                destructor: (i) => Interlocked.Increment(ref destructorCnt));

            XAssert.AreEqual(0, constructorCnt, "Constructor should not be called as soon as Reloader is created");
            XAssert.AreEqual(0, destructorCnt, "Destructor should not be called before Reloader is disposed.");

            // reload and assert constructor was called again, but no destructor
            reloader.Reload(reloader.CurrentVersion);
            XAssert.AreEqual(1, constructorCnt);
            XAssert.AreEqual(0, destructorCnt, "Destructor should not be called before Reloader is disposed.");

            // reload and assert constructor was called again, but no destructor
            reloader.Reload(reloader.CurrentVersion);
            XAssert.AreEqual(2, constructorCnt);
            XAssert.AreEqual(0, destructorCnt, "Destructor should not be called before Reloader is disposed.");

            // dispose and assert that destructor was called twice (once for each reloaded value)
            reloader.Dispose();
            XAssert.AreEqual(2, destructorCnt, "Destructor wasn't called for each created value.");
        }
예제 #3
0
        public void TestConcurrentReloadsOfSameVersionCreateOnlyOneNewValue()
        {
            int cnt = 0;

            using (var reloader = new Reloader <string>(() => "hi" + Interlocked.Increment(ref cnt)))
            {
                // call 'Reload(startVersion)' concurrently from multiple threads
                var startVersion = reloader.CurrentVersion;
                var range        = Enumerable.Range(0, 100).ToList();
                var threads      = range.Select(_ => new Thread(() =>
                {
                    reloader.Reload(startVersion);
                    var instance = reloader.CurrentVersionedValue;

                    // assert each thread gets the same instance
                    XAssert.AreEqual(startVersion + 1, instance.Version);
                    XAssert.AreEqual("hi1", instance.Value);
                })).ToList();
                ConcurrencyTest.Start(threads);
                ConcurrencyTest.Join(threads);

                // assert only 1 new value was created
                XAssert.AreEqual(startVersion + 1, reloader.CurrentVersion);
                XAssert.AreEqual(startVersion + 1, reloader.CurrentVersionedValue.Version);
                XAssert.AreEqual("hi1", reloader.CurrentVersionedValue.Value);
            }
        }
예제 #4
0
 public void Reload()
 {
     if (reloader == null)
     {
         return;
     }
     reloader.Reload();
 }