2016-04-20 11:31:19 +00:00
|
|
|
-module(woody_tests_SUITE).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
|
|
|
-include_lib("common_test/include/ct.hrl").
|
|
|
|
|
2016-05-04 17:40:00 +00:00
|
|
|
-include("woody_test_thrift.hrl").
|
2016-04-20 11:31:19 +00:00
|
|
|
-include("src/woody_defs.hrl").
|
2016-04-14 07:40:33 +00:00
|
|
|
|
|
|
|
-behaviour(supervisor).
|
2016-04-20 11:31:19 +00:00
|
|
|
-behaviour(woody_server_thrift_handler).
|
|
|
|
-behaviour(woody_event_handler).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
|
|
|
%% supervisor callbacks
|
|
|
|
-export([init/1]).
|
|
|
|
|
2016-04-20 11:31:19 +00:00
|
|
|
%% woody_server_thrift_handler callbacks
|
2016-05-05 11:18:49 +00:00
|
|
|
-export([handle_function/4]).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-20 11:31:19 +00:00
|
|
|
%% woody_event_handler callbacks
|
2016-05-05 13:30:14 +00:00
|
|
|
-export([handle_event/3]).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-05-20 15:55:02 +00:00
|
|
|
%% common test API
|
|
|
|
-export([all/0,
|
|
|
|
init_per_suite/1, init_per_testcase/2, end_per_suite/1, end_per_test_case/2]).
|
|
|
|
-export([
|
|
|
|
call_safe_ok_test/1,
|
|
|
|
call_ok_test/1,
|
|
|
|
call_safe_handler_throw_test/1,
|
|
|
|
call_handler_throw_test/1,
|
|
|
|
call_safe_handler_throw_unexpected_test/1,
|
|
|
|
call_handler_throw_unexpected_test/1,
|
|
|
|
call_safe_handler_error_test/1,
|
|
|
|
call_handler_error_test/1,
|
|
|
|
call_safe_client_transport_error_test/1,
|
|
|
|
call_client_transport_error_test/1,
|
|
|
|
call_safe_server_transport_error_test/1,
|
|
|
|
call_server_transport_error_test/1,
|
|
|
|
call_oneway_void_test/1,
|
|
|
|
call_async_ok_test/1,
|
2016-05-20 23:26:59 +00:00
|
|
|
call_pass_through_ok_test/1,
|
|
|
|
call_pass_through_except_test/1,
|
|
|
|
call_no_pass_through_bad_ok_test/1,
|
|
|
|
call_no_pass_through_bad_except_test/1,
|
2016-05-20 15:55:02 +00:00
|
|
|
span_ids_sequence_test/1,
|
|
|
|
call_with_client_pool_test/1,
|
|
|
|
multiplexed_transport_test/1,
|
|
|
|
allowed_transport_options_test/1,
|
|
|
|
server_http_request_validation_test/1
|
|
|
|
]).
|
|
|
|
|
2016-04-14 07:40:33 +00:00
|
|
|
%% internal API
|
|
|
|
-export([call/4, call_safe/4]).
|
|
|
|
|
2016-05-04 17:40:00 +00:00
|
|
|
|
|
|
|
-define(THRIFT_DEFS, woody_test_thrift).
|
|
|
|
|
2016-04-14 07:40:33 +00:00
|
|
|
%% Weapons service
|
|
|
|
-define(SLOTS, #{
|
|
|
|
1 => <<"Impact Hammer">>,
|
|
|
|
2 => <<"Enforcer">>,
|
|
|
|
3 => <<"Bio Rifle">>,
|
|
|
|
4 => <<"Shock Rifle">>,
|
|
|
|
5 => <<"Pulse Gun">>,
|
|
|
|
6 => <<"Ripper">>,
|
|
|
|
7 => <<"Minigun">>,
|
|
|
|
8 => <<"Flak Cannon">>,
|
|
|
|
9 => <<"Rocket Launcher">>,
|
|
|
|
0 => <<"Sniper Rifle">>
|
|
|
|
}).
|
|
|
|
|
2016-05-25 12:59:01 +00:00
|
|
|
-define(weapon(Name, Pos, Ammo), Name => #'Weapon'{
|
2016-04-15 10:28:34 +00:00
|
|
|
name = Name,
|
2016-04-14 07:40:33 +00:00
|
|
|
slot_pos = Pos,
|
2016-04-15 10:28:34 +00:00
|
|
|
ammo = Ammo
|
2016-04-14 07:40:33 +00:00
|
|
|
}).
|
|
|
|
-define(weapon(Name, Pos), ?weapon(Name, Pos, undefined)).
|
|
|
|
|
|
|
|
-define(WEAPONS, #{
|
2016-04-15 10:28:34 +00:00
|
|
|
?weapon(<<"Impact Hammer">> , 1),
|
|
|
|
?weapon(<<"Enforcer">> , 2, 25),
|
|
|
|
?weapon(<<"Bio Rifle">> , 3, 0),
|
|
|
|
?weapon(<<"Shock Rifle">> , 4, 0),
|
|
|
|
?weapon(<<"Pulse Gun">> , 5, 0),
|
|
|
|
?weapon(<<"Ripper">> , 6, 16),
|
|
|
|
?weapon(<<"Minigun">> , 7, 0),
|
|
|
|
?weapon(<<"Flak Cannon">> , 8, 30),
|
|
|
|
?weapon(<<"Rocket Launcher">> , 9, 6),
|
|
|
|
?weapon(<<"Sniper Rifle">> , 0, 20)
|
2016-04-14 07:40:33 +00:00
|
|
|
}).
|
|
|
|
|
2016-05-25 12:59:01 +00:00
|
|
|
-define(weapon_failure(Reason), #'WeaponFailure'{
|
2016-04-15 10:28:34 +00:00
|
|
|
code = <<"weapon_error">>,
|
2016-04-14 07:40:33 +00:00
|
|
|
reason = genlib:to_binary(Reason)
|
|
|
|
}).
|
|
|
|
|
2016-05-25 12:59:01 +00:00
|
|
|
-define(powerup_failure(Reason), #'PowerupFailure'{
|
2016-05-20 20:07:43 +00:00
|
|
|
code = <<"powerup_error">>,
|
|
|
|
reason = genlib:to_binary(Reason)
|
|
|
|
}).
|
|
|
|
|
|
|
|
-define(except_weapon_failure (Reason), {exception, ?weapon_failure (Reason)}).
|
|
|
|
-define(except_powerup_failure(Reason), {exception, ?powerup_failure(Reason)}).
|
2016-04-19 13:26:05 +00:00
|
|
|
|
2016-04-14 07:40:33 +00:00
|
|
|
-define(pos_error, {pos_error, "pos out of boundaries"}).
|
|
|
|
|
|
|
|
%% Powerup service
|
|
|
|
-define(powerup(Name, Params),
|
2016-05-25 12:59:01 +00:00
|
|
|
Name => #'Powerup'{name = Name, Params}
|
2016-04-14 07:40:33 +00:00
|
|
|
).
|
|
|
|
|
|
|
|
-define(POWERUPS, #{
|
2016-04-15 10:28:34 +00:00
|
|
|
?powerup(<<"Thigh Pads">> , level = 23),
|
|
|
|
?powerup(<<"Body Armor">> , level = 82),
|
|
|
|
?powerup(<<"Shield Belt">> , level = 0),
|
|
|
|
?powerup(<<"AntiGrav Boots">> , level = 2),
|
|
|
|
?powerup(<<"Damage Amplifier">> , time_left = 0),
|
|
|
|
?powerup(<<"Invisibility">> , time_left = 0)
|
2016-04-14 07:40:33 +00:00
|
|
|
}).
|
|
|
|
|
|
|
|
|
2016-04-15 10:28:34 +00:00
|
|
|
-define(SERVER_IP , {0,0,0,0}).
|
|
|
|
-define(SERVER_PORT , 8085).
|
|
|
|
-define(URL_BASE , "0.0.0.0:8085").
|
2016-04-20 11:31:19 +00:00
|
|
|
-define(PATH_WEAPONS , "/v1/woody/test/weapons").
|
|
|
|
-define(PATH_POWERUPS , "/v1/woody/test/powerups").
|
2016-04-14 07:40:33 +00:00
|
|
|
|
|
|
|
%%
|
|
|
|
%% tests descriptions
|
|
|
|
%%
|
|
|
|
all() ->
|
|
|
|
[
|
2016-04-14 11:18:27 +00:00
|
|
|
call_safe_ok_test,
|
|
|
|
call_ok_test,
|
|
|
|
call_safe_handler_throw_test,
|
|
|
|
call_handler_throw_test,
|
|
|
|
call_safe_handler_throw_unexpected_test,
|
|
|
|
call_handler_throw_unexpected_test,
|
|
|
|
call_safe_handler_error_test,
|
|
|
|
call_handler_error_test,
|
|
|
|
call_safe_client_transport_error_test,
|
|
|
|
call_client_transport_error_test,
|
|
|
|
call_safe_server_transport_error_test,
|
|
|
|
call_server_transport_error_test,
|
2016-04-14 12:27:08 +00:00
|
|
|
call_oneway_void_test,
|
2016-04-14 11:18:27 +00:00
|
|
|
call_async_ok_test,
|
2016-05-20 23:26:59 +00:00
|
|
|
call_pass_through_ok_test,
|
|
|
|
call_pass_through_except_test,
|
|
|
|
call_no_pass_through_bad_ok_test,
|
|
|
|
call_no_pass_through_bad_except_test,
|
2016-04-19 13:26:05 +00:00
|
|
|
span_ids_sequence_test,
|
2016-04-14 17:55:47 +00:00
|
|
|
call_with_client_pool_test,
|
2016-04-19 13:26:05 +00:00
|
|
|
multiplexed_transport_test,
|
|
|
|
allowed_transport_options_test,
|
|
|
|
server_http_request_validation_test
|
2016-04-14 07:40:33 +00:00
|
|
|
].
|
|
|
|
|
|
|
|
%%
|
|
|
|
%% starting/stopping
|
|
|
|
%%
|
|
|
|
init_per_suite(C) ->
|
2016-04-20 11:31:19 +00:00
|
|
|
{ok, Apps} = application:ensure_all_started(woody),
|
2016-04-14 07:40:33 +00:00
|
|
|
[{apps, Apps}|C].
|
|
|
|
|
|
|
|
end_per_suite(C) ->
|
|
|
|
[application_stop(App) || App <- proplists:get_value(apps, C)].
|
|
|
|
|
|
|
|
application_stop(App=sasl) ->
|
|
|
|
%% hack for preventing sasl deadlock
|
|
|
|
%% http://erlang.org/pipermail/erlang-questions/2014-May/079012.html
|
|
|
|
error_logger:delete_report_handler(cth_log_redirect),
|
2016-05-20 23:26:59 +00:00
|
|
|
_ = application:stop(App),
|
2016-04-14 07:40:33 +00:00
|
|
|
error_logger:add_report_handler(cth_log_redirect),
|
|
|
|
ok;
|
|
|
|
application_stop(App) ->
|
|
|
|
application:stop(App).
|
|
|
|
|
|
|
|
init_per_testcase(_, C) ->
|
|
|
|
{ok, Sup} = supervisor:start_link({local, ?MODULE}, ?MODULE, []),
|
2016-05-25 12:59:01 +00:00
|
|
|
{ok, _} = start_woody_server(woody_ct, Sup, ['Weapons', 'Powerups']),
|
2016-04-14 07:40:33 +00:00
|
|
|
[{sup, Sup} | C].
|
|
|
|
|
2016-04-20 11:31:19 +00:00
|
|
|
start_woody_server(Id, Sup, Services) ->
|
|
|
|
Server = woody_server:child_spec(Id, #{
|
2016-04-15 10:28:34 +00:00
|
|
|
handlers => [get_handler(S) || S <- Services],
|
2016-04-14 07:40:33 +00:00
|
|
|
event_handler => ?MODULE,
|
2016-04-15 10:28:34 +00:00
|
|
|
ip => ?SERVER_IP,
|
|
|
|
port => ?SERVER_PORT,
|
|
|
|
net_opts => []
|
2016-04-14 07:40:33 +00:00
|
|
|
}),
|
|
|
|
{ok, _} = supervisor:start_child(Sup, Server).
|
|
|
|
|
2016-05-25 12:59:01 +00:00
|
|
|
get_handler('Powerups') ->
|
2016-04-14 07:40:33 +00:00
|
|
|
{
|
|
|
|
?PATH_POWERUPS,
|
2016-05-25 12:59:01 +00:00
|
|
|
{{?THRIFT_DEFS, 'Powerups'}, ?MODULE, []}
|
2016-04-14 07:40:33 +00:00
|
|
|
};
|
2016-05-25 12:59:01 +00:00
|
|
|
get_handler('Weapons') ->
|
2016-04-14 07:40:33 +00:00
|
|
|
{
|
|
|
|
?PATH_WEAPONS,
|
2016-05-25 12:59:01 +00:00
|
|
|
{{?THRIFT_DEFS, 'Weapons'}, ?MODULE, []}
|
2016-04-14 07:40:33 +00:00
|
|
|
}.
|
|
|
|
|
|
|
|
end_per_test_case(_,C) ->
|
|
|
|
Sup = proplists:get_value(sup, C),
|
|
|
|
exit(Sup, shutdown),
|
|
|
|
Ref = monitor(process, Sup),
|
|
|
|
receive
|
|
|
|
{'DOWN', Ref, process, Sup, _Reason} ->
|
2016-04-15 10:28:34 +00:00
|
|
|
demonitor(Ref),
|
|
|
|
ok
|
2016-04-14 07:40:33 +00:00
|
|
|
after 1000 ->
|
2016-04-15 10:28:34 +00:00
|
|
|
demonitor(Ref,[flush]),
|
2016-04-14 07:40:33 +00:00
|
|
|
error(exit_timeout)
|
|
|
|
end.
|
|
|
|
|
|
|
|
|
|
|
|
%%
|
|
|
|
%% tests
|
|
|
|
%%
|
2016-04-14 11:18:27 +00:00
|
|
|
call_safe_ok_test(_) ->
|
2016-04-14 07:40:33 +00:00
|
|
|
Gun = <<"Enforcer">>,
|
2016-04-19 13:26:05 +00:00
|
|
|
gun_test_basic(call_safe, <<"call_safe_ok">>, Gun,
|
2016-04-17 21:38:00 +00:00
|
|
|
{ok, genlib_map:get(Gun, ?WEAPONS)}, true).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_ok_test(_) ->
|
2016-04-14 07:40:33 +00:00
|
|
|
Gun = <<"Enforcer">>,
|
2016-04-19 13:26:05 +00:00
|
|
|
gun_test_basic(call, <<"call_ok">>, Gun,
|
2016-04-17 21:38:00 +00:00
|
|
|
{ok, genlib_map:get(Gun, ?WEAPONS)}, true).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_safe_handler_throw_test(_) ->
|
2016-04-14 07:40:33 +00:00
|
|
|
Gun = <<"Bio Rifle">>,
|
2016-04-19 13:26:05 +00:00
|
|
|
gun_test_basic(call_safe, <<"call_safe_handler_throw">>, Gun,
|
|
|
|
?except_weapon_failure("out of ammo"), true).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_handler_throw_test(_) ->
|
2016-04-14 07:40:33 +00:00
|
|
|
Gun = <<"Bio Rifle">>,
|
2016-04-17 21:38:00 +00:00
|
|
|
gun_catch_test_basic(<<"call_handler_throw">>, Gun,
|
2016-04-19 13:26:05 +00:00
|
|
|
{throw, ?except_weapon_failure("out of ammo")}, true).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_safe_handler_throw_unexpected_test(_) ->
|
2016-04-15 10:28:34 +00:00
|
|
|
Id = <<"call_safe_handler_throw_unexpected">>,
|
2016-04-14 07:40:33 +00:00
|
|
|
Current = genlib_map:get(<<"Rocket Launcher">>, ?WEAPONS),
|
2016-05-05 11:18:49 +00:00
|
|
|
Context = make_context(Id),
|
|
|
|
Expect = {{error, ?error_transport(server_error)}, Context},
|
2016-05-25 12:59:01 +00:00
|
|
|
Expect = call_safe(Context, 'Weapons', switch_weapon,
|
2016-04-14 07:40:33 +00:00
|
|
|
[Current, next, 1, self_to_bin()]),
|
|
|
|
{ok, _} = receive_msg({Id, Current}).
|
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_handler_throw_unexpected_test(_) ->
|
2016-04-15 10:28:34 +00:00
|
|
|
Id = <<"call_handler_throw_unexpected">>,
|
2016-04-14 07:40:33 +00:00
|
|
|
Current = genlib_map:get(<<"Rocket Launcher">>, ?WEAPONS),
|
2016-05-05 11:18:49 +00:00
|
|
|
Context = make_context(Id),
|
|
|
|
Expect = {?error_transport(server_error), Context},
|
2016-05-25 12:59:01 +00:00
|
|
|
try call(Context, 'Weapons', switch_weapon, [Current, next, 1, self_to_bin()])
|
2016-04-14 07:40:33 +00:00
|
|
|
catch
|
|
|
|
error:Expect -> ok
|
|
|
|
end,
|
|
|
|
{ok, _} = receive_msg({Id, Current}).
|
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_safe_handler_error_test(_) ->
|
2016-04-14 07:40:33 +00:00
|
|
|
Gun = <<"The Ultimate Super Mega Destroyer">>,
|
2016-04-19 13:26:05 +00:00
|
|
|
gun_test_basic(call_safe, <<"call_safe_handler_error">>, Gun,
|
|
|
|
{error, ?error_transport(server_error)}, true).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_handler_error_test(_) ->
|
2016-04-14 07:40:33 +00:00
|
|
|
Gun = <<"The Ultimate Super Mega Destroyer">>,
|
2016-04-17 21:38:00 +00:00
|
|
|
gun_catch_test_basic(<<"call_handler_error">>, Gun,
|
2016-04-19 13:26:05 +00:00
|
|
|
{error, ?error_transport(server_error)}, true).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_safe_client_transport_error_test(_) ->
|
2016-04-17 21:38:00 +00:00
|
|
|
Gun = 'Wrong Type of Mega Destroyer',
|
2016-05-05 11:18:49 +00:00
|
|
|
Id = <<"call_safe_client_transport_error">>,
|
|
|
|
Context = make_context(Id),
|
|
|
|
{{error, ?error_protocol(_)}, Context} = call_safe(Context,
|
2016-05-25 12:59:01 +00:00
|
|
|
'Weapons', get_weapon, [Gun, self_to_bin()]).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_client_transport_error_test(_) ->
|
2016-04-17 21:38:00 +00:00
|
|
|
Gun = 'Wrong Type of Mega Destroyer',
|
2016-05-05 11:18:49 +00:00
|
|
|
Id = <<"call_client_transport_error">>,
|
|
|
|
Context = make_context(Id),
|
2016-05-25 12:59:01 +00:00
|
|
|
try call(Context, 'Weapons', get_weapon, [Gun, self_to_bin()])
|
2016-04-17 21:38:00 +00:00
|
|
|
catch
|
2016-05-05 11:18:49 +00:00
|
|
|
error:{?error_protocol(_), Context} -> ok
|
2016-04-17 21:38:00 +00:00
|
|
|
end.
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_safe_server_transport_error_test(_) ->
|
2016-05-05 11:18:49 +00:00
|
|
|
Id = <<"call_safe_server_transport_error">>,
|
|
|
|
Armor = <<"Helmet">>,
|
|
|
|
Context = make_context(Id),
|
|
|
|
Expect = {{error, ?error_transport(server_error)}, Context},
|
2016-05-25 12:59:01 +00:00
|
|
|
Expect = call_safe(Context, 'Powerups', get_powerup,
|
2016-04-14 07:40:33 +00:00
|
|
|
[Armor, self_to_bin()]),
|
|
|
|
{ok, _} = receive_msg({Id, Armor}).
|
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_server_transport_error_test(_) ->
|
|
|
|
do_call_server_transport_error(<<"call_server_transport_error">>).
|
|
|
|
|
|
|
|
do_call_server_transport_error(Id) ->
|
2016-05-05 11:18:49 +00:00
|
|
|
Armor = <<"Helmet">>,
|
|
|
|
Context = make_context(Id),
|
|
|
|
Expect = {?error_transport(server_error), Context},
|
2016-05-25 12:59:01 +00:00
|
|
|
try call(Context, 'Powerups', get_powerup, [Armor, self_to_bin()])
|
2016-04-14 07:40:33 +00:00
|
|
|
catch
|
2016-04-14 11:18:27 +00:00
|
|
|
error:Expect -> ok
|
2016-04-14 07:40:33 +00:00
|
|
|
end,
|
|
|
|
{ok, _} = receive_msg({Id, Armor}).
|
|
|
|
|
2016-04-14 12:27:08 +00:00
|
|
|
call_oneway_void_test(_) ->
|
2016-04-15 10:28:34 +00:00
|
|
|
Id = <<"call_oneway_void_test">>,
|
|
|
|
Armor = <<"Helmet">>,
|
2016-05-05 11:18:49 +00:00
|
|
|
Context = make_context(Id),
|
|
|
|
Expect = {ok, Context},
|
2016-05-25 12:59:01 +00:00
|
|
|
Expect = call(Context, 'Powerups', like_powerup, [Armor, self_to_bin()]),
|
2016-04-14 12:27:08 +00:00
|
|
|
{ok, _} = receive_msg({Id, Armor}).
|
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_async_ok_test(C) ->
|
2016-04-15 10:28:34 +00:00
|
|
|
Sup = proplists:get_value(sup, C),
|
|
|
|
Pid = self(),
|
|
|
|
Callback = fun(Res) -> collect(Res, Pid) end,
|
|
|
|
Id1 = <<"call_async_ok1">>,
|
2016-05-05 11:18:49 +00:00
|
|
|
Context1 = make_context(Id1),
|
|
|
|
{ok, Pid1, Context1} = get_weapon(Context1, Sup, Callback, <<"Impact Hammer">>),
|
2016-04-15 10:28:34 +00:00
|
|
|
Id2 = <<"call_async_ok2">>,
|
2016-05-05 11:18:49 +00:00
|
|
|
Context2 = make_context(Id2),
|
|
|
|
{ok, Pid2, Context2} = get_weapon(Context2, Sup, Callback, <<"Flak Cannon">>),
|
|
|
|
{ok, Pid1} = receive_msg({Context1,
|
2016-04-21 10:57:46 +00:00
|
|
|
genlib_map:get(<<"Impact Hammer">>, ?WEAPONS)}),
|
2016-05-05 11:18:49 +00:00
|
|
|
{ok, Pid2} = receive_msg({Context2,
|
2016-04-21 10:57:46 +00:00
|
|
|
genlib_map:get(<<"Flak Cannon">>, ?WEAPONS)}).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-05-05 11:18:49 +00:00
|
|
|
get_weapon(Context, Sup, Cb, Gun) ->
|
2016-05-25 12:59:01 +00:00
|
|
|
call_async(Context, 'Weapons', get_weapon, [Gun, <<>>], Sup, Cb).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-05-05 11:18:49 +00:00
|
|
|
collect({{ok, Result}, Context}, Pid) ->
|
|
|
|
send_msg(Pid, {Context, Result}).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-19 13:26:05 +00:00
|
|
|
span_ids_sequence_test(_) ->
|
|
|
|
Id = <<"span_ids_sequence">>,
|
2016-04-14 07:40:33 +00:00
|
|
|
Current = genlib_map:get(<<"Enforcer">>, ?WEAPONS),
|
2016-05-05 11:18:49 +00:00
|
|
|
Context = make_context(Id),
|
|
|
|
Expect = {{ok, genlib_map:get(<<"Ripper">>, ?WEAPONS)}, Context},
|
2016-05-25 12:59:01 +00:00
|
|
|
Expect = call(Context, 'Weapons', switch_weapon,
|
2016-04-14 07:40:33 +00:00
|
|
|
[Current, next, 1, self_to_bin()]).
|
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
call_with_client_pool_test(_) ->
|
2016-04-14 07:40:33 +00:00
|
|
|
Pool = guns,
|
2016-05-05 11:18:49 +00:00
|
|
|
ok = woody_client_thrift:start_pool(Pool, 10),
|
|
|
|
Id = <<"call_with_client_pool">>,
|
|
|
|
Gun = <<"Enforcer">>,
|
|
|
|
Context = make_context(Id),
|
2016-05-25 12:59:01 +00:00
|
|
|
{Url, Service} = get_service_endpoint('Weapons'),
|
2016-05-05 11:18:49 +00:00
|
|
|
Expect = {{ok, genlib_map:get(Gun, ?WEAPONS)}, Context},
|
2016-04-20 11:31:19 +00:00
|
|
|
Expect = woody_client:call(
|
2016-05-05 11:18:49 +00:00
|
|
|
Context,
|
2016-04-14 07:40:33 +00:00
|
|
|
{Service, get_weapon, [Gun, self_to_bin()]},
|
|
|
|
#{url => Url, pool => Pool}
|
|
|
|
),
|
2016-05-20 23:26:59 +00:00
|
|
|
{ok, _} = receive_msg({Id, Gun}),
|
2016-04-20 11:31:19 +00:00
|
|
|
ok = woody_client_thrift:stop_pool(Pool).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-14 17:55:47 +00:00
|
|
|
multiplexed_transport_test(_) ->
|
|
|
|
Id = <<"multiplexed_transport">>,
|
2016-04-19 13:26:05 +00:00
|
|
|
{Client1, {error, ?error_transport(bad_request)}} = thrift_client:call(
|
2016-04-21 10:57:46 +00:00
|
|
|
make_thrift_multiplexed_client(Id, "powerups",
|
2016-05-25 12:59:01 +00:00
|
|
|
get_service_endpoint('Powerups')),
|
2016-04-14 17:55:47 +00:00
|
|
|
get_powerup,
|
|
|
|
[<<"Body Armor">>, self_to_bin()]
|
|
|
|
),
|
|
|
|
thrift_client:close(Client1).
|
|
|
|
|
|
|
|
make_thrift_multiplexed_client(Id, ServiceName, {Url, Service}) ->
|
|
|
|
{ok, Protocol} = thrift_binary_protocol:new(
|
2016-04-20 11:31:19 +00:00
|
|
|
woody_client_thrift_http_transport:new(
|
2016-04-14 23:20:59 +00:00
|
|
|
#{
|
2016-04-16 19:11:54 +00:00
|
|
|
span_id => Id, trace_id => Id, parent_id => Id
|
2016-04-14 23:20:59 +00:00
|
|
|
},
|
2016-04-17 21:38:00 +00:00
|
|
|
#{url => Url}, ?MODULE
|
2016-04-14 23:20:59 +00:00
|
|
|
),
|
2016-04-14 17:55:47 +00:00
|
|
|
[{strict_read, true}, {strict_write, true}]
|
|
|
|
),
|
|
|
|
{ok, Protocol1} = thrift_multiplexed_protocol:new(Protocol, ServiceName),
|
2016-05-05 11:18:49 +00:00
|
|
|
{ok, Context} = thrift_client:new(Protocol1, Service),
|
|
|
|
Context.
|
2016-04-14 17:55:47 +00:00
|
|
|
|
2016-04-19 13:26:05 +00:00
|
|
|
allowed_transport_options_test(_) ->
|
2016-05-05 11:18:49 +00:00
|
|
|
Id = <<"allowed_transport_options">>,
|
|
|
|
Gun = <<"Enforcer">>,
|
2016-04-19 13:26:05 +00:00
|
|
|
Args = [Gun, self_to_bin()],
|
2016-05-25 12:59:01 +00:00
|
|
|
{Url, Service} = get_service_endpoint('Weapons'),
|
2016-04-19 13:26:05 +00:00
|
|
|
Pool = guns,
|
2016-04-20 11:31:19 +00:00
|
|
|
ok = woody_client_thrift:start_pool(Pool, 1),
|
2016-05-05 11:18:49 +00:00
|
|
|
Context = make_context(Id),
|
2016-04-19 13:26:05 +00:00
|
|
|
Options = #{url => Url, pool => Pool, ssl_options => [], connect_timeout => 0},
|
2016-05-05 11:18:49 +00:00
|
|
|
{{error, ?error_transport(connect_timeout)}, Context} = woody_client:call_safe(
|
|
|
|
Context,
|
2016-04-19 13:26:05 +00:00
|
|
|
{Service, get_weapon, Args},
|
|
|
|
Options
|
|
|
|
),
|
|
|
|
BadOpt = #{custom_option => 'fire!'},
|
2016-04-21 10:57:46 +00:00
|
|
|
ErrorBadOpt = {badarg, {unsupported_options, BadOpt}},
|
2016-05-05 11:18:49 +00:00
|
|
|
{{error, {error, ErrorBadOpt, _}}, Context} = woody_client:call_safe(
|
|
|
|
Context,
|
2016-04-19 13:26:05 +00:00
|
|
|
{Service, get_weapon, Args},
|
|
|
|
maps:merge(Options, BadOpt)
|
2016-04-20 11:31:19 +00:00
|
|
|
),
|
|
|
|
ok = woody_client_thrift:stop_pool(Pool).
|
2016-04-19 13:26:05 +00:00
|
|
|
|
|
|
|
server_http_request_validation_test(_) ->
|
|
|
|
Id = <<"server_http_request_validation">>,
|
2016-05-25 12:59:01 +00:00
|
|
|
{Url, _Service} = get_service_endpoint('Weapons'),
|
2016-04-19 13:26:05 +00:00
|
|
|
Headers = [
|
|
|
|
{?HEADER_NAME_RPC_ROOT_ID , genlib:to_binary(Id)},
|
|
|
|
{?HEADER_NAME_RPC_ID , genlib:to_binary(Id)},
|
|
|
|
{?HEADER_NAME_RPC_PARENT_ID , genlib:to_binary(<<"undefined">>)},
|
|
|
|
{<<"content-type">> , ?CONTENT_TYPE_THRIFT},
|
|
|
|
{<<"accept">> , ?CONTENT_TYPE_THRIFT}
|
|
|
|
],
|
|
|
|
|
|
|
|
%% Check missing Id headers, content-type and an empty body on the last step,
|
2016-04-21 10:57:46 +00:00
|
|
|
%% as missing Accept is allowed
|
2016-04-19 13:26:05 +00:00
|
|
|
lists:foreach(fun({C, H}) ->
|
|
|
|
{ok, C, _, _} = hackney:request(post, Url, Headers -- [H], <<>>, [{url, Url}])
|
2016-04-22 12:05:04 +00:00
|
|
|
end, lists:zip([400,400,400,415,400], Headers)),
|
2016-04-19 13:26:05 +00:00
|
|
|
|
2016-04-21 10:57:46 +00:00
|
|
|
%% Check wrong Accept
|
2016-04-19 13:26:05 +00:00
|
|
|
{ok, 406, _, _} = hackney:request(post, Url,
|
|
|
|
lists:keyreplace(<<"accept">>, 1, Headers, {<<"accept">>, <<"application/text">>}),
|
|
|
|
<<>>, [{url, Url}]),
|
2016-04-21 10:57:46 +00:00
|
|
|
|
2016-04-19 13:26:05 +00:00
|
|
|
%% Check wrong methods
|
|
|
|
lists:foreach(fun(M) ->
|
|
|
|
{ok, 405, _, _} = hackney:request(M, Url, Headers, <<>>, [{url, Url}]) end,
|
2016-04-21 10:57:46 +00:00
|
|
|
[get, put, delete, trace, options, patch]),
|
|
|
|
{ok, 405, _} = hackney:request(head, Url, Headers, <<>>, [{url, Url}]),
|
|
|
|
{ok, 400, _, _} = hackney:request(connect, Url, Headers, <<>>, [{url, Url}]).
|
2016-04-19 13:26:05 +00:00
|
|
|
|
2016-05-20 23:26:59 +00:00
|
|
|
call_pass_through_ok_test(_) ->
|
|
|
|
Id = <<"call_pass_through_ok">>,
|
|
|
|
Armor = <<"AntiGrav Boots">>,
|
|
|
|
Context = make_context(Id),
|
|
|
|
Expect = {{ok, genlib_map:get(Armor, ?POWERUPS)}, Context},
|
2016-05-25 12:59:01 +00:00
|
|
|
Expect = call(Context, 'Powerups', proxy_get_powerup, [Armor, self_to_bin()]).
|
2016-05-20 23:26:59 +00:00
|
|
|
|
|
|
|
call_pass_through_except_test(_) ->
|
|
|
|
Id = <<"call_pass_through_except">>,
|
|
|
|
Armor = <<"Shield Belt">>,
|
|
|
|
Context = make_context(Id),
|
|
|
|
Expect = {?except_powerup_failure("run out"), Context},
|
2016-05-25 12:59:01 +00:00
|
|
|
try call(Context, 'Powerups', proxy_get_powerup, [Armor, self_to_bin()])
|
2016-05-20 23:26:59 +00:00
|
|
|
catch
|
|
|
|
throw:Expect -> ok
|
|
|
|
end.
|
|
|
|
|
|
|
|
call_no_pass_through_bad_ok_test(_) ->
|
|
|
|
Id = <<"call_no_pass_through_bad_ok">>,
|
|
|
|
Armor = <<"AntiGrav Boots">>,
|
|
|
|
Context = make_context(Id),
|
2016-05-25 12:59:01 +00:00
|
|
|
try call(Context, 'Powerups', bad_proxy_get_powerup, [Armor, self_to_bin()])
|
2016-05-20 23:26:59 +00:00
|
|
|
catch
|
|
|
|
error:{?error_transport(server_error), Context} ->
|
|
|
|
ok
|
|
|
|
end.
|
|
|
|
|
|
|
|
call_no_pass_through_bad_except_test(_) ->
|
|
|
|
Id = <<"call_no_pass_through_bad_except">>,
|
|
|
|
Armor = <<"Shield Belt">>,
|
|
|
|
Context = make_context(Id),
|
2016-05-25 12:59:01 +00:00
|
|
|
try call(Context, 'Powerups', bad_proxy_get_powerup, [Armor, self_to_bin()])
|
2016-05-20 23:26:59 +00:00
|
|
|
catch
|
|
|
|
error:{?error_transport(server_error), Context} ->
|
|
|
|
ok
|
|
|
|
end.
|
2016-04-14 17:55:47 +00:00
|
|
|
|
2016-04-14 07:40:33 +00:00
|
|
|
%%
|
|
|
|
%% supervisor callbacks
|
|
|
|
%%
|
|
|
|
init(_) ->
|
|
|
|
{ok, {
|
|
|
|
{one_for_one, 1, 1}, []
|
|
|
|
}}.
|
|
|
|
|
|
|
|
%%
|
2016-04-20 11:31:19 +00:00
|
|
|
%% woody_server_thrift_handler callbacks
|
2016-04-14 07:40:33 +00:00
|
|
|
%%
|
|
|
|
|
|
|
|
%% Weapons
|
2016-04-16 22:43:01 +00:00
|
|
|
handle_function(switch_weapon, {CurrentWeapon, Direction, Shift, To},
|
2016-05-05 11:18:49 +00:00
|
|
|
Context = #{ parent_id := SpanId, trace_id := TraceId,
|
|
|
|
rpc_id := #{span_id := SpanId, trace_id := TraceId}}, _Opts)
|
2016-04-16 22:43:01 +00:00
|
|
|
->
|
|
|
|
send_msg(To, {SpanId, CurrentWeapon}),
|
2016-05-20 20:07:43 +00:00
|
|
|
{switch_weapon(CurrentWeapon, Direction, Shift, Context), Context};
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-04-16 22:43:01 +00:00
|
|
|
handle_function(get_weapon, {Name, To},
|
2016-05-20 20:07:43 +00:00
|
|
|
Context = #{ parent_id := SpanId, trace_id := TraceId,
|
2016-05-05 11:18:49 +00:00
|
|
|
rpc_id := #{span_id := SpanId, trace_id := TraceId}}, _Opts)
|
2016-04-14 07:40:33 +00:00
|
|
|
->
|
2016-04-16 22:43:01 +00:00
|
|
|
send_msg(To,{SpanId, Name}),
|
2016-04-14 07:40:33 +00:00
|
|
|
Res = case genlib_map:get(Name, ?WEAPONS) of
|
2016-05-25 12:59:01 +00:00
|
|
|
#'Weapon'{ammo = 0} ->
|
2016-05-20 20:07:43 +00:00
|
|
|
throw({?weapon_failure("out of ammo"), Context});
|
2016-05-25 12:59:01 +00:00
|
|
|
Weapon = #'Weapon'{} ->
|
2016-04-14 07:40:33 +00:00
|
|
|
Weapon
|
|
|
|
end,
|
2016-05-20 20:07:43 +00:00
|
|
|
{{ok, Res}, Context};
|
2016-04-14 07:40:33 +00:00
|
|
|
|
|
|
|
%% Powerups
|
2016-04-16 22:43:01 +00:00
|
|
|
handle_function(get_powerup, {Name, To},
|
2016-05-20 20:07:43 +00:00
|
|
|
Context = #{ parent_id := SpanId, trace_id := TraceId,
|
2016-05-05 11:18:49 +00:00
|
|
|
rpc_id := #{span_id := SpanId, trace_id := TraceId}}, _Opts)
|
2016-04-16 22:43:01 +00:00
|
|
|
->
|
|
|
|
send_msg(To, {SpanId, Name}),
|
2016-05-20 20:07:43 +00:00
|
|
|
{{ok, return_powerup(Name, Context)}, Context};
|
|
|
|
|
2016-05-20 23:26:59 +00:00
|
|
|
handle_function(proxy_get_powerup, {Name, To},
|
|
|
|
Context = #{ parent_id := SpanId, trace_id := TraceId,
|
|
|
|
rpc_id := #{span_id := SpanId, trace_id := TraceId}}, _Opts)
|
|
|
|
->
|
2016-05-25 12:59:01 +00:00
|
|
|
call(Context, 'Powerups', get_powerup, [Name, To]);
|
2016-05-20 23:26:59 +00:00
|
|
|
|
|
|
|
handle_function(bad_proxy_get_powerup, {Name, To},
|
|
|
|
Context = #{ parent_id := SpanId, trace_id := TraceId,
|
|
|
|
rpc_id := #{span_id := SpanId, trace_id := TraceId}}, _Opts)
|
|
|
|
->
|
2016-05-25 12:59:01 +00:00
|
|
|
call(Context, 'Powerups', get_powerup, [Name, To]);
|
2016-05-20 23:26:59 +00:00
|
|
|
|
2016-04-16 22:43:01 +00:00
|
|
|
handle_function(like_powerup, {Name, To},
|
2016-05-20 20:07:43 +00:00
|
|
|
Context = #{ parent_id := SpanId, trace_id := TraceId,
|
2016-05-05 11:18:49 +00:00
|
|
|
rpc_id := #{span_id := SpanId, trace_id := TraceId}}, _Opts)
|
2016-04-16 22:43:01 +00:00
|
|
|
->
|
|
|
|
send_msg(To, {SpanId, Name}),
|
2016-05-20 20:07:43 +00:00
|
|
|
{ok, Context}.
|
2016-04-14 07:40:33 +00:00
|
|
|
|
|
|
|
%%
|
2016-04-20 11:31:19 +00:00
|
|
|
%% woody_event_handler callbacks
|
2016-04-14 07:40:33 +00:00
|
|
|
%%
|
2016-05-05 13:30:14 +00:00
|
|
|
handle_event(Type, RpcId, Meta) ->
|
|
|
|
ct:pal(info, "woody event ~p for RPC ID: ~p~n~p", [Type, RpcId, Meta]).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
|
|
|
%%
|
|
|
|
%% internal functions
|
|
|
|
%%
|
2016-05-05 11:18:49 +00:00
|
|
|
make_context(ReqId) ->
|
|
|
|
woody_client:new_context(ReqId, ?MODULE).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-05-05 11:18:49 +00:00
|
|
|
call(Context, ServiceName, Function, Args) ->
|
|
|
|
do_call(call, Context, ServiceName, Function, Args).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-05-05 11:18:49 +00:00
|
|
|
call_safe(Context, ServiceName, Function, Args) ->
|
|
|
|
do_call(call_safe, Context, ServiceName, Function, Args).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-05-05 11:18:49 +00:00
|
|
|
do_call(Call, Context, ServiceName, Function, Args) ->
|
2016-04-14 07:40:33 +00:00
|
|
|
{Url, Service} = get_service_endpoint(ServiceName),
|
2016-04-20 11:31:19 +00:00
|
|
|
woody_client:Call(
|
2016-05-05 11:18:49 +00:00
|
|
|
Context,
|
2016-04-14 07:40:33 +00:00
|
|
|
{Service, Function, Args},
|
|
|
|
#{url => Url}
|
|
|
|
).
|
|
|
|
|
2016-05-05 11:18:49 +00:00
|
|
|
call_async(Context, ServiceName, Function, Args, Sup, Callback) ->
|
2016-04-14 07:40:33 +00:00
|
|
|
{Url, Service} = get_service_endpoint(ServiceName),
|
2016-04-20 11:31:19 +00:00
|
|
|
woody_client:call_async(Sup, Callback,
|
2016-05-05 11:18:49 +00:00
|
|
|
Context,
|
2016-04-14 07:40:33 +00:00
|
|
|
{Service, Function, Args},
|
|
|
|
#{url => Url}
|
|
|
|
).
|
|
|
|
|
2016-05-25 12:59:01 +00:00
|
|
|
get_service_endpoint('Weapons') ->
|
2016-04-14 07:40:33 +00:00
|
|
|
{
|
|
|
|
genlib:to_binary(?URL_BASE ++ ?PATH_WEAPONS),
|
2016-05-25 12:59:01 +00:00
|
|
|
{?THRIFT_DEFS, 'Weapons'}
|
2016-04-14 07:40:33 +00:00
|
|
|
};
|
2016-05-25 12:59:01 +00:00
|
|
|
get_service_endpoint('Powerups') ->
|
2016-04-14 07:40:33 +00:00
|
|
|
{
|
|
|
|
genlib:to_binary(?URL_BASE ++ ?PATH_POWERUPS),
|
2016-05-25 12:59:01 +00:00
|
|
|
{?THRIFT_DEFS, 'Powerups'}
|
2016-04-14 07:40:33 +00:00
|
|
|
}.
|
|
|
|
|
2016-04-19 13:26:05 +00:00
|
|
|
gun_test_basic(CallFun, Id, Gun, {ExpectStatus, ExpectRes}, WithMsg) ->
|
2016-05-05 11:18:49 +00:00
|
|
|
Context = make_context(Id),
|
|
|
|
Expect = {{ExpectStatus, ExpectRes}, Context},
|
2016-05-25 12:59:01 +00:00
|
|
|
Expect = ?MODULE:CallFun(Context, 'Weapons', get_weapon, [Gun, self_to_bin()]),
|
2016-04-14 07:40:33 +00:00
|
|
|
case WithMsg of
|
|
|
|
true -> {ok, _} = receive_msg({Id, Gun});
|
2016-04-15 10:28:34 +00:00
|
|
|
_ -> ok
|
2016-04-14 07:40:33 +00:00
|
|
|
end.
|
|
|
|
|
2016-04-14 11:18:27 +00:00
|
|
|
gun_catch_test_basic(Id, Gun, {Class, Exception}, WithMsg) ->
|
2016-05-05 11:18:49 +00:00
|
|
|
Context = make_context(Id),
|
|
|
|
Expect = {Exception, Context},
|
2016-05-25 12:59:01 +00:00
|
|
|
try call(Context, 'Weapons', get_weapon, [Gun, self_to_bin()])
|
2016-04-14 07:40:33 +00:00
|
|
|
catch
|
|
|
|
Class:Expect -> ok
|
|
|
|
end,
|
|
|
|
case WithMsg of
|
|
|
|
true -> {ok, _} = receive_msg({Id, Gun});
|
2016-04-15 10:28:34 +00:00
|
|
|
_ -> ok
|
2016-04-14 07:40:33 +00:00
|
|
|
end.
|
|
|
|
|
2016-05-05 11:18:49 +00:00
|
|
|
switch_weapon(CurrentWeapon, Direction, Shift, Context) ->
|
2016-05-25 12:59:01 +00:00
|
|
|
case call_safe(Context, 'Weapons', get_weapon,
|
2016-05-20 20:07:43 +00:00
|
|
|
[new_weapon_name(CurrentWeapon, Direction, Shift, Context), self_to_bin()])
|
2016-04-14 07:40:33 +00:00
|
|
|
of
|
2016-04-19 13:26:05 +00:00
|
|
|
{{ok, Weapon}, _} ->
|
2016-04-14 07:40:33 +00:00
|
|
|
{ok, Weapon};
|
2016-05-25 12:59:01 +00:00
|
|
|
{{exception, #'WeaponFailure'{
|
2016-04-15 10:28:34 +00:00
|
|
|
code = <<"weapon_error">>,
|
2016-04-14 07:40:33 +00:00
|
|
|
reason = <<"out of ammo">>
|
2016-05-05 11:18:49 +00:00
|
|
|
}}, NextContex} ->
|
|
|
|
ok = validate_next_context(NextContex, Context),
|
|
|
|
switch_weapon(CurrentWeapon, Direction, Shift + 1, NextContex)
|
2016-04-14 07:40:33 +00:00
|
|
|
end.
|
|
|
|
|
2016-05-25 12:59:01 +00:00
|
|
|
new_weapon_name(#'Weapon'{slot_pos = Pos}, next, Shift, Ctx) ->
|
2016-05-20 20:07:43 +00:00
|
|
|
new_weapon_name(Pos + Shift, Ctx);
|
2016-05-25 12:59:01 +00:00
|
|
|
new_weapon_name(#'Weapon'{slot_pos = Pos}, prev, Shift, Ctx) ->
|
2016-05-20 20:07:43 +00:00
|
|
|
new_weapon_name(Pos - Shift, Ctx).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-05-20 20:07:43 +00:00
|
|
|
new_weapon_name(Pos, _) when is_integer(Pos), Pos >= 0, Pos < 10 ->
|
2016-04-14 07:40:33 +00:00
|
|
|
genlib_map:get(Pos, ?SLOTS, <<"no weapon">>);
|
2016-05-20 20:07:43 +00:00
|
|
|
new_weapon_name(_, Context) ->
|
|
|
|
throw({?pos_error, Context}).
|
2016-04-14 07:40:33 +00:00
|
|
|
|
2016-05-05 11:18:49 +00:00
|
|
|
validate_next_context(#{seq := NextSeq}, #{seq := Seq}) ->
|
2016-04-14 07:40:33 +00:00
|
|
|
NextSeq = Seq + 1,
|
|
|
|
ok.
|
|
|
|
|
2016-05-20 20:07:43 +00:00
|
|
|
-define(BAD_POWERUP_REPLY, powerup_unknown).
|
|
|
|
|
|
|
|
return_powerup(Name, Context) when is_binary(Name) ->
|
|
|
|
return_powerup(genlib_map:get(Name, ?POWERUPS, ?BAD_POWERUP_REPLY), Context);
|
2016-05-25 12:59:01 +00:00
|
|
|
return_powerup(#'Powerup'{level = Level}, Context) when Level == 0 ->
|
2016-05-20 20:07:43 +00:00
|
|
|
throw({?powerup_failure("run out"), Context});
|
2016-05-25 12:59:01 +00:00
|
|
|
return_powerup(#'Powerup'{time_left = Time}, Context) when Time == 0 ->
|
2016-05-20 20:07:43 +00:00
|
|
|
throw({?powerup_failure("expired"), Context});
|
2016-05-25 12:59:01 +00:00
|
|
|
return_powerup(P = #'Powerup'{}, _) ->
|
2016-05-20 20:07:43 +00:00
|
|
|
P;
|
|
|
|
return_powerup(P = ?BAD_POWERUP_REPLY, _) ->
|
|
|
|
P.
|
|
|
|
|
2016-04-14 07:40:33 +00:00
|
|
|
self_to_bin() ->
|
|
|
|
genlib:to_binary(pid_to_list(self())).
|
|
|
|
|
|
|
|
send_msg(<<>>, _) ->
|
|
|
|
ok;
|
|
|
|
send_msg(To, Msg) when is_pid(To) ->
|
2016-05-20 23:26:59 +00:00
|
|
|
To ! {self(), Msg},
|
|
|
|
ok;
|
2016-04-14 07:40:33 +00:00
|
|
|
send_msg(To, Msg) when is_binary(To) ->
|
|
|
|
send_msg(list_to_pid(genlib:to_list(To)), Msg).
|
|
|
|
|
|
|
|
receive_msg(Msg) ->
|
|
|
|
receive
|
|
|
|
{From, Msg} ->
|
|
|
|
{ok, From}
|
|
|
|
after 1000 ->
|
|
|
|
error(get_msg_timeout)
|
|
|
|
end.
|
2016-05-20 20:07:43 +00:00
|
|
|
|