public async Task TestFibonacciAsync()
        {
            var fibGetter1 = new FibGetter {
                callCount = 0
            };
            var fibGetter2 = new FibGetter {
                callCount = 0
            };

            var groupName = "Fibonacci";
            // Creating groupcache client for "Fibonacci" on peer1
            var peer1Group = GroupCache.GroupCache.NewGroup(groupName, fibGetter1, peer1Pool.GetPicker(groupName));
            // Creating groupcache client for "Fibonacci" on peer1
            var peer2Group = GroupCache.GroupCache.NewGroup(groupName, fibGetter2, peer2Pool.GetPicker(groupName));

            // Inject Stat class that count number execution of each internal operation
            var group1Stat = new UnitTestGroupStat();
            var group2Stat = new UnitTestGroupStat();

            peer1Group.Stats = group1Stat;
            peer2Group.Stats = group2Stat;

            fibGetter1.getter = peer1Group; // Use the groupcache to do recursive to compute fibonacci
            fibGetter2.getter = peer2Group; // Use the groupcache to do recursive to compute fibonacci

            using (var result1a = new MemoryStream())
            {
                await peer1Group.GetAsync("90", result1a, new CacheControl(), CancellationToken.None);

                var result1aStr = result1a.StreamToString();
                Assert.AreEqual("2880067194370816120", result1aStr);
            }


            Assert.AreEqual(group1Stat.PeerLoads + group2Stat.PeerLoads, group1Stat.ServerRequests + group2Stat.ServerRequests);
            Assert.AreEqual(91, group1Stat.LocalLoads + group2Stat.LocalLoads);
            Assert.AreEqual(91, fibGetter1.callCount + fibGetter2.callCount);

            using (var result1b = new MemoryStream())
            {
                await peer2Group.GetAsync("90", result1b, new CacheControl(), CancellationToken.None);

                var result1bStr = result1b.StreamToString();
                Assert.AreEqual("2880067194370816120", result1bStr);
            }
            Assert.AreEqual(91, fibGetter1.callCount + fibGetter2.callCount);
        }
        public void TestGroupForwarding()
        {
            var getter1 = new HelloGetter {
                peerName = "peer1"
            };
            var getter2 = new HelloGetter {
                peerName = "peer2"
            };

            var fooResponse = "foo";
            var barResponse = "bar";

            // Creating groupcache client for "TestGroupForwarding" on peer1
            var peer1Group = GroupCache.GroupCache.NewGroup("TestGroupForwarding", getter1, peer1Pool.GetPicker("TestGroupForwarding"));
            // Creating groupcache client for "TestGroupForwarding" on peer2
            var peer2Group = GroupCache.GroupCache.NewGroup("TestGroupForwarding", getter2, peer2Pool.GetPicker("TestGroupForwarding"));

            // Inject Stat class that count number execution of each internal operation
            var group1Stat = new UnitTestGroupStat();
            var group2Stat = new UnitTestGroupStat();

            peer1Group.Stats = group1Stat;
            peer2Group.Stats = group2Stat;

            using (var result1a = new MemoryStream())
                using (var result1b = new MemoryStream())
                    using (var result2a = new MemoryStream())
                        using (var result2b = new MemoryStream())
                        {
                            peer1Group.GetAsync("foo", result1a, new CacheControl(), CancellationToken.None).Wait();

                            peer1Group.GetAsync("bar", result1b, new CacheControl(), CancellationToken.None).Wait();

                            peer2Group.GetAsync("foo", result2a, new CacheControl(), CancellationToken.None).Wait();

                            peer2Group.GetAsync("bar", result2b, new CacheControl(), CancellationToken.None).Wait();

                            var result1aStr = result1a.StreamToString();
                            Assert.AreEqual(fooResponse, result1aStr);
                            var result1bStr = result1b.StreamToString();
                            Assert.AreEqual(barResponse, result1bStr);
                            var result2aStr = result2a.StreamToString();
                            Assert.AreEqual(fooResponse, result2aStr);
                            var result2bStr = result2b.StreamToString();
                            Assert.AreEqual(barResponse, result2bStr);
                        }


            using (var result3a = new MemoryStream())
                using (var result3b = new MemoryStream())
                    using (var result4a = new MemoryStream())
                        using (var result4b = new MemoryStream())
                        {
                            peer1Group.GetAsync("foo", result3a, new CacheControl(), CancellationToken.None).Wait();
                            result3a.Position = 0;
                            peer1Group.GetAsync("bar", result3b, new CacheControl(), CancellationToken.None).Wait();
                            result3b.Position = 0;
                            peer2Group.GetAsync("foo", result4a, new CacheControl(), CancellationToken.None).Wait();
                            result4a.Position = 0;
                            peer2Group.GetAsync("bar", result4b, new CacheControl(), CancellationToken.None).Wait();
                            result4b.Position = 0;
                        }

            // Verify that we are indeed caching the result
            Assert.AreEqual(2, getter1.callCount + getter2.callCount);
            Assert.AreEqual(2, group1Stat.LocalLoads + group2Stat.LocalLoads);
        }