Rev 30 | Blame | Compare with Previous | Last modification | View Log | RSS feed
%%%% Licensed to the Apache Software Foundation (ASF) under one%% or more contributor license agreements. See the NOTICE file%% distributed with this work for additional information%% regarding copyright ownership. The ASF licenses this file%% to you under the Apache License, Version 2.0 (the%% "License"); you may not use this file except in compliance%% with the License. You may obtain a copy of the License at%%%% http://www.apache.org/licenses/LICENSE-2.0%%%% Unless required by applicable law or agreed to in writing,%% software distributed under the License is distributed on an%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY%% KIND, either express or implied. See the License for the%% specific language governing permissions and limitations%% under the License.%%%% Tests the behavior of clients in the face of transport errors.%% Makes sure start, start_linked, and start_tethered work as expected.-module(test_tether).-compile(export_all).t() ->io:format("Beginning transport error test.~n"),Pid1 = erlang:spawn(?MODULE, t_sub, [2]),wait_for(Pid1),io:format("Beginning protocol error test.~n"),Pid2 = erlang:spawn(?MODULE, t_sub, [22]),wait_for(Pid2),ok.t_sub(Port) ->io:format("Starting.~n", []),register(tester, self()),Pid1 = erlang:spawn(?MODULE, test_start, [Port]),receive after 200 -> ok end, % Wait for completion.case is_up(Pid1) oftrue ->io:format("PASS. Unlinked owner still alive.~n");false ->io:format("FAIL. Unlinked owner is dead.~n")end,Pid2 = erlang:spawn(?MODULE, test_linked, [Port]),receive after 200 -> ok end, % Wait for completion.case is_up(Pid2) oftrue ->io:format("FAIL. Linked owner still alive.~n");false ->io:format("PASS. Linked owner is dead.~n")end,Pid3 = erlang:spawn(?MODULE, test_tethered, [Port]),receive after 200 -> ok end, % Wait for completion.case is_up(Pid3) oftrue ->io:format("PASS. Tethered owner still alive.~n");false ->io:format("FAIL. Tethered owner is dead.~n")end,check_extras(3).is_up(Pid) ->MonitorRef = erlang:monitor(process, Pid),receive{'DOWN', MonitorRef, process, Pid, _Info} ->falseafter50 ->erlang:demonitor(MonitorRef),trueend.wait_for(Pid) ->MonitorRef = erlang:monitor(process, Pid),receive{'DOWN', MonitorRef, process, Pid, _Info} ->okend.check_extras(0) -> ok;check_extras(N) ->receive{client, Type, Pid} ->case {Type, is_up(Pid)} of{unlinked, true} ->io:format("PASS. Unlinked client still alive.~n");{unlinked, false} ->io:format("FAIL. Unlinked client dead.~n");{linked, true} ->io:format("FAIL. Linked client still alive.~n");{linked, false} ->io:format("PASS. Linked client dead.~n");{tethered, true} ->io:format("FAIL. Tethered client still alive.~n");{tethered, false} ->io:format("PASS. Tethered client dead.~n")end,check_extras(N-1)after500 ->io:format("FAIL. Expected ~p more clients.~n", [N])end.make_thrift_client(Opts) ->thrift_client:start(fun()->ok end, thriftTest_thrift, Opts).make_protocol_factory(Port) ->{ok, TransportFactory} =thrift_socket_transport:new_transport_factory("127.0.0.1", Port, []),{ok, ProtocolFactory} =thrift_binary_protocol:new_protocol_factory(TransportFactory, []),ProtocolFactory.test_start(Port) ->{ok, Client1} = make_thrift_client([{connect, false}]),tester ! {client, unlinked, Client1},{ok, Client2} = make_thrift_client([{connect, false}]),io:format("PASS. Unlinked clients created.~n"),trygen_server:call(Client2, {connect, make_protocol_factory(Port)}),thrift_client:call(Client2, testVoid, []),io:format("FAIL. Unlinked client connected and called.~n", [])catchKind:Info ->io:format("PASS. Caught unlinked error. ~p:~p~n", [Kind, Info])end,receive after 100 ->io:format("PASS. Still alive after unlinked death.~n"),%% Hang around a little longer so our parent can verify.receive after 200 -> ok endend,%% Exit abnormally to not kill our unlinked extra client.exit(die).test_linked(Port) ->{ok, Client1} = make_thrift_client([{connect, false}, {monitor, link}]),tester ! {client, linked, Client1},{ok, Client2} = make_thrift_client([{connect, false}, {monitor, link}]),io:format("PASS. Linked clients created.~n"),trygen_server:call(Client2, {connect, make_protocol_factory(Port)}),thrift_client:call(Client2, testVoid, []),io:format("FAIL. Linked client connected and called.~n", [])catchKind:Info ->io:format("FAIL. Caught linked error. ~p:~p~n", [Kind, Info])end,receive after 100 ->io:format("FAIL. Still alive after linked death.~n"),% Hang around a little longer so our parent can verify.receive after 200 -> ok endend,%% Exit abnormally to kill our linked extra client.%% But we should never get here.exit(die).test_tethered(Port) ->{ok, Client1} = make_thrift_client([{connect, false}, {monitor, tether}]),tester ! {client, tethered, Client1},{ok, Client2} = make_thrift_client([{connect, false}, {monitor, tether}]),io:format("PASS. Tethered clients created.~n"),trygen_server:call(Client2, {connect, make_protocol_factory(Port)}),thrift_client:call(Client2, testVoid, []),io:format("FAIL. Tethered client connected and called.~n", [])catchKind:Info ->io:format("PASS. Caught tethered error. ~p:~p~n", [Kind, Info])end,receive after 100 ->io:format("PASS. Still alive after tethered death.~n"),% Hang around a little longer so our parent can verify.receive after 200 -> ok endend,%% Exit abnormally to kill our tethered extra client.exit(die).