/// <summary> /// Uses reflection to determine if the MongoDB Session State Provider is holding onto a sessionId /// in it's memory cache object. /// </summary> /// <param name="mongoSessionStateProvider">The provider to use</param> /// <param name="sessionId">The session id to query</param> /// <param name="dataFromCache">The data retrieved from the cache</param> /// <returns>True if the session exists in the provider's cache</returns> private bool CheckSessionExistsInCache(MongoDBSessionStateProvider mongoSessionStateProvider, string sessionId, out ISessionStateData dataFromCache) { var mongoSessionStateProviderBaseType = mongoSessionStateProvider.GetType().BaseType; bool objectExistsInCache = (bool)mongoSessionStateProviderBaseType .GetMethod("CacheContains", BindingFlags.NonPublic | BindingFlags.Instance) .Invoke(mongoSessionStateProvider, new object[] { sessionId }); dataFromCache = (DefaultSessionStateData)mongoSessionStateProviderBaseType .GetMethod("CacheGet", BindingFlags.NonPublic | BindingFlags.Instance) .Invoke(mongoSessionStateProvider, new object[] { sessionId }); return objectExistsInCache; }
/// <summary> /// Method that creates a new session, waits for it to automatically expire and then /// verifies that the session has been removed from the provider as well as the provider's /// memory cache. /// </summary> /// <param name="mongoSessionStateProvider">The MongoDB provider to use for the test.</param> private void VerifySessionExpiration(MongoDBSessionStateProvider mongoSessionStateProvider) { var mongoSessionStateProviderBaseType = mongoSessionStateProvider.GetType().BaseType; HttpRequest httpRequest = null; HttpResponse httpResponse = null; HttpContext httpContext = GetContext(out httpRequest, out httpResponse); var timeoutInMinutes = (_TimeoutInSeconds / 60); var storeData = mongoSessionStateProvider.CreateNewStoreData(httpContext, timeoutInMinutes); storeData.Items["DummyEntry"] = "DummyValue"; string sessionId = null; lock (_SessionIdManager) { sessionId = _SessionIdManager.CreateSessionID(httpContext); } object lockId = null; // New items don't have a lockId mongoSessionStateProvider.SetAndReleaseItemExclusive(httpContext, sessionId, storeData, lockId, true); TestContext.WriteLine("Created Session {0}", sessionId); int counter = _TimeoutInSeconds + 60; TestContext.WriteLine("Waiting {0} seconds...", counter); while (counter > 0) { System.Threading.Thread.Sleep(1000); counter--; } bool locked; TimeSpan lockAge; object lockId2 = null; System.Web.SessionState.SessionStateActions actions; var storeDataAfterExpiry = mongoSessionStateProvider.GetItem(httpContext, sessionId, out locked, out lockAge, out lockId2, out actions); if (storeDataAfterExpiry == null || storeDataAfterExpiry.Items.Count == 0) { TestContext.WriteLine("Session expired from Session State Provider. Verifying session provider cache..."); ISessionStateData objectInCache = null; bool objectExistsInCache = CheckSessionExistsInCache(mongoSessionStateProvider, sessionId, out objectInCache); if (objectInCache != null) { Assert.Fail("Session data exists in cache when should have expired - Expires = {0}", objectInCache.Expires); } else if (objectInCache == null && objectExistsInCache) { Assert.Fail("Session data has expired but the cache is retaining the object!"); } else { TestContext.WriteLine("Success - session data does not exist in cache."); } } else { Assert.Fail("Session expired but MongoDB Sessions State Provider still contains data!"); } }
/// <summary> /// Uses reflection to determine if the MongoDB Session State Provider is holding onto a sessionId /// in it's memory cache object. /// </summary> /// <param name="mongoSessionStateProvider">The provider to use</param> /// <param name="sessionId">The session id to query</param> /// <param name="dataFromCache">The data retrieved from the cache</param> /// <returns>True if the session exists in the provider's cache</returns> private bool CheckSessionExistsInCache(MongoDBSessionStateProvider mongoSessionStateProvider, string sessionId, out ISessionStateData dataFromCache) { var mongoSessionStateProviderBaseType = mongoSessionStateProvider.GetType().BaseType; bool objectExistsInCache = (bool)mongoSessionStateProviderBaseType .GetMethod("CacheContains", BindingFlags.NonPublic | BindingFlags.Instance) .Invoke(mongoSessionStateProvider, new object[] { sessionId }); dataFromCache = (DefaultSessionStateData)mongoSessionStateProviderBaseType .GetMethod("CacheGet", BindingFlags.NonPublic | BindingFlags.Instance) .Invoke(mongoSessionStateProvider, new object[] { sessionId }); return(objectExistsInCache); }
/// <summary> /// Method that creates a new session using the provider supplied. This method /// also verifies that the session was created, then modifies the session, then /// deletes the session and verifies deletion from the store and the memory cache /// in the provider. /// </summary> /// <param name="provider">The MongoDB provider to use for the test.</param> private void VerifySessionPersistence(MongoDBSessionStateProvider provider) { string itemName = "DummyItem"; string itemValue = "Value"; HttpRequest request = null; HttpResponse response = null; HttpContext context = GetContext(out request, out response); TestContext.WriteLine("Creating Store Data"); var dataStore = provider.CreateNewStoreData(context, (_TimeoutInSeconds / 60)); dataStore.Items[itemName] = itemValue; var sessionId = _SessionIdManager.CreateSessionID(context); TestContext.WriteLine("Writing Store Data"); provider.SetAndReleaseItemExclusive(context, sessionId, dataStore, null, true); System.Threading.Thread.Sleep(2000); bool locked; TimeSpan lockAge; object lockId; System.Web.SessionState.SessionStateActions actions; TestContext.WriteLine("Retrieving new Store Data"); var retrievedDataStore = provider.GetItemExclusive(context, sessionId, out locked, out lockAge, out lockId, out actions); if (retrievedDataStore == null || retrievedDataStore.Items.Count == 0) { Assert.Fail("Retrieved data store does not contain session data"); } TestContext.WriteLine("Testing Store Data"); var dummyValue = retrievedDataStore.Items[itemName]; Assert.AreEqual(itemValue, dummyValue); itemValue = "NewValue"; retrievedDataStore.Items[itemName] = itemValue; TestContext.WriteLine("Updating Store Data"); provider.SetAndReleaseItemExclusive(context, sessionId, retrievedDataStore, lockId, false); System.Threading.Thread.Sleep(2000); var retrievedDataStore2 = provider.GetItemExclusive(context, sessionId, out locked, out lockAge, out lockId, out actions); if (retrievedDataStore2 == null || retrievedDataStore2.Items.Count == 0) { Assert.Fail("Retrieved data store does not contain session data"); } TestContext.WriteLine("Testing Store Data"); Assert.AreEqual(itemValue, retrievedDataStore2.Items[itemName]); TestContext.WriteLine("Releasing Store Data"); provider.ReleaseItemExclusive(context, sessionId, lockId); System.Threading.Thread.Sleep(2000); retrievedDataStore2 = provider.GetItemExclusive(context, sessionId, out locked, out lockAge, out lockId, out actions); TestContext.WriteLine("Deleting Store Data"); provider.RemoveItem(context, sessionId, lockId, retrievedDataStore2); System.Threading.Thread.Sleep(2000); TestContext.WriteLine("Ensuring store was deleted"); var retrievedDataStore3 = provider.GetItem(context, sessionId, out locked, out lockAge, out lockId, out actions); Assert.IsNull(retrievedDataStore3); System.Threading.Thread.Sleep(2000); TestContext.WriteLine("Ensuring cache is empty"); ISessionStateData sessionStateDataFromCache = null; bool sessionExistsInCache = CheckSessionExistsInCache(provider, sessionId, out sessionStateDataFromCache); if (sessionExistsInCache) { Assert.Fail("Session should have been removed but still exists in cache"); } TestContext.WriteLine("Success"); }