1-module(yaws_sessions_server_SUITE). 2 3-include("testsuite.hrl"). 4 5-compile(export_all). 6 7all() -> 8 [ 9 {group, basic_tests}, 10 {group, cookiegen_tests} 11 ]. 12 13groups() -> 14 [ 15 {basic_tests, [], [init, 16 new_session_and_list, 17 replace_session, 18 replace_session_cleanup, 19 cookieval_to_opaque, 20 delete_session, 21 timeout]}, 22 {cookiegen_tests, [], [new_cookiegen_session]} 23 ]. 24 25%%==================================================================== 26init_per_suite(Config) -> 27 application:load(yaws), 28 Config. 29 30end_per_suite(_Config) -> 31 application:unload(yaws), 32 ok. 33 34init_per_group(cookiegen_tests, Config) -> 35 Id = "testsuite-server", 36 YConf = filename:join(?tempdir(?MODULE), "yaws.conf"), 37 YawsHome = ?tempdir(?MODULE), 38 os:putenv("YAWSHOME", YawsHome), 39 application:load(yaws), 40 application:set_env(yaws, id, Id), 41 application:set_env(yaws, conf, YConf), 42 ok = yaws:start(), 43 {ok, GConf, SCs} = yaws_api:getconf(), 44 yaws_api:setconf(yaws:gconf_ysession_cookiegen(GConf, ?MODULE), SCs), 45 Config; 46init_per_group(_Group, Config) -> 47 Config. 48 49end_per_group(cookiegen_tests, _Config) -> 50 ok = application:stop(yaws); 51end_per_group(_Group, _Config) -> 52 ok. 53 54init_per_testcase(_Test, Config) -> 55 Config. 56 57end_per_testcase(_Test, _Config) -> 58 ok. 59 60%%==================================================================== 61%% Change this macro to test another backend storage module 62%%-define(BACKEND, ?MODULE). 63-define(BACKEND, yaws_session_server). 64 65start() -> 66 %% starting crypto is required for these tests to pass on R13 67 {ok, Pid} = gen_server:start({local, yaws_session_server}, 68 yaws_session_server, ?BACKEND, []), 69 ?BACKEND:cleanup(), 70 {ok, Pid}. 71 72init(_Config) -> 73 {ok, _} = start(), 74 ?assertEqual([], ?BACKEND:list()), 75 yaws_session_server:stop(), 76 ok. 77 78new_session_and_list(_Config) -> 79 {ok, _} = start(), 80 ?assertMatch([], ?BACKEND:list()), 81 Cookie1 = yaws_session_server:new_session({opaque, 1}), 82 Cookie2 = yaws_session_server:new_session({opaque, 2}, 1, self()), 83 Cookie3 = yaws_session_server:new_session({opaque, 3}, 1, self(), "cookie"), 84 ?assert(Cookie1 /= Cookie2), 85 CPrefix = atom_to_list(node()) ++ "-", 86 ?assert(lists:prefix(CPrefix, Cookie1)), 87 ?assert(lists:prefix(CPrefix, Cookie2)), 88 ?assertEqual("cookie", Cookie3), 89 ?assertMatch([_, _, _], ?BACKEND:list()), 90 yaws_session_server:stop(), 91 ok. 92 93replace_session(_Config) -> 94 {ok, _} = start(), 95 Opaque = {opaque, 1}, 96 Cookie1 = yaws_session_server:new_session(Opaque), 97 [Session] = ?BACKEND:list(), 98 Opaque2 = {opaque, 2}, 99 ?assert(yaws_session_server:replace_session(Cookie1, Opaque2)), 100 [Session_updated] = ?BACKEND:list(), 101 ?assert(Session /= Session_updated), 102 yaws_session_server:stop(), 103 ok. 104 105replace_session_cleanup(_Config) -> 106 {ok, _} = start(), 107 Parent = self(), 108 Cleanup1 = spawn(fun() -> 109 receive 110 stop -> ok; 111 Msg -> Parent ! {cleanup1, Msg} 112 end 113 end), 114 Opaque = {opaque, 1}, 115 Cookie = yaws_session_server:new_session(Opaque, 60, Cleanup1), 116 Cleanup2 = spawn(fun() -> 117 receive 118 stop -> ok; 119 Msg -> Parent ! {cleanup2, Msg} 120 end 121 end), 122 Opaque2 = {opaque, 2}, 123 ?assert(yaws_session_server:replace_session(Cookie, Opaque2, Cleanup2)), 124 ?assert(is_process_alive(Cleanup1)), 125 ?assert(is_process_alive(Cleanup2)), 126 yaws_session_server:delete_session(Cookie), 127 Res = receive 128 {cleanup2, {yaws_session_end, normal, _, Opaque2}} -> 129 ?assertNot(is_process_alive(Cleanup2)), 130 ok 131 after 132 5000 -> 133 {error, cleanup_failure} 134 end, 135 ?assertEqual(ok, Res), 136 ?assert(is_process_alive(Cleanup1)), 137 Cleanup1 ! stop, 138 yaws_session_server:stop(), 139 ok. 140 141cookieval_to_opaque(_Config) -> 142 {ok, _} = start(), 143 Opaque = {opaque, 1}, 144 Cookie1 = yaws_session_server:new_session(Opaque), 145 [Session] = ?BACKEND:list(), 146 timer:sleep(1000), %% ensure cookie TS is updated of at least 1 second 147 {ok, Result} = yaws_session_server:cookieval_to_opaque(Cookie1), 148 ?assertEqual(Opaque, Result), 149 [Session_updated] = ?BACKEND:list(), 150 ?assert(Session /= Session_updated), 151 yaws_session_server:stop(), 152 ok. 153 154delete_session(_Config) -> 155 {ok, _} = start(), 156 Opaque = {opaque, 1}, 157 Cookie1 = yaws_session_server:new_session(Opaque), 158 Cookie2 = yaws_session_server:new_session(Opaque, 10, self()), 159 ?assertMatch([_, _], ?BACKEND:list()), 160 Expected1 = nocleanup, 161 ?assertEqual(Expected1, yaws_session_server:delete_session(Cookie1)), 162 Delete_notif = {yaws_session_end, normal, Cookie2, Opaque}, 163 ?assertEqual(Delete_notif, yaws_session_server:delete_session(Cookie2)), 164 ?assertEqual([], ?BACKEND:list()), 165 Res = receive 166 Delete_notif -> ok 167 after 168 500 -> cleanup_timeout 169 end, 170 ?assertEqual(ok, Res), 171 yaws_session_server:stop(), 172 ok. 173 174timeout(_Config) -> 175 {ok, Pid} = start(), 176 Opaque = {opaque, 1}, 177 Cookie1 = yaws_session_server:new_session(Opaque, 0, self()), 178 Opaque2 = {opaque, 1}, 179 _Cookie2 = yaws_session_server:new_session(Opaque2, 10, self()), 180 ?assertMatch([_, _], ?BACKEND:list()), 181 Pid ! timeout, 182 Timeout_notif = {yaws_session_end,timeout, Cookie1, Opaque}, 183 Res = 184 receive 185 Timeout_notif -> ok 186 after 187 500 -> cleanup_timeout 188 end, 189 ?assertEqual(ok, Res), 190 ?assertMatch([_], ?BACKEND:list()), 191 yaws_session_server:stop(), 192 ok. 193 194%% Our test callbacks 195init_backend(_) -> 196 proc_lib:start (?MODULE, mock_session_server, []), 197 ok. 198 199insert(Session) -> 200 ?MODULE ! {insert, Session}, 201 true. 202 203lookup(Cookie) -> 204 ?MODULE ! {{lookup, Cookie}, self()}, 205 receive {ok, Opaque} -> [Opaque] 206 after 1000 -> list_timeout 207 end. 208 209list() -> 210 ?MODULE ! {list, self()}, 211 receive {ok, Sessions} -> Sessions 212 after 1000 -> list_timeout 213 end. 214 215delete(Cookie) -> 216 ?MODULE ! {delete, Cookie}, 217 true. 218 219cleanup() -> 220 Cleaner = 221 fun(Session) -> 222 Cookie = yaws_session_server:cookie(Session), 223 delete(Cookie) 224 end, 225 lists:foreach(Cleaner, list()). 226 227traverse(Gnow) -> 228 Timeouter = 229 fun (Session) -> 230 case yaws_session_server:has_timedout(Session, Gnow) of 231 false -> 232 ok; 233 true -> 234 yaws_session_server:report_timedout_sess(Session), 235 Cookie = yaws_session_server:cookie(Session), 236 delete(Cookie) 237 end 238 end, 239 lists:foreach(Timeouter, list()). 240 241stop_backend() -> 242 ?MODULE ! stop, 243 ok. 244 245%% Mock Internals 246mock_session_server() -> 247 register(?MODULE, self()), 248 proc_lib:init_ack({ok, self()}), 249 mock_loop(). 250 251mock_loop() -> 252 receive 253 {list, Pid} -> 254 Pid ! {ok, sessions()}, 255 mock_loop(); 256 {insert, Session} -> 257 Cookie = element(2, Session), 258 put({session, Cookie}, Session), 259 mock_loop(); 260 {{lookup, Cookie}, Pid} -> 261 Session = get({session, Cookie}), 262 Pid ! {ok, Session}, 263 mock_loop(); 264 {delete, Cookie} -> 265 erase({session, Cookie}), 266 mock_loop(); 267 stop -> 268 ok; 269 Other -> 270 ?debugFmt("Unexpected: ~p~n", [Other]) 271 end. 272 273sessions() -> 274 lists:foldl(fun({{session, _}, Session}, Acc) -> [Session | Acc]; 275 (_, Acc) -> Acc 276 end, [], get()). 277 278%%==================================================================== 279 280-define(SPECIAL_COOKIE, "my special cookie"). 281new_cookie() -> 282 ?SPECIAL_COOKIE. 283 284new_cookiegen_session(_Config) -> 285 Cookie1 = yaws_session_server:new_session({opaque, 1}), 286 Cookie2 = yaws_session_server:new_session({opaque, 2}, 1, self()), 287 Cookie3 = yaws_session_server:new_session({opaque, 3}, 1, self(), "cookie"), 288 ?assertEqual(?SPECIAL_COOKIE, Cookie1), 289 ?assertEqual(Cookie1, Cookie2), 290 ?assertEqual("cookie", Cookie3), 291 ok. 292