/** * Tests sessionAttributeFilter attribute: only filtered/allowed attributes must be serialized. */ @SuppressWarnings( { "unchecked", "rawtypes" } ) @Test public void testOnlyFilteredAttributesAreIncludedInSessionBackup() throws InterruptedException, ExecutionException { final TranscoderService transcoderServiceMock = mock( TranscoderService.class ); final ConcurrentMap<String, Object> anyMap = any( ConcurrentMap.class ); when( transcoderServiceMock.serializeAttributes( any( MemcachedBackupSession.class ), anyMap ) ).thenReturn( new byte[0] ); _service.setTranscoderService( transcoderServiceMock ); final MemcachedBackupSession session = createSession( _service ); _service.setSessionAttributeFilter( "^(foo|bar)$" ); session.setAttribute( "foo", "foo" ); session.setAttribute( "bar", "bar" ); session.setAttribute( "baz", "baz" ); _service.backupSession( session.getIdInternal(), false, null ).get(); // capture the supplied argument, alternatively we could have used some Matcher (but there seems to be no MapMatcher). final ArgumentCaptor<ConcurrentMap> model = ArgumentCaptor.forClass( ConcurrentMap.class ); verify( transcoderServiceMock, times( 1 ) ).serializeAttributes( eq( session ), model.capture() ); // the serialized attributes must only contain allowed ones assertTrue( model.getValue().containsKey( "foo" ) ); assertTrue( model.getValue().containsKey( "bar" ) ); assertFalse( model.getValue().containsKey( "baz" ) ); }
/** * Tests sessionAttributeFilter attribute: only filtered/allowed attributes must be serialized in updateExpirationInMemcached. */ @SuppressWarnings( { "unchecked", "rawtypes" } ) @Test public void testOnlyFilteredAttributesAreIncludedDuringUpdateExpiration() throws InterruptedException, ExecutionException { final TranscoderService transcoderServiceMock = mock( TranscoderService.class ); final ConcurrentMap<String, Object> anyMap = any( ConcurrentMap.class ); when( transcoderServiceMock.serializeAttributes( any( MemcachedBackupSession.class ), anyMap ) ).thenReturn( new byte[0] ); _service.setTranscoderService( transcoderServiceMock ); final MemcachedBackupSession session = createSession( _service ); _service.setSessionAttributeFilter( "^(foo|bar)$" ); session.setAttribute( "foo", "foo" ); session.setAttribute( "bar", "bar" ); session.setAttribute( "baz", "baz" ); session.access(); session.endAccess(); _service.updateExpirationInMemcached(); // capture the supplied argument, alternatively we could have used some Matcher (but there seems to be no MapMatcher). final ArgumentCaptor<ConcurrentMap> model = ArgumentCaptor.forClass( ConcurrentMap.class ); verify( transcoderServiceMock, times( 1 ) ).serializeAttributes( eq( session ), model.capture() ); // the serialized attributes must only contain allowed ones assertTrue( model.getValue().containsKey( "foo" ) ); assertTrue( model.getValue().containsKey( "bar" ) ); assertFalse( model.getValue().containsKey( "baz" ) ); }
/** * Test for issue #105: Make memcached node optional for single-node setup * http://code.google.com/p/memcached-session-manager/issues/detail?id=105 */ @Test public void testBackupSessionFailureWithoutMemcachedNodeIdConfigured105() throws Exception { _service.setMemcachedNodes( "127.0.0.1:11211" ); _service.setSessionBackupAsync(false); _service.startInternal(new MemcachedStorageClient(_memcachedMock)); final MemcachedBackupSession session = createSession( _service ); session.access(); session.endAccess(); session.setAttribute( "foo", "bar" ); @SuppressWarnings( "unchecked" ) final OperationFuture<Boolean> futureMock = mock( OperationFuture.class ); when( futureMock.get( ) ).thenThrow(new ExecutionException(new RuntimeException("Simulated exception."))); when( futureMock.get( anyInt(), any( TimeUnit.class ) ) ).thenThrow(new ExecutionException(new RuntimeException("Simulated exception."))); when( _memcachedMock.set( eq( session.getId() ), anyInt(), any(), any( Transcoder.class ) ) ).thenReturn( futureMock ); final BackupResult backupResult = _service.backupSession( session.getIdInternal(), false, null ).get(); assertEquals(backupResult.getStatus(), BackupResultStatus.FAILURE); verify( _memcachedMock, times( 1 ) ).set( eq( session.getId() ), anyInt(), any(), any( Transcoder.class ) ); }
/** * Tests sessionAttributeFilter attribute: when excluded attributes are accessed/put the session should * not be marked as touched. */ @SuppressWarnings( "unchecked" ) @Test public void testOnlyHashAttributesOfAccessedFilteredAttributes() throws InterruptedException, ExecutionException { final TranscoderService transcoderServiceMock = mock( TranscoderService.class ); _service.setTranscoderService( transcoderServiceMock ); final MemcachedBackupSession session = createSession( _service ); _service.setSessionAttributeFilter( "^(foo|bar)$" ); session.setAttribute( "baz", "baz" ); session.access(); session.endAccess(); _service.backupSession( session.getIdInternal(), false, null ).get(); verify( transcoderServiceMock, never() ).serializeAttributes( (MemcachedBackupSession)any(), (ConcurrentMap)any() ); }
session.setAttribute( "foo", "bar" ); _service.backupSession( session.getIdInternal(), false, null ).get(); verify( _memcachedMock, times( 1 ) ).set( eq( session.getId() ), anyInt(), any(), any( Transcoder.class ) ); session.setAttribute( "foo", "bar" ); session.setAttribute( "bar", "baz" ); _service.backupSession( session.getIdInternal(), false, null ).get(); verify( _memcachedMock, times( 2 ) ).set( eq( session.getId() ), anyInt(), any(), any( Transcoder.class ) );
/** * Test that session attribute serialization and hash calculation is only * performed if session attributes were accessed since the last backup. * Otherwise this computing time shall be saved for a better world :-) * @throws ExecutionException * @throws InterruptedException */ @Test public void testOnlyHashAttributesOfAccessedAttributes() throws InterruptedException, ExecutionException { final TranscoderService transcoderServiceMock = mock( TranscoderService.class ); @SuppressWarnings( "unchecked" ) final ConcurrentMap<String, Object> anyMap = any( ConcurrentMap.class ); when( transcoderServiceMock.serializeAttributes( any( MemcachedBackupSession.class ), anyMap ) ).thenReturn( new byte[0] ); _service.setTranscoderService( transcoderServiceMock ); final MemcachedBackupSession session = createSession( _service ); session.access(); session.endAccess(); session.setAttribute( "foo", "bar" ); _service.backupSession( session.getIdInternal(), false, null ).get(); verify( transcoderServiceMock, times( 1 ) ).serializeAttributes( eq( session ), eq( session.getAttributesInternal() ) ); session.access(); session.endAccess(); _service.backupSession( session.getIdInternal(), false, null ).get(); verify( transcoderServiceMock, times( 1 ) ).serializeAttributes( eq( session ), eq( session.getAttributesInternal() ) ); }
/** * Test that session attribute serialization and hash calculation is only * performed if the session and its attributes were accessed since the last backup/backup check. * Otherwise this computing time shall be saved for a better world :-) * @throws ExecutionException * @throws InterruptedException */ @Test public void testOnlyHashAttributesOfAccessedSessionsAndAttributes() throws InterruptedException, ExecutionException { final TranscoderService transcoderServiceMock = mock( TranscoderService.class ); @SuppressWarnings( "unchecked" ) final ConcurrentMap<String, Object> anyMap = any( ConcurrentMap.class ); when( transcoderServiceMock.serializeAttributes( any( MemcachedBackupSession.class ), anyMap ) ).thenReturn( new byte[0] ); _service.setTranscoderService( transcoderServiceMock ); final MemcachedBackupSession session = createSession( _service ); session.setAttribute( "foo", "bar" ); _service.backupSession( session.getIdInternal(), false, null ).get(); verify( transcoderServiceMock, times( 1 ) ).serializeAttributes( eq( session ), eq( session.getAttributesInternal() ) ); // we need some millis between last backup and next access (due to check in BackupSessionService) Thread.sleep(5L); session.access(); session.getAttribute( "foo" ); _service.backupSession( session.getIdInternal(), false, null ).get(); verify( transcoderServiceMock, times( 2 ) ).serializeAttributes( eq( session ), eq( session.getAttributesInternal() ) ); // we need some millis between last backup and next access (due to check in BackupSessionService) Thread.sleep(5L); _service.backupSession( session.getIdInternal(), false, null ).get(); verify( transcoderServiceMock, times( 2 ) ).serializeAttributes( eq( session ), eq( session.getAttributesInternal() ) ); }
@Test public void testSerializeSessionWithAttributes() { final MemcachedBackupSession session = (MemcachedBackupSession) _manager.createSession( null ); final TranscoderService transcoderService = new TranscoderService( new JavaSerializationTranscoder( _manager ) ); final String value = "bar"; session.setAttribute( "foo", value ); session.setLastBackupTime( System.currentTimeMillis() ); final byte[] data = transcoderService.serialize( session ); final MemcachedBackupSession deserialized = transcoderService.deserialize( data, _manager ); assertSessionFields( session, deserialized ); Assert.assertEquals( value, deserialized.getAttribute( "foo" ) ); }
@Test public void testBackupSessionInRedis() throws InterruptedException, ExecutionException, UnsupportedEncodingException, ClassNotFoundException, IOException { final MemcachedSessionService service = _tomcat1.getService(); final MemcachedBackupSession session = createSession( service ); final String sessionId = "12345"; session.setId(sessionId); session.setAttribute( "foo", "bar" ); final BackupResult backupResult = service.backupSession( session.getIdInternal(), false, null ).get(); assertEquals(backupResult.getStatus(), BackupResultStatus.SUCCESS); final MemcachedBackupSession loadedSession = transcoderService.deserialize( redisClient.get(sessionId.getBytes("UTF-8")), _tomcat1.getManager()); checkSession(loadedSession, session); }
@Test public void testBackupSessionInCouchbase() throws InterruptedException, ExecutionException { final MemcachedSessionService service = _tomcat1.getService(); final MemcachedBackupSession session = createSession( service ); final String sessionId = "12345"; session.setId(sessionId); session.setAttribute( "foo", "bar" ); final BackupResult backupResult = service.backupSession( session.getIdInternal(), false, null ).get(); assertEquals(backupResult.getStatus(), BackupResultStatus.SUCCESS); final MemcachedBackupSession loadedSession = transcoderService.deserialize(mc.get(sessionId, ByteArrayTranscoder.INSTANCE), _tomcat1.getManager()); checkSession(loadedSession, session); }
session.setAttribute( "foo", "bar" ); _service.backupSession( session.getIdInternal(), false, "foo" ).get();
session.setAttribute( "foo", "bar" ); final String sessionId = session.getId();
assertTrue(session2.isLocked()); assertEquals(session2.getRefCount(), 1); session2.setAttribute("foo", "bar");
/** * Test for issue #38: * Notify HttpSessionActivationListeners when loading a session from memcached * @throws Exception */ @Test( enabled = true ) public void testHttpSessionActivationListenersNotifiedOnLoadWithJvmRoute() throws Exception { final SessionManager manager1 = _tomcat1.getManager(); final SessionManager manager2 = _tomcat2.getManager(); final SessionIdFormat format = new SessionIdFormat(); final String sessionId1 = get( _httpClient, TC_PORT_1, null ).getSessionId(); assertEquals( format.extractJvmRoute( sessionId1 ), JVM_ROUTE_1 ); final MemcachedBackupSession session = (MemcachedBackupSession) manager1.findSession( sessionId1 ); session.setAttribute( "listener", new RecordingSessionActivationListener() ); get( _httpClient, TC_PORT_1, sessionId1 ); final String sessionId2 = get( _httpClient, TC_PORT_2, sessionId1 ).getSessionId(); assertEquals( format.stripJvmRoute( sessionId2 ), format.stripJvmRoute( sessionId1 ) ); assertEquals( format.extractJvmRoute( sessionId2 ), JVM_ROUTE_2 ); final MemcachedBackupSession loaded = (MemcachedBackupSession) manager2.findSession( sessionId2 ); assertNotNull( loaded ); final RecordingSessionActivationListener listener = (RecordingSessionActivationListener) loaded.getAttribute( "listener" ); assertNotNull( listener ); final String notifiedSessionId = listener.getSessionDidActivate(); assertEquals( notifiedSessionId, sessionId2 ); }
@Test(enabled = false) // spurious failures public void testBackupSessionInCouchbaseCluster() throws Exception { final MemcachedSessionService service = _tomcat1.getService(); cluster.add(setupCouchbase(getMaxCouchbasePort() + 1)); service.setMemcachedNodes(getMemcachedNodesConfig(getURIs())); setupCouchbaseClient(); waitForReconnect(service.getStorageClient(), cluster.size(), 1000); waitForReconnect(mc, cluster.size(), 1000); final MemcachedBackupSession session = createSession( service ); final String sessionId = "12345"; session.setId(sessionId); session.setAttribute( "foo", "bar" ); final BackupResult backupResult = service.backupSession( session.getIdInternal(), false, null ).get(); assertEquals(backupResult.getStatus(), BackupResultStatus.SUCCESS); final MemcachedBackupSession loadedSession = transcoderService.deserialize(mc.get(sessionId, ByteArrayTranscoder.INSTANCE), _tomcat1.getManager()); checkSession(loadedSession, session); }
/** * Test for issue #38: * Notify HttpSessionActivationListeners when loading a session from memcached * @throws Exception */ @Test( enabled = true ) public void testHttpSessionActivationListenersNotifiedOnLoadWithoutJvmRoute() throws Exception { _tomcat1.stop(); _tomcat2.stop(); _tomcat1 = startTomcat( TC_PORT_1, null ); _tomcat2 = startTomcat( TC_PORT_2, null ); final SessionManager manager1 = _tomcat1.getManager(); final SessionManager manager2 = _tomcat2.getManager(); final SessionIdFormat format = new SessionIdFormat(); final String sessionId1 = get( _httpClient, TC_PORT_1, null ).getSessionId(); assertNull( format.extractJvmRoute( sessionId1 ) ); final MemcachedBackupSession session = (MemcachedBackupSession) manager1.findSession( sessionId1 ); session.setAttribute( "listener", new RecordingSessionActivationListener() ); get( _httpClient, TC_PORT_1, sessionId1 ); final String sessionId2 = get( _httpClient, TC_PORT_2, sessionId1 ).getSessionId(); assertEquals( sessionId2, sessionId1 ); final MemcachedBackupSession loaded = (MemcachedBackupSession) manager2.findSession( sessionId2 ); assertNotNull( loaded ); final RecordingSessionActivationListener listener = (RecordingSessionActivationListener) loaded.getAttribute( "listener" ); assertNotNull( listener ); final String notifiedSessionId = listener.getSessionDidActivate(); assertEquals( notifiedSessionId, sessionId2 ); }
@Test( enabled = true ) public void testDeserializeHibernateCollection() { final SessionManager manager = createSessionManager(); final Set<Animal> animals = new HashSet<Animal>( Arrays.asList( new Animal( "cat" ) ) ); final Person person = new Person( "foo bar", animals ); final Long personId = createPerson( person ); final Person foundPerson = findPerson( personId ); LOG.info( "person: " + person.toString() ); LOG.info( "found: " + foundPerson.toString() ); TestUtils.assertDeepEquals( person, foundPerson ); final TranscoderService transcoderService = new TranscoderService( createTranscoder( manager ) ); final MemcachedBackupSession session = createSession( manager, "123456789" ); session.setAttribute( "person", foundPerson ); final byte[] data = transcoderService.serialize( session ); final MemcachedBackupSession deserialized = transcoderService.deserialize( data, manager ); final Person deserializedPerson = (Person) deserialized.getAttribute( "person" ); TestUtils.assertDeepEquals( foundPerson, deserializedPerson ); }