blob: c5051455ebd276a27c0dd61279e55351200044fe [file] [log] [blame]
David Reiss5e530af2009-06-04 02:01:24 +00001%% Tests the behavior of clients in the face of transport errors.
2%% Makes sure start, start_linked, and start_tethered work as expected.
3
4-module(test_tether).
5
6-compile(export_all).
7
David Reissfad60652009-06-04 02:01:35 +00008
David Reiss5e530af2009-06-04 02:01:24 +00009t() ->
David Reissfad60652009-06-04 02:01:35 +000010 io:format("Beginning transport error test.~n"),
11 Pid1 = erlang:spawn(?MODULE, t_sub, [2]),
12 wait_for(Pid1),
13 io:format("Beginning protocol error test.~n"),
14 Pid2 = erlang:spawn(?MODULE, t_sub, [22]),
15 wait_for(Pid2),
16 ok.
17
18t_sub(Port) ->
David Reiss5e530af2009-06-04 02:01:24 +000019 io:format("Starting.~n", []),
20 register(tester, self()),
21
David Reissfad60652009-06-04 02:01:35 +000022 Pid1 = erlang:spawn(?MODULE, test_start, [Port]),
David Reiss5e530af2009-06-04 02:01:24 +000023 receive after 200 -> ok end, % Wait for completion.
24 case is_up(Pid1) of
25 true ->
26 io:format("PASS. Unlinked owner still alive.~n");
27 false ->
28 io:format("FAIL. Unlinked owner is dead.~n")
29 end,
30
David Reissfad60652009-06-04 02:01:35 +000031 Pid2 = erlang:spawn(?MODULE, test_linked, [Port]),
David Reiss5e530af2009-06-04 02:01:24 +000032 receive after 200 -> ok end, % Wait for completion.
33 case is_up(Pid2) of
34 true ->
35 io:format("FAIL. Linked owner still alive.~n");
36 false ->
37 io:format("PASS. Linked owner is dead.~n")
38 end,
39
David Reissfad60652009-06-04 02:01:35 +000040 Pid3 = erlang:spawn(?MODULE, test_tethered, [Port]),
David Reiss1e1a6972009-06-04 02:01:32 +000041 receive after 200 -> ok end, % Wait for completion.
42 case is_up(Pid3) of
43 true ->
44 io:format("PASS. Tethered owner still alive.~n");
45 false ->
46 io:format("FAIL. Tethered owner is dead.~n")
47 end,
48
David Reissfad60652009-06-04 02:01:35 +000049 check_extras(3).
David Reiss5e530af2009-06-04 02:01:24 +000050
51is_up(Pid) ->
52 MonitorRef = erlang:monitor(process, Pid),
53 receive
54 {'DOWN', MonitorRef, process, Pid, _Info} ->
55 false
56 after
57 50 ->
58 erlang:demonitor(MonitorRef),
59 true
60 end.
61
David Reissfad60652009-06-04 02:01:35 +000062wait_for(Pid) ->
63 MonitorRef = erlang:monitor(process, Pid),
64 receive
65 {'DOWN', MonitorRef, process, Pid, _Info} ->
66 ok
67 end.
68
David Reiss5e530af2009-06-04 02:01:24 +000069check_extras(0) -> ok;
70check_extras(N) ->
71 receive
72 {client, Type, Pid} ->
73 case {Type, is_up(Pid)} of
74 {unlinked, true} ->
75 io:format("PASS. Unlinked client still alive.~n");
76 {unlinked, false} ->
77 io:format("FAIL. Unlinked client dead.~n");
78 {linked, true} ->
79 io:format("FAIL. Linked client still alive.~n");
80 {linked, false} ->
David Reiss1e1a6972009-06-04 02:01:32 +000081 io:format("PASS. Linked client dead.~n");
82 {tethered, true} ->
83 io:format("FAIL. Tethered client still alive.~n");
84 {tethered, false} ->
85 io:format("PASS. Tethered client dead.~n")
David Reiss5e530af2009-06-04 02:01:24 +000086 end,
87 check_extras(N-1)
88 after
89 500 ->
90 io:format("FAIL. Expected ~p more clients.~n", [N])
91 end.
92
David Reissbb97fd92009-06-04 02:01:28 +000093make_thrift_client(Opts) ->
94 thrift_client:start(fun()->ok end, thriftTest_thrift, Opts).
95
David Reiss5e530af2009-06-04 02:01:24 +000096make_protocol_factory(Port) ->
97 {ok, TransportFactory} =
98 thrift_socket_transport:new_transport_factory(
99 "127.0.0.1", Port, []),
100 {ok, ProtocolFactory} =
101 thrift_binary_protocol:new_protocol_factory(
102 TransportFactory, []),
103 ProtocolFactory.
104
105
David Reissfad60652009-06-04 02:01:35 +0000106test_start(Port) ->
David Reissbb97fd92009-06-04 02:01:28 +0000107 {ok, Client1} = make_thrift_client([{connect, false}]),
David Reiss5e530af2009-06-04 02:01:24 +0000108 tester ! {client, unlinked, Client1},
David Reissbb97fd92009-06-04 02:01:28 +0000109 {ok, Client2} = make_thrift_client([{connect, false}]),
David Reiss5e530af2009-06-04 02:01:24 +0000110 io:format("PASS. Unlinked clients created.~n"),
111 try
David Reissfad60652009-06-04 02:01:35 +0000112 gen_server:call(Client2, {connect, make_protocol_factory(Port)}),
113 thrift_client:call(Client2, testVoid, []),
114 io:format("FAIL. Unlinked client connected and called.~n", [])
David Reiss5e530af2009-06-04 02:01:24 +0000115 catch
116 Kind:Info ->
117 io:format("PASS. Caught unlinked error. ~p:~p~n", [Kind, Info])
118 end,
119 receive after 100 ->
120 io:format("PASS. Still alive after unlinked death.~n"),
121 %% Hang around a little longer so our parent can verify.
122 receive after 200 -> ok end
123 end,
124 %% Exit abnormally to not kill our unlinked extra client.
125 exit(die).
126
David Reissfad60652009-06-04 02:01:35 +0000127test_linked(Port) ->
David Reissbb97fd92009-06-04 02:01:28 +0000128 {ok, Client1} = make_thrift_client([{connect, false}, {monitor, link}]),
David Reiss5e530af2009-06-04 02:01:24 +0000129 tester ! {client, linked, Client1},
David Reissbb97fd92009-06-04 02:01:28 +0000130 {ok, Client2} = make_thrift_client([{connect, false}, {monitor, link}]),
David Reiss5e530af2009-06-04 02:01:24 +0000131 io:format("PASS. Linked clients created.~n"),
132 try
David Reissfad60652009-06-04 02:01:35 +0000133 gen_server:call(Client2, {connect, make_protocol_factory(Port)}),
134 thrift_client:call(Client2, testVoid, []),
135 io:format("FAIL. Linked client connected and called.~n", [])
David Reiss5e530af2009-06-04 02:01:24 +0000136 catch
137 Kind:Info ->
138 io:format("FAIL. Caught linked error. ~p:~p~n", [Kind, Info])
139 end,
140 receive after 100 ->
141 io:format("FAIL. Still alive after linked death.~n"),
142 % Hang around a little longer so our parent can verify.
143 receive after 200 -> ok end
144 end,
145 %% Exit abnormally to kill our linked extra client.
146 %% But we should never get here.
147 exit(die).
David Reiss1e1a6972009-06-04 02:01:32 +0000148
David Reissfad60652009-06-04 02:01:35 +0000149test_tethered(Port) ->
David Reiss1e1a6972009-06-04 02:01:32 +0000150 {ok, Client1} = make_thrift_client([{connect, false}, {monitor, tether}]),
151 tester ! {client, tethered, Client1},
152 {ok, Client2} = make_thrift_client([{connect, false}, {monitor, tether}]),
153 io:format("PASS. Tethered clients created.~n"),
154 try
David Reissfad60652009-06-04 02:01:35 +0000155 gen_server:call(Client2, {connect, make_protocol_factory(Port)}),
156 thrift_client:call(Client2, testVoid, []),
157 io:format("FAIL. Tethered client connected and called.~n", [])
David Reiss1e1a6972009-06-04 02:01:32 +0000158 catch
159 Kind:Info ->
160 io:format("PASS. Caught tethered error. ~p:~p~n", [Kind, Info])
161 end,
162 receive after 100 ->
163 io:format("PASS. Still alive after tethered death.~n"),
164 % Hang around a little longer so our parent can verify.
165 receive after 200 -> ok end
166 end,
167 %% Exit abnormally to kill our tethered extra client.
168 exit(die).