public void IsReady_TileFetcherHasTileRequests_ReturnFalse() { // Setup using (var isReadyCalledEvent = new AutoResetEvent(false)) { var tileInfo = new TileInfo(); var mocks = new MockRepository(); var tileProvider = mocks.Stub <ITileProvider>(); tileProvider.Stub(p => p.GetTile(tileInfo)) .WhenCalled(invocation => isReadyCalledEvent.WaitOne(100)) .Return(null); mocks.ReplayAll(); using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200)) { fetcher.GetTile(tileInfo); // Call bool fetcherIsReady = fetcher.IsReady(); // Assert isReadyCalledEvent.Set(); Assert.IsFalse(fetcherIsReady); mocks.VerifyAll(); } } }
public void GetTile_TileInPersistentCacheInUse_ReturnNull() { // Setup var info = new TileInfo(); var data = new byte[0]; var mocks = new MockRepository(); var tileProvider = mocks.Stub <ITileProvider>(); tileProvider.Stub(tp => tp.GetTile(info)).Return(data); var persistentCache = mocks.Stub <ITileCache <byte[]> >(); persistentCache.Stub(c => c.Find(info.Index)).Throw(new IOException()); mocks.ReplayAll(); using (var fetcherFiredAsyncEvent = new AutoResetEvent(false)) using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200, persistentCache)) { fetcher.TileReceived += (sender, args) => fetcherFiredAsyncEvent.Set(); fetcher.QueueEmpty += (sender, args) => fetcherFiredAsyncEvent.Set(); byte[] fetchedData = fetcher.GetTile(info); // Assert Assert.IsNull(fetchedData); if (fetcherFiredAsyncEvent.WaitOne(allowedTileFetchTime)) { Assert.Fail("TileFetcher should not fire asynchronous events if tile is retrieved from cache."); } mocks.VerifyAll(); } }
public void DropAllPendingTileRequests_TileFetcherIsProcessingRequests_RequestsAreDropped() { // Setup var info = new TileInfo(); var data = new byte[0]; using (var blockingEvent = new ManualResetEvent(false)) { var blockingTileProvider = new TileProviderStub(blockingEvent) { TileDataToReturn = data }; using (var fetcherIsDoneEvent = new ManualResetEvent(false)) using (var fetcher = new AsyncTileFetcher(blockingTileProvider, 100, 200)) { fetcher.TileReceived += (sender, args) => fetcherIsDoneEvent.Set(); fetcher.QueueEmpty += (sender, args) => fetcherIsDoneEvent.Set(); byte[] fetchedData = fetcher.GetTile(info); // Precondition Assert.IsNull(fetchedData); // Call fetcher.DropAllPendingTileRequests(); Assert.IsFalse(fetcherIsDoneEvent.WaitOne(allowedTileFetchTime), "TileFetcher should have dropped request."); } } }
public void GetTile_TileAlreadyFetched_GetTileFromMemoryCache() { // Setup var info = new TileInfo(); var data = new byte[0]; var mocks = new MockRepository(); var tileProvider = mocks.Stub <ITileProvider>(); tileProvider.Stub(tp => tp.GetTile(info)).Return(data); var persistentCache = mocks.Stub <ITileCache <byte[]> >(); persistentCache.Stub(c => c.Find(info.Index)).Return(null); persistentCache.Stub(c => c.Add(info.Index, data)); mocks.ReplayAll(); using (var fetcherFiredAsyncEvent = new AutoResetEvent(false)) using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200, persistentCache)) { fetcher.QueueEmpty += (sender, args) => fetcherFiredAsyncEvent.Set(); byte[] fetchedData = fetcher.GetTile(info); // Precondition Assert.IsNull(fetchedData, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); if (!fetcherFiredAsyncEvent.WaitOne(allowedTileFetchTime)) { Assert.Fail("TileFetcher did not respond within timelimit."); } fetcherFiredAsyncEvent.Reset(); // Assert fetchedData = fetcher.GetTile(info); Assert.AreSame(data, fetchedData); if (fetcherFiredAsyncEvent.WaitOne(allowedTileFetchTime)) { Assert.Fail("TileFetcher should not fire asynchronous events if tile is retrieved from cache."); } mocks.VerifyAll(); } }
public void GetTile_TileNotCachedAnywhere_GetTileAsynchronouslyFromTileProvider() { // Setup var info = new TileInfo(); var data = new byte[0]; var mocks = new MockRepository(); var tileProvider = mocks.Stub <ITileProvider>(); tileProvider.Stub(tp => tp.GetTile(info)).Return(data); var persistentCache = mocks.Stub <ITileCache <byte[]> >(); persistentCache.Stub(c => c.Find(info.Index)).Return(null); persistentCache.Expect(c => c.Add(info.Index, data)); mocks.ReplayAll(); using (var fetcherIsDoneEvent = new AutoResetEvent(false)) using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200, persistentCache)) { TileReceivedEventArgs receivedArguments = null; var tileReceivedCounter = 0; fetcher.TileReceived += (sender, args) => { receivedArguments = args; tileReceivedCounter++; }; var queueEmptyCounter = 0; fetcher.QueueEmpty += (sender, args) => { queueEmptyCounter++; fetcherIsDoneEvent.Set(); }; // Call byte[] fetchedData = fetcher.GetTile(info); // Assert Assert.IsNull(fetchedData, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); if (fetcherIsDoneEvent.WaitOne(allowedTileFetchTime)) { Assert.AreEqual(1, tileReceivedCounter); Assert.AreSame(data, receivedArguments.Tile); Assert.AreSame(info, receivedArguments.TileInfo); Assert.AreEqual(1, queueEmptyCounter); } else { Assert.Fail("TileFetcher did not respond within timelimit."); } } mocks.VerifyAll(); }
public void GetTile_TileFetcherDisposed_ThrowObjectDisposedException() { // Setup var mocks = new MockRepository(); var tileProvider = mocks.Stub <ITileProvider>(); mocks.ReplayAll(); var tileFetcher = new AsyncTileFetcher(tileProvider, 1, 2); tileFetcher.Dispose(); var tileInfo = new TileInfo(); // Call TestDelegate call = () => tileFetcher.GetTile(tileInfo); // Assert string objectName = Assert.Throws <ObjectDisposedException>(call).ObjectName; Assert.AreEqual("AsyncTileFetcher", objectName); mocks.VerifyAll(); }
public void GivenTileFetcherWithoutCachedTile_WhenGettingTileFailsForFirstTime_ThenTileFetcherTriesSecondTime() { // Setup var info = new TileInfo(); var data = new byte[0]; var mocks = new MockRepository(); var tileProvider = mocks.Stub <ITileProvider>(); using (mocks.Ordered()) { var callCount = 0; tileProvider.Stub(tp => tp.GetTile(info)) .WhenCalled(invocation => { if (++callCount == 1) { throw new Exception("1st attempt fails."); } }) .Return(data); } var persistentCache = mocks.Stub <ITileCache <byte[]> >(); persistentCache.Stub(c => c.Find(info.Index)).Return(null); persistentCache.Expect(c => c.Add(info.Index, data)); mocks.ReplayAll(); using (var fetcherIsDoneEvent = new AutoResetEvent(false)) using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200, persistentCache)) { TileReceivedEventArgs receivedArguments = null; var tileReceivedCounter = 0; fetcher.TileReceived += (sender, args) => { receivedArguments = args; tileReceivedCounter++; }; var queueEmptyCounter = 0; fetcher.QueueEmpty += (sender, args) => { queueEmptyCounter++; fetcherIsDoneEvent.Set(); }; // Call byte[] fetchedData = fetcher.GetTile(info); // Assert Assert.IsNull(fetchedData, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); if (fetcherIsDoneEvent.WaitOne(allowedTileFetchTime)) { Assert.AreEqual(1, tileReceivedCounter); Assert.AreSame(data, receivedArguments.Tile); Assert.AreSame(info, receivedArguments.TileInfo); Assert.AreEqual(1, queueEmptyCounter); } else { Assert.Fail("TileFetcher did not respond within timelimit."); } mocks.VerifyAll(); } }
public void GivenTileFetcherWithoutCachedTile_WhenGettingSameTimeMultipleTimes_IgnoreDuplicateRequests() { // Given var info = new TileInfo(); var data = new byte[0]; using (var allRequestsDoneEvent = new ManualResetEvent(false)) { var tileProvider = new TileProviderStub(allRequestsDoneEvent) { TileDataToReturn = data }; using (var fetcherIsDoneEvent = new ManualResetEvent(false)) using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200)) { TileReceivedEventArgs receivedArguments = null; var tileReceivedCounter = 0; fetcher.TileReceived += (sender, args) => { receivedArguments = args; tileReceivedCounter++; }; var queueEmptyCounter = 0; fetcher.QueueEmpty += (sender, args) => { queueEmptyCounter++; fetcherIsDoneEvent.Set(); }; // When byte[] fetchedData1 = fetcher.GetTile(info); byte[] fetchedData2 = fetcher.GetTile(info); byte[] fetchedData3 = fetcher.GetTile(info); byte[] fetchedData4 = fetcher.GetTile(info); Assert.IsTrue(allRequestsDoneEvent.Set()); // Assert if (fetcherIsDoneEvent.WaitOne(allowedTileFetchTime)) { Assert.AreEqual(1, tileProvider.GetTileCallCount); Assert.AreEqual(1, tileReceivedCounter); Assert.AreSame(data, receivedArguments.Tile); Assert.AreSame(info, receivedArguments.TileInfo); Assert.AreEqual(1, queueEmptyCounter); } else { Assert.Fail("TileFetcher did not respond within timelimit."); } Assert.IsNull(fetchedData1, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); Assert.IsNull(fetchedData2, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); Assert.IsNull(fetchedData3, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); Assert.IsNull(fetchedData4, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); } } }