public void CanAddMessagesToCache()
 {
     // 5 secs to purge
     var timeToPurge = TimeSpan.FromSeconds(5);
     var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);
     cache.AddToCache(_someBatches);
     Assert.IsTrue(cache.Size == _someBatches.Count);
 }
 public void CannotManuallyTellCacheToPurge()
 {
     // 5 secs to purge
     var timeToPurge = TimeSpan.FromSeconds(5);
     var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);
     cache.AddToCache(_someBatches);
     IList<IBatchContainer> purged;
     cache.TryPurgeFromCache(out purged); // Should we assert true/false? what should it return
     Assert.IsNull(purged);
     Assert.IsTrue(cache.Size == _someBatches.Count);
 }
        public void CachePurgesOldMessages()
        {
            // 2 secs to purge
            var timeToPurge = TimeSpan.FromSeconds(2);
            var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);
            cache.AddToCache(_someBatches);
            Task.Delay(timeToPurge).Wait();

            // You have to do another add to trigger purging:
            cache.AddToCache(_someBatches.Take(1).ToList());
            // should now have only the last one added
            Assert.IsTrue(cache.Size == 1);
        }
        public void EmptyCacheSouldntMoveAndShouldReturnNull()
        {
            var timeToPurge = TimeSpan.FromSeconds(5);
            var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);

            Exception ex;
            var cursor = cache.GetCacheCursor(_streamGuid, _streamNamespace, null);
            Assert.IsFalse(cursor.MoveNext());
            Assert.IsNull(cursor.GetCurrent(out ex));
            Assert.IsNull(ex);

            cursor = cache.GetCacheCursor(_streamGuid, _streamNamespace, new TimeSequenceToken(DateTime.Today));
            Assert.IsFalse(cursor.MoveNext());
            Assert.IsNull(cursor.GetCurrent(out ex));
            Assert.IsNull(ex);
        }
        public void ReplayOnlyRelevantMessages()
        {
            var timeToPurge = TimeSpan.FromSeconds(10);
            var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);

            // add batches for this stream:
            cache.AddToCache(_someBatches.Take(5).ToList());
            // add batches for another stream:
            cache.AddToCache(_otherBatches.Take(5).ToList());
            // add batches for this stream:
            cache.AddToCache(_someBatches.Skip(5).ToList());
            // add batches for another stream:
            cache.AddToCache(_otherBatches.Skip(5).ToList());

            var firstBatch = _someBatches.First() as PipeQueueAdapterBatchContainer;
            var token = firstBatch.RealToken;
            // We only want to read messages for stream with this GUID in this namespace:
            var cursor = cache.GetCacheCursor(_streamGuid, _streamNamespace, new TimeSequenceToken(DateTime.Today));

            // check that we read only the relevant batches for this stream
            foreach (var b in _someBatches)
            {
                // Move
                Assert.IsTrue(cursor.MoveNext());
                // Read the same batch
                Exception ex;
                Assert.IsTrue(b == cursor.GetCurrent(out ex));
                Assert.IsTrue(ex == null);
            }

            // Can't move any more
            Assert.IsFalse(cursor.MoveNext());
        }
        public void ReplayFromStart()
        {
            var timeToPurge = TimeSpan.FromSeconds(5);
            var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);
            cache.AddToCache(_someBatches);

            // start time to read is the time of the first batch
            var firstBatch = _someBatches.First() as PipeQueueAdapterBatchContainer;
            var token = firstBatch.RealToken;

            var cursor = cache.GetCacheCursor(_streamGuid, _streamNamespace, token);

            foreach (var b in _someBatches)
            {
                // Move
                Assert.IsTrue(cursor.MoveNext());
                // Read the same batch
                Exception ex;
                Assert.IsTrue(b == cursor.GetCurrent(out ex));
                Assert.IsTrue(ex == null);
            }

            // Can't move any more
            Assert.IsFalse(cursor.MoveNext());
        }
        public void ReplayFromLastMessageWhenNoTokenGiven()
        {
            var timeToPurge = TimeSpan.FromSeconds(5);
            var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);
            cache.AddToCache(_someBatches);

            // Give a null token
            var cursor = cache.GetCacheCursor(_streamGuid, _streamNamespace, null);
            Exception ex;
            // Should be able to get the last message
            Assert.IsTrue(cursor.MoveNext());
            Assert.IsTrue(cursor.GetCurrent(out ex) == _someBatches.Last());
            Assert.IsNull(ex);
            // That should have been the last message, so there should be no more to read after it
            Assert.IsFalse(cursor.MoveNext());
            // Still on the same message:
            Assert.IsTrue(cursor.GetCurrent(out ex) == _someBatches.Last());
            Assert.IsNull(ex);
        }
        public void ReadAsDifferentStreamWithNoTokenShouldReturnNoMessages2()
        {
            // 2 secs to purge
            var timeToPurge = TimeSpan.FromSeconds(5);
            var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);
            cache.AddToCache(_someBatches);

            var cursor = cache.GetCacheCursor(_anotherStreamGuid, _streamNamespace, null);

            // Can't move
            Assert.IsFalse(cursor.MoveNext());
        }
        public void ReadAsDifferentStreamShouldReturnNoMessages()
        {
            // 2 secs to purge
            var timeToPurge = TimeSpan.FromSeconds(5);
            var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);
            cache.AddToCache(_someBatches);

            // start time to read is the time of the first batch
            var firstBatch = _someBatches.First() as PipeQueueAdapterBatchContainer;
            var token = firstBatch.RealToken;

            var cursor = cache.GetCacheCursor(_anotherStreamGuid, _streamNamespace, token);

            // Can't move
            Assert.IsFalse(cursor.MoveNext());
        }
        public void NoMessagesWhenTokenRequestedIsTooNew()
        {
            var timeToPurge = TimeSpan.FromSeconds(5);
            var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);
            cache.AddToCache(_someBatches);

            // get last token:
            var lastToken = (_someBatches.Last() as PipeQueueAdapterBatchContainer).RealToken;
            var newerToken = new TimeSequenceToken(lastToken.Timestamp.AddMilliseconds(1));

            var cursor = cache.GetCacheCursor(_streamGuid, _streamNamespace, newerToken);
            Assert.IsFalse(cursor.MoveNext());
        }
        public void NewCursorShouldBeForwardedWhenMessagesArePurged()
        {
            var timeToPurge = TimeSpan.FromSeconds(7);
            var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);
            var firstBatches = _someBatches.Take(5);
            cache.AddToCache(firstBatches.ToList());

            // get a cursor on the first message:
            var cursor = cache.GetCacheCursor(_streamGuid, _streamNamespace, new TimeSequenceToken(DateTime.Today));

            var moreBatches = _someBatches.Skip(5).ToList();
            // trigger purge by adding again, the previous batches are 10, 9, ..., 6 seconds old so the earliest 3 will be purged given 7 seconds to purge
            var timeNow = DateTime.UtcNow;
            cache.AddToCache(moreBatches);

            var purged = firstBatches.Count(x => (timeNow - (x.SequenceToken as TimeSequenceToken).Timestamp) > timeToPurge);
            var countRemains = firstBatches.Count() - purged;

            Assert.IsTrue(cache.Size == countRemains + moreBatches.Count);
            // cursor now should be forwarded and should read batches at indices: 3, 4, .. count-1
            Exception ex;
            foreach (var b in _someBatches.Skip(purged))
            {
                Assert.IsTrue(cursor.MoveNext());
                var current = cursor.GetCurrent(out ex);
                Assert.IsTrue(b == current);
                Assert.IsNull(ex);
            }
            // no more
            Assert.IsFalse(cursor.MoveNext());
        }
        public void LaggingCursorShouldBeForwardedWhenAllMessagesArePurged()
        {
            var timeToPurge = TimeSpan.FromSeconds(1);
            var cache = new QueueCache(QueueId.GetQueueId(0), timeToPurge, _mockLogger.Object);
            cache.AddToCache(_someBatches.Take(5).ToList());

            // get a cursor on the first message:
            var cursor = cache.GetCacheCursor(_streamGuid, _streamNamespace, new TimeSequenceToken(DateTime.Today));

            // Set it on first message:
            cursor.MoveNext();
            var moreBatches = _someBatches.Skip(5).ToList();
            // trigger purge by adding again, all previous messages should be purged now
            cache.AddToCache(moreBatches);
            // Only new messages should exist
            Assert.IsTrue(cache.Size == moreBatches.Count);
            // cursor now should be forwarded and should read batches at indices: 3, 4, .. count-1
            Exception ex;
            foreach (var b in moreBatches)
            {
                Assert.IsTrue(cursor.MoveNext());
                var current = cursor.GetCurrent(out ex);
                Assert.IsTrue(b == current);
                Assert.IsNull(ex);
            }
            // no more
            Assert.IsFalse(cursor.MoveNext());
        }