/// <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!"); } }