public async Task ValidatesAbsoluteExpiration()
        {
            DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions();

            cacheOptions.AbsoluteExpiration = DateTime.UtcNow.AddHours(-1);

            CosmosCacheSession existingSession = new CosmosCacheSession();

            existingSession.SessionKey = "key";
            existingSession.Content    = new byte[0];
            Mock <ItemResponse <CosmosCacheSession> > mockedItemResponse = new Mock <ItemResponse <CosmosCacheSession> >();
            Mock <CosmosClient>      mockedClient    = new Mock <CosmosClient>();
            Mock <Container>         mockedContainer = new Mock <Container>();
            Mock <Database>          mockedDatabase  = new Mock <Database>();
            Mock <ContainerResponse> mockedResponse  = new Mock <ContainerResponse>();

            mockedResponse.Setup(c => c.StatusCode).Returns(HttpStatusCode.OK);
            mockedContainer.Setup(c => c.ReadContainerAsync(It.IsAny <ContainerRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(mockedResponse.Object);
            mockedClient.Setup(c => c.GetContainer(It.IsAny <string>(), It.IsAny <string>())).Returns(mockedContainer.Object);
            mockedClient.Setup(c => c.GetDatabase(It.IsAny <string>())).Returns(mockedDatabase.Object);
            mockedClient.Setup(x => x.Endpoint).Returns(new Uri("http://localhost"));
            CosmosCache cache = new CosmosCache(Options.Create(new CosmosCacheOptions()
            {
                DatabaseName  = "something",
                ContainerName = "something",
                CosmosClient  = mockedClient.Object
            }));

            await Assert.ThrowsAsync <ArgumentOutOfRangeException>(() => cache.SetAsync(existingSession.SessionKey, existingSession.Content, cacheOptions));
        }
        public async Task StoreSessionData()
        {
            const string sessionId  = "sessionId";
            const int    ttl        = 1400;
            const int    throughput = 2000;

            CosmosClientBuilder builder = new CosmosClientBuilder(ConfigurationManager.AppSettings["Endpoint"], ConfigurationManager.AppSettings["MasterKey"]);

            IOptions <CosmosCacheOptions> options = Options.Create(new CosmosCacheOptions()
            {
                ContainerName       = "session",
                DatabaseName        = CosmosCacheEmulatorTests.databaseName,
                ContainerThroughput = throughput,
                CreateIfNotExists   = true,
                ClientBuilder       = builder
            });

            CosmosCache cache = new CosmosCache(options);
            DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions();

            cacheOptions.SlidingExpiration = TimeSpan.FromSeconds(ttl);
            await cache.SetAsync(sessionId, new byte[0], cacheOptions);

            // Verify that container has been created

            CosmosCacheSession storedSession = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadItemAsync <CosmosCacheSession>(sessionId, new PartitionKey(sessionId));

            Assert.Equal(sessionId, storedSession.SessionKey);
        }
        public async Task SetAsyncCallsUpsert()
        {
            int ttl = 10;
            DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions();

            cacheOptions.SlidingExpiration = TimeSpan.FromSeconds(ttl);

            CosmosCacheSession existingSession = new CosmosCacheSession();

            existingSession.SessionKey = "key";
            existingSession.Content    = new byte[0];
            Mock <ItemResponse <CosmosCacheSession> > mockedItemResponse = new Mock <ItemResponse <CosmosCacheSession> >();
            Mock <CosmosClient>      mockedClient    = new Mock <CosmosClient>();
            Mock <Container>         mockedContainer = new Mock <Container>();
            Mock <Database>          mockedDatabase  = new Mock <Database>();
            Mock <ContainerResponse> mockedResponse  = new Mock <ContainerResponse>();

            mockedResponse.Setup(c => c.StatusCode).Returns(HttpStatusCode.OK);
            mockedContainer.Setup(c => c.ReadContainerAsync(It.IsAny <ContainerRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(mockedResponse.Object);
            mockedContainer.Setup(c => c.UpsertItemAsync <CosmosCacheSession>(It.Is <CosmosCacheSession>(item => item.SessionKey == existingSession.SessionKey && item.TimeToLive == ttl), It.IsAny <PartitionKey?>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(mockedItemResponse.Object);
            mockedClient.Setup(c => c.GetContainer(It.IsAny <string>(), It.IsAny <string>())).Returns(mockedContainer.Object);
            mockedClient.Setup(c => c.GetDatabase(It.IsAny <string>())).Returns(mockedDatabase.Object);
            mockedClient.Setup(x => x.Endpoint).Returns(new Uri("http://localhost"));
            CosmosCache cache = new CosmosCache(Options.Create(new CosmosCacheOptions()
            {
                DatabaseName  = "something",
                ContainerName = "something",
                CosmosClient  = mockedClient.Object
            }));

            await cache.SetAsync(existingSession.SessionKey, existingSession.Content, cacheOptions);

            mockedContainer.Verify(c => c.UpsertItemAsync <CosmosCacheSession>(It.Is <CosmosCacheSession>(item => item.SessionKey == existingSession.SessionKey && item.TimeToLive == ttl), It.IsAny <PartitionKey?>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Once);
        }
        public void ValidatesNullTtlDoesNotSerializeProperty()
        {
            CosmosCacheSession existingSession = new CosmosCacheSession();

            existingSession.SessionKey = "key";
            existingSession.Content    = new byte[0];
            string serialized = JsonConvert.SerializeObject(existingSession);

            Assert.False(serialized.Contains("\"ttl\""), "Session without expiration should not include ttl property.");
        }
Exemplo n.º 5
0
        public void ValidatesIsSlidingExpirationDoesSerializeProperty()
        {
            CosmosCacheSession existingSession = new CosmosCacheSession();

            existingSession.SessionKey          = "key";
            existingSession.Content             = new byte[0];
            existingSession.IsSlidingExpiration = true;
            string serialized = JsonConvert.SerializeObject(existingSession);

            Assert.True(serialized.Contains("\"isSlidingExpiration\""), "Session with sliding expiration should include isSlidingExpiration property.");
        }
        public void ValidatesCustomPartitionKeyCreatesProperty()
        {
            const string       pkProperty      = "notTheId";
            CosmosCacheSession existingSession = new CosmosCacheSession();

            existingSession.SessionKey            = "key";
            existingSession.Content               = new byte[0];
            existingSession.PartitionKeyAttribute = pkProperty;
            string serialized = JsonConvert.SerializeObject(existingSession);

            Assert.True(serialized.Contains($"\"{pkProperty}\""), "Missing custom partition key.");
        }
        public void ValidatesContract()
        {
            const string       expectedContract = "{\"id\":\"key\",\"content\":\"AQ==\",\"ttl\":5,\"isSlidingExpiration\":true}";
            CosmosCacheSession existingSession  = new CosmosCacheSession();

            existingSession.SessionKey          = "key";
            existingSession.IsSlidingExpiration = true;
            existingSession.TimeToLive          = 5;
            existingSession.Content             = new byte[1] {
                1
            };
            string serialized = JsonConvert.SerializeObject(existingSession);

            Assert.Equal(expectedContract, serialized);
        }
Exemplo n.º 8
0
        public async Task SlidingAndAbsoluteExpiration()
        {
            const string sessionId   = "sessionId";
            const int    ttl         = 10;
            const int    absoluteTtl = 15;
            const int    throughput  = 400;

            CosmosClientBuilder builder = new CosmosClientBuilder(ConfigurationManager.AppSettings["Endpoint"], ConfigurationManager.AppSettings["MasterKey"]);

            IOptions <CosmosCacheOptions> options = Options.Create(new CosmosCacheOptions()
            {
                ContainerName       = "session",
                DatabaseName        = CosmosCacheEmulatorTests.databaseName,
                ContainerThroughput = throughput,
                CreateIfNotExists   = true,
                ClientBuilder       = builder
            });

            CosmosCache cache = new CosmosCache(options);
            DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions();

            cacheOptions.SlidingExpiration  = TimeSpan.FromSeconds(ttl);
            cacheOptions.AbsoluteExpiration = DateTimeOffset.UtcNow.AddSeconds(absoluteTtl);
            byte[] data = new byte[4] {
                1, 2, 3, 4
            };
            await cache.SetAsync(sessionId, data, cacheOptions);

            // Verify that container has been created

            CosmosCacheSession storedSession = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadItemAsync <CosmosCacheSession>(sessionId, new PartitionKey(sessionId));

            Assert.Equal(ttl, storedSession.TimeToLive);

            await Task.Delay(8000); // Wait

            await cache.GetAsync(sessionId);

            storedSession = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadItemAsync <CosmosCacheSession>(sessionId, new PartitionKey(sessionId));

            // Since the absolute expiration is closer than the sliding value, the TTL should be lower
            Assert.True(storedSession.TimeToLive < ttl);
        }
        public async Task GetObtainsSessionAndUpdatesCacheForSlidingExpirationWithAbsoluteExpirationWithHigherTime()
        {
            const int          ttlSliding      = 20;
            const int          ttlAbsolute     = 50;
            string             etag            = "etag";
            CosmosCacheSession existingSession = new CosmosCacheSession();

            existingSession.SessionKey                = "key";
            existingSession.Content                   = new byte[0];
            existingSession.IsSlidingExpiration       = true;
            existingSession.TimeToLive                = ttlSliding;
            existingSession.AbsoluteSlidingExpiration = DateTimeOffset.UtcNow.AddSeconds(ttlAbsolute).ToUnixTimeSeconds();
            Mock <ItemResponse <CosmosCacheSession> > mockedItemResponse = new Mock <ItemResponse <CosmosCacheSession> >();
            Mock <CosmosClient>      mockedClient    = new Mock <CosmosClient>();
            Mock <Container>         mockedContainer = new Mock <Container>();
            Mock <Database>          mockedDatabase  = new Mock <Database>();
            Mock <ContainerResponse> mockedResponse  = new Mock <ContainerResponse>();

            mockedItemResponse.Setup(c => c.Resource).Returns(existingSession);
            mockedItemResponse.Setup(c => c.ETag).Returns(etag);
            mockedResponse.Setup(c => c.StatusCode).Returns(HttpStatusCode.OK);
            mockedContainer.Setup(c => c.ReadContainerAsync(It.IsAny <ContainerRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(mockedResponse.Object);
            mockedContainer.Setup(c => c.ReadItemAsync <CosmosCacheSession>(It.Is <string>(id => id == "key"), It.IsAny <PartitionKey>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(mockedItemResponse.Object);
            mockedContainer.Setup(c => c.ReplaceItemAsync <CosmosCacheSession>(It.Is <CosmosCacheSession>(item => item == existingSession), It.Is <string>(id => id == "key"), It.IsAny <PartitionKey?>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(mockedItemResponse.Object);
            mockedClient.Setup(c => c.GetContainer(It.IsAny <string>(), It.IsAny <string>())).Returns(mockedContainer.Object);
            mockedClient.Setup(c => c.GetDatabase(It.IsAny <string>())).Returns(mockedDatabase.Object);
            mockedClient.Setup(x => x.Endpoint).Returns(new Uri("http://localhost"));
            CosmosCache cache = new CosmosCache(Options.Create(new CosmosCacheOptions()
            {
                DatabaseName      = "something",
                ContainerName     = "something",
                CreateIfNotExists = true,
                CosmosClient      = mockedClient.Object
            }));

            Assert.Same(existingSession.Content, await cache.GetAsync("key"));
            // Checks for Db existence due to CreateIfNotExists
            mockedClient.Verify(c => c.CreateDatabaseIfNotExistsAsync(It.IsAny <string>(), It.IsAny <int?>(), It.IsAny <RequestOptions>(), It.IsAny <CancellationToken>()), Times.Once);
            mockedContainer.Verify(c => c.ReadItemAsync <CosmosCacheSession>(It.Is <string>(id => id == "key"), It.IsAny <PartitionKey>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Once);
            mockedContainer.Verify(c => c.ReplaceItemAsync <CosmosCacheSession>(It.Is <CosmosCacheSession>(item => item.TimeToLive == ttlSliding), It.Is <string>(id => id == "key"), It.IsAny <PartitionKey?>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Once);
        }
        public async Task GetDoesRetryUpdateIfRetrySlidingExpirationUpdatesIsTrue()
        {
            string             etag            = "etag";
            CosmosCacheSession existingSession = new CosmosCacheSession();

            existingSession.SessionKey          = "key";
            existingSession.Content             = new byte[0];
            existingSession.IsSlidingExpiration = true;
            Mock <ItemResponse <CosmosCacheSession> > mockedItemResponse = new Mock <ItemResponse <CosmosCacheSession> >();
            Mock <CosmosClient>      mockedClient    = new Mock <CosmosClient>();
            Mock <Container>         mockedContainer = new Mock <Container>();
            Mock <Database>          mockedDatabase  = new Mock <Database>();
            Mock <ContainerResponse> mockedResponse  = new Mock <ContainerResponse>();

            mockedItemResponse.Setup(c => c.Resource).Returns(existingSession);
            mockedItemResponse.Setup(c => c.ETag).Returns(etag);
            mockedResponse.Setup(c => c.StatusCode).Returns(HttpStatusCode.OK);
            mockedContainer.Setup(c => c.ReadContainerAsync(It.IsAny <ContainerRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(mockedResponse.Object);
            mockedContainer.Setup(c => c.ReadItemAsync <CosmosCacheSession>(It.Is <string>(id => id == "key"), It.IsAny <PartitionKey>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(mockedItemResponse.Object);
            mockedContainer.SetupSequence(c => c.ReplaceItemAsync <CosmosCacheSession>(It.Is <CosmosCacheSession>(item => item == existingSession), It.Is <string>(id => id == "key"), It.IsAny <PartitionKey?>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()))
            .ThrowsAsync(new CosmosException("test", HttpStatusCode.PreconditionFailed, 0, "", 0))
            .ReturnsAsync(mockedItemResponse.Object);
            mockedClient.Setup(c => c.GetContainer(It.IsAny <string>(), It.IsAny <string>())).Returns(mockedContainer.Object);
            mockedClient.Setup(c => c.GetDatabase(It.IsAny <string>())).Returns(mockedDatabase.Object);
            mockedClient.Setup(x => x.Endpoint).Returns(new Uri("http://localhost"));
            CosmosCache cache = new CosmosCache(Options.Create(new CosmosCacheOptions()
            {
                DatabaseName                  = "something",
                ContainerName                 = "something",
                CreateIfNotExists             = true,
                CosmosClient                  = mockedClient.Object,
                RetrySlidingExpirationUpdates = true
            }));

            Assert.Same(existingSession.Content, await cache.GetAsync("key"));
            // Checks for Db existence due to CreateIfNotExists
            mockedClient.Verify(c => c.CreateDatabaseIfNotExistsAsync(It.IsAny <string>(), It.IsAny <int?>(), It.IsAny <RequestOptions>(), It.IsAny <CancellationToken>()), Times.Once);
            mockedContainer.Verify(c => c.ReadItemAsync <CosmosCacheSession>(It.Is <string>(id => id == "key"), It.IsAny <PartitionKey>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Exactly(2));
            mockedContainer.Verify(c => c.ReplaceItemAsync <CosmosCacheSession>(It.Is <CosmosCacheSession>(item => item == existingSession), It.Is <string>(id => id == "key"), It.IsAny <PartitionKey?>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Exactly(2));
        }
Exemplo n.º 11
0
        public async Task StoreSessionData_CustomPartitionKey()
        {
            const string sessionId             = "sessionId";
            const int    ttl                   = 1400;
            const int    throughput            = 2000;
            const string partitionKeyAttribute = "notTheId";

            CosmosClientBuilder builder = new CosmosClientBuilder(ConfigurationManager.AppSettings["Endpoint"], ConfigurationManager.AppSettings["MasterKey"]);

            IOptions <CosmosCacheOptions> options = Options.Create(new CosmosCacheOptions()
            {
                ContainerName                  = "session",
                DatabaseName                   = CosmosCacheEmulatorTests.databaseName,
                ContainerThroughput            = throughput,
                CreateIfNotExists              = true,
                ClientBuilder                  = builder,
                ContainerPartitionKeyAttribute = partitionKeyAttribute,
            });

            CosmosCache cache = new CosmosCache(options);
            DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions();

            cacheOptions.SlidingExpiration = TimeSpan.FromSeconds(ttl);
            byte[] data = new byte[4] {
                1, 2, 3, 4
            };
            await cache.SetAsync(sessionId, data, cacheOptions);

            // Verify that container has been created

            CosmosCacheSession storedSession = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadItemAsync <CosmosCacheSession>(sessionId, new PartitionKey(sessionId));

            Assert.Equal(sessionId, storedSession.SessionKey);
            Assert.Equal(data, storedSession.Content);

            ItemResponse <dynamic> dynamicSession = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadItemAsync <dynamic>(sessionId, new PartitionKey(sessionId));

            Assert.NotNull(dynamicSession.Resource.notTheId);
            Assert.Equal(sessionId, (string)dynamicSession.Resource.notTheId);
        }