/** * Tests update of session expiration in memcached (like {@link * #testExpirationOfSessionsInMemcachedIfBackupWasSkippedSimple()}) but for the scenario where * many readonly requests occur: in this case, we cannot just use <em>maxInactiveInterval - * secondsSinceLastBackup</em> (in {@link MemcachedSessionService#updateExpirationInMemcached}) to * determine if an expiration update is required, but we must use the last expiration time sent to * memcached. * * @throws Exception if something goes wrong with the http communication with tomcat */ @Test(enabled = true, dataProviderClass = TestUtils.class, dataProvider = STICKYNESS_PROVIDER) public void testExpirationOfSessionsInMemcachedIfBackupWasSkippedManyReadonlyRequests( final SessionAffinityMode stickyness) throws Exception { final SessionManager manager = _tomcat1.getManager(); setStickyness(stickyness); // set to 1 sec above (in setup), default is 10 seconds final int delay = manager.getContainer().getBackgroundProcessorDelay(); manager.setMaxInactiveInterval(delay * 4); final String sessionId1 = makeRequest(_httpClient, _portTomcat1, null); assertNotNull(sessionId1, "No session created."); assertWaitingWithProxy(Predicates.<MemcachedClientIF>notNull(), 200l, _memcached) .get(sessionId1); /* after 3 seconds make another request without changing the session, so that * it's not sent to memcached */ Thread.sleep(TimeUnit.SECONDS.toMillis(delay * 3)); assertEquals( makeRequest(_httpClient, _portTomcat1, sessionId1), sessionId1, "SessionId should be the same"); assertNotNull(_memcached.get(sessionId1), "Session should still exist in memcached."); /* after another 3 seconds make another request without changing the session */ Thread.sleep(TimeUnit.SECONDS.toMillis(delay * 3)); assertEquals( makeRequest(_httpClient, _portTomcat1, sessionId1), sessionId1, "SessionId should be the same"); assertNotNull(_memcached.get(sessionId1), "Session should still exist in memcached."); /* after another nearly 4 seconds (maxInactiveInterval) check that the session is still alive in memcached, * this would have been expired without an updated expiration */ Thread.sleep(TimeUnit.SECONDS.toMillis(manager.getMaxInactiveInterval()) - 500); assertNotNull(_memcached.get(sessionId1), "Session should still exist in memcached."); /* after another second in sticky mode (more than 4 seconds since the last request), or an two times the * maxInactiveInterval in non-sticky mode (we must keep sessions in memcached with double expirationtime) * the session must be expired in memcached */ Thread.sleep(TimeUnit.SECONDS.toMillis(delay) + 500); assertNotSame( makeRequest(_httpClient, _portTomcat1, sessionId1), sessionId1, "The sessionId should have changed due to expired sessin"); }
/** * Test for issue #60 (Add possibility to disable msm at runtime): start msm disabled and * afterwards enable */ @Test(enabled = true) public void testStartMsmDisabled() throws Exception { // shutdown our server and our client _memcached.shutdown(); _daemon.stop(); // start a new tomcat with msm initially disabled _tomcat1.stop(); Thread.sleep(500); final String memcachedNodes = _memcachedNodeId + ":localhost:" + _memcachedPort; _tomcat1 = getTestUtils() .tomcatBuilder() .port(_portTomcat1) .memcachedNodes(memcachedNodes) .sticky(true) .enabled(false) .jvmRoute("app1") .buildAndStart(); LOG.info("Waiting, check logs to see if the client causes any 'Connection refused' logging..."); Thread.sleep(1000); // some basic tests for session functionality checkSessionFunctionalityWithMsmDisabled(); // start memcached, client and reenable msm _daemon.start(); _memcached = createMemcachedClient(memcachedNodes, new InetSocketAddress("localhost", _memcachedPort)); _tomcat1.getManager().setEnabled(true); // Wait a little bit, so that msm's memcached client can connect and is ready when test starts Thread.sleep(100); // memcached based stuff should work again final String sessionId1 = makeRequest(_httpClient, _portTomcat1, null); assertNotNull(sessionId1, "No session created."); assertNotNull( new SessionIdFormat().extractMemcachedId(sessionId1), "memcached node id missing with msm switched to enabled"); Thread.sleep(50); assertNotNull(_memcached.get(sessionId1), "Session not available in memcached."); waitForSessionExpiration(true); assertNull(_memcached.get(sessionId1), "Expired session still existing in memcached"); }
/** * Test for issue #49: Sessions not associated with a memcached node don't get associated as soon * as a memcached is available * * @throws InterruptedException * @throws IOException * @throws TimeoutException * @throws ExecutionException */ @Test(enabled = true) public void testNotAssociatedSessionGetsAssociatedIssue49() throws InterruptedException, IOException, ExecutionException, TimeoutException { _daemon.stop(); final SessionManager manager = _tomcat1.getManager(); manager.setMaxInactiveInterval(5); manager.setSticky(true); final SessionIdFormat sessionIdFormat = new SessionIdFormat(); final Session session = manager.createSession(null); assertNull(sessionIdFormat.extractMemcachedId(session.getId())); _daemon.start(); // Wait so that the daemon will be available and the client can reconnect (async get didn't do // the trick) Thread.sleep(4000); final String newSessionId = manager.getMemcachedSessionService().changeSessionIdOnMemcachedFailover(session.getId()); assertNotNull(newSessionId); assertEquals(newSessionId, session.getId()); assertEquals(sessionIdFormat.extractMemcachedId(newSessionId), _memcachedNodeId); }
@Test(enabled = true, dataProviderClass = TestUtils.class, dataProvider = STICKYNESS_PROVIDER) public void testSessionAvailableInMemcached(final SessionAffinityMode sessionAffinity) throws IOException, InterruptedException, HttpException { setStickyness(sessionAffinity); final String sessionId1 = makeRequest(_httpClient, _portTomcat1, null); assertNotNull(sessionId1, "No session created."); Thread.sleep(50); assertNotNull(_memcached.get(sessionId1), "Session not available in memcached."); }
private void waitForSessionExpiration(final boolean sticky) throws InterruptedException { final SessionManager manager = _tomcat1.getManager(); assertEquals(manager.getMemcachedSessionService().isSticky(), sticky); final Container container = manager.getContainer(); final long timeout = TimeUnit.SECONDS.toMillis( sticky ? container.getBackgroundProcessorDelay() + manager.getMaxInactiveInterval() : 2 * manager.getMaxInactiveInterval()) + 1000; Thread.sleep(timeout); }
/** * Tests, that for a session that was not sent to memcached (because it's attributes were not * modified), the expiration is updated so that they don't expire in memcached before they expire * in tomcat. * * @throws Exception if something goes wrong with the http communication with tomcat */ @Test(enabled = true, dataProviderClass = TestUtils.class, dataProvider = STICKYNESS_PROVIDER) public void testExpirationOfSessionsInMemcachedIfBackupWasSkippedSimple( final SessionAffinityMode stickyness) throws Exception { final SessionManager manager = _tomcat1.getManager(); setStickyness(stickyness); // set to 1 sec above (in setup), default is 10 seconds final int delay = manager.getContainer().getBackgroundProcessorDelay(); manager.setMaxInactiveInterval(delay * 4); final String sessionId1 = makeRequest(_httpClient, _portTomcat1, null); assertNotNull(sessionId1, "No session created."); assertNotNull(_memcached.get(sessionId1), "Session not available in memcached."); /* after 2 seconds make another request without changing the session, so that * it's not sent to memcached */ Thread.sleep(TimeUnit.SECONDS.toMillis(delay * 2)); assertEquals( makeRequest(_httpClient, _portTomcat1, sessionId1), sessionId1, "SessionId should be the same"); /* after another 3 seconds check that the session is still alive in memcached, * this would have been expired without an updated expiration */ Thread.sleep(TimeUnit.SECONDS.toMillis(delay * 3)); assertNotNull(_memcached.get(sessionId1), "Session should still exist in memcached."); /* after another >1 second (4 seconds since the last request) * the session must be expired in memcached */ Thread.sleep( TimeUnit.SECONDS.toMillis(delay) + 500); // +1000 just to be sure that we're >4 secs assertNotSame( makeRequest(_httpClient, _portTomcat1, sessionId1), sessionId1, "The sessionId should have changed due to expired sessin"); }
private void setStickyness(final SessionAffinityMode sessionAffinity) { if (!sessionAffinity.isSticky()) { _tomcat1.getEngine().setJvmRoute(null); } final SessionManager manager = _tomcat1.getManager(); manager.setSticky(sessionAffinity.isSticky()); try { waitForReconnect(manager.getMemcachedSessionService().getMemcached(), 1, 500); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e); } }
@Test(enabled = true, dataProviderClass = TestUtils.class, dataProvider = STICKYNESS_PROVIDER) public void testSessionAvailableInMemcachedWithCookiesDisabled( final SessionAffinityMode sessionAffinity) throws Exception { _tomcat1.stop(); _tomcat1 = tcBuilder() .sticky(sessionAffinity.isSticky()) .cookies(false) .jvmRoute("app1") .buildAndStart(); final Response response = get(_httpClient, _portTomcat1, null); final String sessionId = response.get(TestServlet.ID); assertNotNull(sessionId, "No session created."); Thread.sleep(50); assertNotNull(_memcached.get(sessionId), "Session not available in memcached."); }
private MemcachedClient createMemcachedClient( final String memcachedNodes, final InetSocketAddress address) throws IOException, InterruptedException { final MemcachedNodesManager nodesManager = MemcachedNodesManager.createFor(memcachedNodes, null, _memcachedClientCallback); final ConnectionFactory cf = nodesManager.isEncodeNodeIdInSessionId() ? new SuffixLocatorConnectionFactory( nodesManager, nodesManager.getSessionIdFormat(), Statistics.create(), 1000, 1000) : new DefaultConnectionFactory(); final MemcachedClient result = new MemcachedClient(cf, Arrays.asList(address)); // Wait a little bit, so that the memcached client can connect and is ready when test starts Thread.sleep(100); return result; }
@Test(enabled = true, dataProviderClass = TestUtils.class, dataProvider = STICKYNESS_PROVIDER) public void testInvalidSessionNotFound(@Nonnull final SessionAffinityMode sessionAffinity) throws IOException, InterruptedException, HttpException { setStickyness(sessionAffinity); final String sessionId1 = makeRequest(_httpClient, _portTomcat1, null); assertNotNull(sessionId1, "No session created."); /* * wait some time, as processExpires runs every second and the * maxInactiveTime is set to 1 sec... */ Thread.sleep(2100); final String sessionId2 = makeRequest(_httpClient, _portTomcat1, sessionId1); assertNotSame(sessionId1, sessionId2, "Expired session returned."); }