def check_bad_cookie(no_datastore, cookie_only_threshold): for test in (check_bad_sid, check_manip_cookie_data, check_bogus_data, check_bogus_data2): logger.info('preparing for %s' % test.__name__) st = SessionTester(no_datastore=no_datastore, cookie_only_threshold=cookie_only_threshold) st.start_request() st['x'] = 7 st.finish_request_and_check() logger.info('running %s' % test.__name__) test(st, st.get_cookies()) st.new_session_state() st.start_request() assert not st.is_active() # due to invalid sig st.finish_request_and_check()
def check_correct_usage(no_datastore, cookie_only_threshold): """Checks correct usage of session including in the face of memcache data loss.""" def minitest_divider(test): logger.debug('\n\n' + '-'*50) logger.debug(test + ' (nd=%s cot=%s)' % (no_datastore, cookie_only_threshold)) st = SessionTester(no_datastore=no_datastore, cookie_only_threshold=cookie_only_threshold) expected_num_sessions_in_db_if_db_used = lambda a,b=0 : generic_expected_num_sessions_in_db_if_db_used(st, no_datastore, cookie_only_threshold, a, b) st.verify_active_sessions_in_db(0) minitest_divider('try doing nothing (no session should be started)') st.noop() st.verify_active_sessions_in_db(0) minitest_divider('start a session with a single write') st.start_request() str(st) assert st.get_expiration()==0, "no session yet => no expiration yet" assert st.is_active() is False st['x'] = 7 assert st.is_active() is True st.finish_request_and_check() expected_num_sessions_in_db_if_db_used(1) minitest_divider('start another session') st2 = SessionTester(st=st) st2.start_request() assert not st2.is_active() assert st2.get('x') is None, "shouldn't get other session's data" assert not st2.is_active(), "still shouldn't be active - nothing set yet" st2['x'] = 'st2x' assert st2.is_active() st2.finish_request_and_check() expected_num_sessions_in_db_if_db_used(2) minitest_divider('each session should get a unique sid') assert st2.ss.sid != st.ss.sid minitest_divider('we should still have the values we set earlier') st.start_request() str(st) assert_equal(st['x'], 7) st.finish_request_and_check() st2.start_request() assert_equal(st2['x'], 'st2x') st2.finish_request_and_check() minitest_divider("check get session by sid, save(True), and terminate()") if cookie_only_threshold == 0: data1 = st.ss.data data2 = st2.ss.data else: # data is being stored in cookie-only form => won't be in the db data1 = data2 = {} resp = st.get_url('/get_by_sid?sid=%s' % st.ss.sid) assert_equal(pickle.loads(b64decode(resp.body)), data1) resp = st2.get_url('/get_by_sid?sid=%s' % st2.ss.sid) assert_equal(pickle.loads(b64decode(resp.body)), data2) expected_num_sessions_in_db_if_db_used(2) st.start_request() st['y'] = 9 # make the session dirty st.save(True) # force it to persist to the db even though it normally wouldn't st.finish_request_and_check() # now the data should be in the db resp = st.get_url('/get_by_sid?sid=%s' % st.ss.sid) assert_equal(pickle.loads(b64decode(resp.body)), st.ss.data) expected_num_sessions_in_db_if_db_used(2, 1) st.start_request() st.terminate() # remove it from the db st.finish_request_and_check() expected_num_sessions_in_db_if_db_used(1) minitest_divider("should be able to terminate() and then start a new session all in one request") st.start_request() st['y'] = 'yy' assert_equal(st.get('y'), 'yy') st.terminate() assert_raises(KeyError, st.__getitem__, 'y') st['x'] = 7 st.finish_request_and_check() expected_num_sessions_in_db_if_db_used(2) minitest_divider("regenerating SID test") initial_sid = st.ss.sid st.start_request() initial_expir = st.get_expiration() st.regenerate_id() assert_equal(st['x'], 7, "data should not be affected") st.finish_request_and_check() assert_not_equal(initial_sid, st.ss.sid, "regenerated sid should be different") assert_equal(initial_expir, st._get_expiration(), "expiration should not change") st.start_request() assert_equal(st['x'], 7, "data should not be affected") st.finish_request_and_check() expected_num_sessions_in_db_if_db_used(2) minitest_divider("regenerating SID test w/new expiration time") initial_sid = st.ss.sid st.start_request() initial_expir = st.get_expiration() new_expir = initial_expir + 120 # something new st.regenerate_id(expiration_ts=new_expir) assert_equal(st['x'], 7, "data should not be affected") st.finish_request_and_check() assert_not_equal(initial_sid, st.ss.sid, "regenerated sid should be different") assert_equal(new_expir, st._get_expiration(), "expiration should be what we asked for") st.start_request() assert_equal(st['x'], 7, "data should not be affected") st.finish_request_and_check() expected_num_sessions_in_db_if_db_used(2) minitest_divider("check basic dictionary operations") st.start_request() st['s'] = 'aaa' st['i'] = 99 st['f'] = 4.37 assert_equal(st.pop('s'), 'aaa') assert_equal(st.pop('s'), None) assert_equal(st.pop('s', 'nil'), 'nil') assert st.has_key('i') assert not st.has_key('s') assert_equal(st.get('i'), 99) assert_equal(st.get('ii'), None) assert_equal(st.get('iii', 3), 3) assert_equal(st.get('f'), st['f']) del st['f'] assert_raises(KeyError, st.__getitem__, 'f') assert 'f' not in st assert 'i' in st assert_equal(st.get('x'), 7) st.clear() assert 'i' not in st assert 'x' not in st st.finish_request_and_check() minitest_divider("add complex data (models and objects) to the session") st.start_request() st['model'] = make_entity(0) st['dict'] = dict(a='alpha', c='charlie', e='echo') st['list'] = ['b', 'd', 'f'] st['set'] = set([2, 3, 5, 7, 11, 13, 17, 19]) st['tuple'] = (7, 7, 1985) st.finish_request_and_check() st.start_request() st.clear() st.finish_request_and_check() minitest_divider("test quick methods: basic usage") st.start_request() st.set_quick('msg', 'mc only!') assert_equal('mc only!', st['msg']) st.finish_request_and_check() st.start_request() assert_equal('mc only!', st.pop_quick('msg')) assert_raises(KeyError, st.__getitem__, 'msg') st.finish_request_and_check() minitest_divider("test quick methods: flush memcache (value will be lost if not using cookies)") st.start_request() st.set_quick('a', 1) st.set_quick('b', 2) st.finish_request_and_check() st.flush_memcache() st.start_request() if cookie_only_threshold > 0: assert_equal(st['a'], 1) assert_equal(st['b'], 2) else: assert_raises(KeyError, st.__getitem__, 'a') assert_raises(KeyError, st.__getitem__, 'b') st.finish_request_and_check() minitest_divider("test quick methods: flush memcache should have no impact if another mutator is also used (and this ISNT memcache-only)") st.start_request() st['x'] = 24 st.set_quick('a', 1) st.finish_request_and_check() st.flush_memcache() st.start_request() if no_datastore and cookie_only_threshold == 0: assert_raises(KeyError, st.__getitem__, 'a') assert_raises(KeyError, st.__getitem__, 'x') else: assert_equal(st['a'], 1) assert_equal(st['x'], 24) st.set_quick('msg', 'hello') st['z'] = 99 st.finish_request_and_check()
def check_correct_usage(no_datastore, cookie_only_threshold): """Checks correct usage of session including in the face of memcache data loss.""" def minitest_divider(test): logger.debug('\n\n' + '-' * 50) logger.debug(test + ' (nd=%s cot=%s)' % (no_datastore, cookie_only_threshold)) st = SessionTester(no_datastore=no_datastore, cookie_only_threshold=cookie_only_threshold) expected_num_sessions_in_db_if_db_used = lambda a, b=0: generic_expected_num_sessions_in_db_if_db_used( st, no_datastore, cookie_only_threshold, a, b) st.verify_active_sessions_in_db(0) minitest_divider('try doing nothing (no session should be started)') st.noop() st.verify_active_sessions_in_db(0) minitest_divider('start a session with a single write') st.start_request() str(st) assert st.get_expiration() == 0, "no session yet => no expiration yet" assert st.is_active() is False st['x'] = 7 assert st.is_active() is True st.finish_request_and_check() expected_num_sessions_in_db_if_db_used(1) minitest_divider('start another session') st2 = SessionTester(st=st) st2.start_request() assert not st2.is_active() assert st2.get('x') is None, "shouldn't get other session's data" assert not st2.is_active(), "still shouldn't be active - nothing set yet" st2['x'] = 'st2x' assert st2.is_active() st2.finish_request_and_check() expected_num_sessions_in_db_if_db_used(2) minitest_divider('each session should get a unique sid') assert st2.ss.sid != st.ss.sid minitest_divider('we should still have the values we set earlier') st.start_request() str(st) assert_equal(st['x'], 7) st.finish_request_and_check() st2.start_request() assert_equal(st2['x'], 'st2x') st2.finish_request_and_check() minitest_divider("check get session by sid, save(True), and terminate()") if cookie_only_threshold == 0: data1 = st.ss.data data2 = st2.ss.data else: # data is being stored in cookie-only form => won't be in the db data1 = data2 = {} resp = st.get_url('/get_by_sid?sid=%s' % st.ss.sid) assert_equal(pickle.loads(b64decode(resp.body)), data1) resp = st2.get_url('/get_by_sid?sid=%s' % st2.ss.sid) assert_equal(pickle.loads(b64decode(resp.body)), data2) expected_num_sessions_in_db_if_db_used(2) st.start_request() st['y'] = 9 # make the session dirty st.save( True) # force it to persist to the db even though it normally wouldn't st.finish_request_and_check() # now the data should be in the db resp = st.get_url('/get_by_sid?sid=%s' % st.ss.sid) assert_equal(pickle.loads(b64decode(resp.body)), st.ss.data) expected_num_sessions_in_db_if_db_used(2, 1) st.start_request() st.terminate() # remove it from the db st.finish_request_and_check() expected_num_sessions_in_db_if_db_used(1) minitest_divider( "should be able to terminate() and then start a new session all in one request" ) st.start_request() st['y'] = 'yy' assert_equal(st.get('y'), 'yy') st.terminate() assert_raises(KeyError, st.__getitem__, 'y') st['x'] = 7 st.finish_request_and_check() expected_num_sessions_in_db_if_db_used(2) minitest_divider("regenerating SID test") initial_sid = st.ss.sid st.start_request() initial_expir = st.get_expiration() st.regenerate_id() assert_equal(st['x'], 7, "data should not be affected") st.finish_request_and_check() assert_not_equal(initial_sid, st.ss.sid, "regenerated sid should be different") assert_equal(initial_expir, st._get_expiration(), "expiration should not change") st.start_request() assert_equal(st['x'], 7, "data should not be affected") st.finish_request_and_check() expected_num_sessions_in_db_if_db_used(2) minitest_divider("regenerating SID test w/new expiration time") initial_sid = st.ss.sid st.start_request() initial_expir = st.get_expiration() new_expir = initial_expir + 120 # something new st.regenerate_id(expiration_ts=new_expir) assert_equal(st['x'], 7, "data should not be affected") st.finish_request_and_check() assert_not_equal(initial_sid, st.ss.sid, "regenerated sid should be different") assert_equal(new_expir, st._get_expiration(), "expiration should be what we asked for") st.start_request() assert_equal(st['x'], 7, "data should not be affected") st.finish_request_and_check() expected_num_sessions_in_db_if_db_used(2) minitest_divider("check basic dictionary operations") st.start_request() st['s'] = 'aaa' st['i'] = 99 st['f'] = 4.37 assert_equal(st.pop('s'), 'aaa') assert_equal(st.pop('s'), None) assert_equal(st.pop('s', 'nil'), 'nil') assert st.has_key('i') assert not st.has_key('s') assert_equal(st.get('i'), 99) assert_equal(st.get('ii'), None) assert_equal(st.get('iii', 3), 3) assert_equal(st.get('f'), st['f']) del st['f'] assert_raises(KeyError, st.__getitem__, 'f') assert 'f' not in st assert 'i' in st assert_equal(st.get('x'), 7) st.clear() assert 'i' not in st assert 'x' not in st st.finish_request_and_check() minitest_divider("add complex data (models and objects) to the session") st.start_request() st['model'] = make_entity(0) st['dict'] = dict(a='alpha', c='charlie', e='echo') st['list'] = ['b', 'd', 'f'] st['set'] = set([2, 3, 5, 7, 11, 13, 17, 19]) st['tuple'] = (7, 7, 1985) st.finish_request_and_check() st.start_request() st.clear() st.finish_request_and_check() minitest_divider("test quick methods: basic usage") st.start_request() st.set_quick('msg', 'mc only!') assert_equal('mc only!', st['msg']) st.finish_request_and_check() st.start_request() assert_equal('mc only!', st.pop_quick('msg')) assert_raises(KeyError, st.__getitem__, 'msg') st.finish_request_and_check() minitest_divider( "test quick methods: flush memcache (value will be lost if not using cookies)" ) st.start_request() st.set_quick('a', 1) st.set_quick('b', 2) st.finish_request_and_check() st.flush_memcache() st.start_request() if cookie_only_threshold > 0: assert_equal(st['a'], 1) assert_equal(st['b'], 2) else: assert_raises(KeyError, st.__getitem__, 'a') assert_raises(KeyError, st.__getitem__, 'b') st.finish_request_and_check() minitest_divider( "test quick methods: flush memcache should have no impact if another mutator is also used (and this ISNT memcache-only)" ) st.start_request() st['x'] = 24 st.set_quick('a', 1) st.finish_request_and_check() st.flush_memcache() st.start_request() if no_datastore and cookie_only_threshold == 0: assert_raises(KeyError, st.__getitem__, 'a') assert_raises(KeyError, st.__getitem__, 'x') else: assert_equal(st['a'], 1) assert_equal(st['x'], 24) st.set_quick('msg', 'hello') st['z'] = 99 st.finish_request_and_check()