public void CachedValuesTest()
        {
            var input = new[] { 1, 2, 1, 3, 1 };
            var fixture = new QueuedAsyncMRUCache<int, int>(x => x * 5, 2);

            var dontcare = input.Select(x => fixture.Get(x)).ToArray();

            var output = fixture.CachedValues().ToArray();
            Assert.IsTrue(output.Length == 2);
        }
        public void CacheShouldBlockOnceWeHitOurConcurrentLimit()
        {
            var fixture = new QueuedAsyncMRUCache<int, int>(x => { Thread.Sleep(1000); return x * 5; }, 5, 3);

            assertStopwatch(new TimeSpan(0, 0, 0, 0, 200), () => {
                fixture.AsyncGet(1);
                fixture.AsyncGet(2);
            });

            assertStopwatch(new TimeSpan(0, 0, 0, 0, 2500), () => {
                Assert.AreEqual(15, fixture.Get(3));
            });
        }
        public void BlockingGetShouldRethrowExceptions()
        {
            var input = new[] { 5, 2, 10, 0/*boom!*/, 5 };
            var fixture = new QueuedAsyncMRUCache<int, int>(x => { Thread.Sleep(1000); return 50 / x; }, 5, 5);
            int[] output = {0};

            bool did_throw = false;
            try {
                output = input.Select(x => fixture.Get(x)).ToArray();
            } catch(Exception ex) {
                did_throw = true;
                this.Log().Debug("Exception thrown", ex);
            }

            output.Run(x => this.Log().Debug(x));
            Assert.IsTrue(did_throw);
        }
        public void GetTest()
        {
            var input = new[] { 1, 1, 1, 1, 1 };
            var fixture = new QueuedAsyncMRUCache<int, int>(x => { Thread.Sleep(1000); return x * 5; }, 5, 2);

            assertStopwatch(new TimeSpan(0,0,0,0,1100), () => {
                input.Select(x => fixture.Get(x)).ToArray();
            });

            assertStopwatch(new TimeSpan(0,0,0,0,100), () => {
                Assert.AreEqual(5, fixture.Get(1));
            });
        }
        public void GetTest()
        {
            var input = new[] { 1, 1, 1, 1, 1 };
            var sched = new TestScheduler();
            QueuedAsyncMRUCache<int, int> fixture;

            var delay = TimeSpan.FromSeconds(1.0);
            using (TestUtils.WithTestScheduler(sched)) {
                fixture = new QueuedAsyncMRUCache<int, int>(x => Observable.Return(x*5).Delay(delay, sched).First(), 5, 2);
            }

            int result = 0;
            var t = new Task(() => {
                foreach (int i in input) {
                    this.Log().InfoFormat("Counter is {0}", result);
                    result += fixture.Get(i);
                }
            });
            t.Start();

            Thread.Sleep(200);

            this.Log().Info("Running to t=0");
            sched.RunTo(sched.FromTimeSpan(TimeSpan.FromMilliseconds(500)));
            Assert.AreEqual(0, result);
            this.Log().Info("Running to t=1200");
            sched.RunTo(sched.FromTimeSpan(TimeSpan.FromMilliseconds(1200)));

            Thread.Sleep(200);

            Assert.AreEqual(25, result);

            this.Log().Info("Running to end");
            sched.Run();
            Assert.AreEqual(25, result);
        }