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 ValidatesNoExpirationUsesNullTtl() { long?ttl = null; DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions(); 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 async Task RemoveAsyncDeletesItem() { 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.DeleteItemAsync <CosmosCacheSession>(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", CosmosClient = mockedClient.Object })); await cache.RemoveAsync("key"); mockedContainer.Verify(c => c.DeleteItemAsync <CosmosCacheSession>(It.Is <string>(id => id == "key"), It.IsAny <PartitionKey>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Once); }
public async Task GetSessionData_WhenNotExists_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); Assert.Null(await cache.GetAsync(sessionId)); }
public CosmosCacheTests() { cacheFactory = new CosmosCacheFactory(LocalClusterCosmosDb.ConnectionURI, LocalClusterCosmosDb.AccessKey, LocalClusterCosmosDb.DbName); stringCache = (CosmosCache <string>)cacheFactory.Create <string>("string-collection"); //stringCache.Remove(CacheKey); }
public async Task InitializeContainerIfNotExists() { 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 ContainerResponse response = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadContainerAsync(); Assert.NotEqual(HttpStatusCode.NotFound, response.StatusCode); Assert.NotEqual(ttl, response.Resource.DefaultTimeToLive); int?throughputContainer = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadThroughputAsync(); Assert.Equal(throughput, throughputContainer); }
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 GetReturnsNullIfKeyDoesNotExist() { 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.ReadItemAsync <CosmosCacheSession>(It.Is <string>(id => id == "key"), It.IsAny <PartitionKey>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())).ThrowsAsync(new CosmosException("test", HttpStatusCode.NotFound, 0, "", 0)); mockedContainer.Setup(c => c.ReplaceItemAsync <CosmosCacheSession>(It.IsAny <CosmosCacheSession>(), It.Is <string>(id => id == "key"), It.IsAny <PartitionKey?>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())).ThrowsAsync(new CosmosException("test", HttpStatusCode.NotFound, 0, "", 0)); 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 })); Assert.Null(await cache.GetAsync("key")); 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.IsAny <CosmosCacheSession>(), It.Is <string>(id => id == "key"), It.IsAny <PartitionKey?>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Never); }
public async Task GetSessionData() { const string sessionId = "sessionId"; const int ttl = 1400; const int throughput = 2000; byte[] data = new byte[1] { 1 }; 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, data, cacheOptions); Assert.Equal(data, await cache.GetAsync(sessionId)); }
public async Task GetSessionData_WhenNotExists() { DiagnosticsSink diagnosticsSink = new DiagnosticsSink(); 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, DiagnosticsHandler = diagnosticsSink.CaptureDiagnostics }); CosmosCache cache = new CosmosCache(options); DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions(); cacheOptions.SlidingExpiration = TimeSpan.FromSeconds(ttl); Assert.Null(await cache.GetAsync(sessionId)); Assert.Equal(4, diagnosticsSink.CapturedDiagnostics.Count); foreach (CosmosDiagnostics diagnostics in diagnosticsSink.CapturedDiagnostics) { Assert.NotNull(diagnostics?.ToString()); } }
public async Task RemoveSessionData_CustomPartitionKey() { const string sessionId = "sessionId"; const int ttl = 1400; const int throughput = 2000; byte[] data = new byte[1] { 1 }; 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); await cache.SetAsync(sessionId, data, cacheOptions); await cache.RemoveAsync(sessionId); CosmosException exception = await Assert.ThrowsAsync <CosmosException>(() => this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadItemAsync <dynamic>(sessionId, new PartitionKey(sessionId))); Assert.Equal(HttpStatusCode.NotFound, exception.StatusCode); }
public CosmosCacheTests(ITestOutputHelper output) { cacheFactory = new CosmosCacheFactory(LocalClusterCosmosDb.ConnectionURI, LocalClusterCosmosDb.AccessKey, LocalClusterCosmosDb.DbName); docDirectCacheFactory = new CosmosCacheFactory(LocalClusterCosmosDb.ConnectionURI, LocalClusterCosmosDb.AccessKey, LocalClusterCosmosDb.DbName, new CosmosCacheFactorySettings() { InsertMode = CosmosCache.InsertMode.Document }); stringCache = (CosmosCache <string>)cacheFactory.Create <string>("string-collection"); _output = output; }
public async Task ConnectAsyncThrowsIfContainerDoesNotExist() { Mock <CosmosClient> mockedClient = new Mock <CosmosClient>(); Mock <Container> mockedContainer = new Mock <Container>(); mockedContainer.Setup(c => c.ReadContainerAsync(It.IsAny <ContainerRequestOptions>(), It.IsAny <CancellationToken>())).ThrowsAsync(new CosmosException("test", HttpStatusCode.NotFound, 0, "", 0)); mockedClient.Setup(c => c.GetContainer(It.IsAny <string>(), It.IsAny <string>())).Returns(mockedContainer.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 <InvalidOperationException>(() => cache.GetAsync("key")); }
public async Task InitializeContainerIfNotExists() { DiagnosticsSink diagnosticsSink = new DiagnosticsSink(); const string sessionId = "sessionId"; const int ttl = 2000; const int ttlInSeconds = ttl / 1000; 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, DefaultTimeToLiveInMs = ttl, DiagnosticsHandler = diagnosticsSink.CaptureDiagnostics }); CosmosCache cache = new CosmosCache(options); DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions(); cacheOptions.SlidingExpiration = TimeSpan.FromSeconds(ttlInSeconds); await cache.SetAsync(sessionId, new byte[0], cacheOptions); // Verify that container has been created ContainerResponse response = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadContainerAsync(); Assert.NotEqual(HttpStatusCode.NotFound, response.StatusCode); Assert.Equal(ttlInSeconds, response.Resource.DefaultTimeToLive); Assert.True(response.Resource.IndexingPolicy.ExcludedPaths.Any(e => e.Path.Equals("/*"))); int?throughputContainer = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadThroughputAsync(); Assert.Equal(throughput, throughputContainer); Assert.Equal(4, diagnosticsSink.CapturedDiagnostics.Count); foreach (CosmosDiagnostics diagnostics in diagnosticsSink.CapturedDiagnostics) { Assert.NotNull(diagnostics?.ToString()); } }
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 RemoveSessionData() { DiagnosticsSink diagnosticsSink = new DiagnosticsSink(); const string sessionId = "sessionId"; const int ttl = 1400; const int throughput = 2000; byte[] data = new byte[1] { 1 }; 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, DiagnosticsHandler = diagnosticsSink.CaptureDiagnostics }); CosmosCache cache = new CosmosCache(options); DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions(); cacheOptions.SlidingExpiration = TimeSpan.FromSeconds(ttl); await cache.SetAsync(sessionId, data, cacheOptions); await cache.RemoveAsync(sessionId); CosmosException exception = await Assert.ThrowsAsync <CosmosException>(() => this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadItemAsync <dynamic>(sessionId, new PartitionKey(sessionId))); Assert.Equal(HttpStatusCode.NotFound, exception.StatusCode); Assert.Equal(5, diagnosticsSink.CapturedDiagnostics.Count); foreach (CosmosDiagnostics diagnostics in diagnosticsSink.CapturedDiagnostics) { Assert.NotNull(diagnostics?.ToString()); } }
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)); }
public async Task InitializeContainerIfNotExists_CustomPartitionKey() { const string sessionId = "sessionId"; const int ttl = 2000; const int ttlInSeconds = ttl / 1000; 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, DefaultTimeToLiveInMs = ttl, ContainerPartitionKeyAttribute = partitionKeyAttribute, }); CosmosCache cache = new CosmosCache(options); DistributedCacheEntryOptions cacheOptions = new DistributedCacheEntryOptions(); cacheOptions.SlidingExpiration = TimeSpan.FromSeconds(ttlInSeconds); await cache.SetAsync(sessionId, new byte[0], cacheOptions); // Verify that container has been created ContainerResponse response = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadContainerAsync(); Assert.NotEqual(HttpStatusCode.NotFound, response.StatusCode); Assert.Equal(ttlInSeconds, response.Resource.DefaultTimeToLive); Assert.True(response.Resource.IndexingPolicy.ExcludedPaths.Any(e => e.Path.Equals("/*"))); Assert.Equal($"/{partitionKeyAttribute}", response.Resource.PartitionKeyPath); int?throughputContainer = await this.testClient.GetContainer(CosmosCacheEmulatorTests.databaseName, "session").ReadThroughputAsync(); Assert.Equal(throughput, throughputContainer); }
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); }