From 2c083eb112b73a99f8a14966c01b953545a2e6be Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 3 Mar 2021 13:47:44 +0300 Subject: [PATCH] ED-65: Allow to force woody request timeout (#9) * Switch to rbkmoney/image-build-erlang@1aa9b46 * Bump to rbkmoney/woody_erlang@f2cd308 * Bump to erlfmt 0.11.0 * Switch to rebar3_lint 0.3.2 --- Makefile | 5 ++- elvis.config | 55 ------------------------ rebar.config | 65 ++++++++++++++++------------ rebar.lock | 57 ++++++++++++++++--------- src/bouncer_client_woody.erl | 75 ++++++++++++++++++++------------- src/bouncer_context_helpers.erl | 4 +- test/bouncer_client_SUITE.erl | 67 +++++++++++++++++++++++------ 7 files changed, 178 insertions(+), 150 deletions(-) delete mode 100644 elvis.config diff --git a/Makefile b/Makefile index ed46ee9..25ac58d 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,8 @@ TEMPLATES_PATH := . # Name of the service SERVICE_NAME := bouncer_client_erlang -BUILD_IMAGE_TAG := 0c638a682f4735a65ef232b81ed872ba494574c3 +BUILD_IMAGE_NAME := build-erlang +BUILD_IMAGE_TAG := 1aa9b46b343bcf3bf0d4359ceca1a7ab6d577699 CALL_ANYWHERE := \ submodules \ @@ -37,7 +38,7 @@ xref: $(REBAR) xref lint: - elvis rock + $(REBAR) lint check_format: $(REBAR) fmt -c diff --git a/elvis.config b/elvis.config deleted file mode 100644 index abd7f7d..0000000 --- a/elvis.config +++ /dev/null @@ -1,55 +0,0 @@ -[ - {elvis, [ - {config, [ - #{ - dirs => [ - "src", - "test" - ], - filter => "*.erl", - ignore => ["_SUITE.erl$"], - rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace}, - {elvis_style, macro_module_names}, - {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, - {elvis_style, nesting_level, #{level => 4}}, - {elvis_style, god_modules, #{limit => 25}}, - {elvis_style, no_if_expression}, - {elvis_style, invalid_dynamic_call, #{ignore => []}}, - {elvis_style, used_ignored_variable}, - {elvis_style, no_behavior_info}, - {elvis_style, module_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*(_SUITE)?$"}}, - {elvis_style, function_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*$"}}, - {elvis_style, state_record_and_type}, - {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself, #{ - min_complexity => 30, - ignore => [] - }}, - {elvis_style, no_debug_call, #{}} - ] - }, - #{ - dirs => ["."], - filter => "Makefile", - ruleset => makefiles - }, - #{ - dirs => ["."], - filter => "elvis.config", - ruleset => elvis_config - }, - #{ - dirs => ["."], - filter => "rebar.config", - rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace} - ] - } - ]} - ]} -]. diff --git a/rebar.config b/rebar.config index ece80a6..287c274 100644 --- a/rebar.config +++ b/rebar.config @@ -1,6 +1,5 @@ %% Common project erlang options. {erl_opts, [ - % mandatory debug_info, warnings_as_errors, @@ -27,31 +26,11 @@ %% Common project dependencies. {deps, [ - {genlib, - {git, "https://github.com/rbkmoney/genlib.git", - {branch, "master"} - } - }, - {bouncer_proto, - {git, "git@github.com:rbkmoney/bouncer-proto.git", - {branch, "master"} - } - }, - {org_management_proto, - {git, "git@github.com:rbkmoney/org-management-proto.git", - {branch, "master"} - } - }, - {scoper, - {git, "git@github.com:rbkmoney/scoper.git", - {branch, master} - } - }, - {woody, - {git, "git@github.com:rbkmoney/woody_erlang.git", - {branch, master} - } - } + {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, + {bouncer_proto, {git, "https://github.com/rbkmoney/bouncer-proto", {branch, "master"}}}, + {org_management_proto, {git, "git@github.com:rbkmoney/org-management-proto.git", {branch, "master"}}}, + {scoper, {git, "https://github.com/rbkmoney/scoper", {branch, master}}}, + {woody, {git, "https://github.com/rbkmoney/woody_erlang", {branch, master}}} ]}. %% XRef checks @@ -61,6 +40,7 @@ deprecated_functions_calls, deprecated_functions ]}. + % at will % {xref_warnings, true}. @@ -79,10 +59,41 @@ ]}. {plugins, [ - {erlfmt, "0.8.0"} + {erlfmt, "0.11.0"}, + {rebar3_lint, "0.3.2"} ]}. {erlfmt, [ {print_width, 120}, {files, "{src,include,test}/*.{hrl,erl}"} ]}. + +{elvis, [ + #{ + dirs => ["src"], + filter => "*.erl", + ruleset => erl_files, + rules => [ + {elvis_text_style, line_length, #{limit => 120}} + ] + }, + #{ + dirs => ["test"], + filter => "*.erl", + ruleset => erl_files, + rules => [ + {elvis_text_style, line_length, #{limit => 120}}, + % Tests are usually more comprehensible when a bit more verbose. + {elvis_style, dont_repeat_yourself, #{min_complexity => 20}} + ] + }, + #{ + dirs => ["."], + filter => "rebar.config", + rules => [ + {elvis_text_style, line_length, #{limit => 120}}, + {elvis_text_style, no_tabs}, + {elvis_text_style, no_trailing_whitespace} + ] + } +]}. diff --git a/rebar.lock b/rebar.lock index 4342c74..c1c848c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,11 +1,11 @@ -{"1.1.0", +{"1.2.0", [{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},3}, {<<"bouncer_proto">>, - {git,"git@github.com:rbkmoney/bouncer-proto.git", + {git,"https://github.com/rbkmoney/bouncer-proto.git", {ref,"7ac88717904c6bab73096198b308380e006ed42c"}}, 0}, - {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, + {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},1}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.3">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, @@ -21,52 +21,67 @@ {ref,"7637d915c4c769f7f45c99f8688b17922e801027"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.2">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.0">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", {ref,"8f11d17eeb6eb74096da7363a9df272fd3099718"}}, 1}, - {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, + {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"org_management_proto">>, {git,"git@github.com:rbkmoney/org-management-proto.git", {ref,"06c5c8430e445cb7874e54358e457cbb5697fc32"}}, 0}, - {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"scoper">>, - {git,"git@github.com:rbkmoney/scoper.git", + {git,"https://github.com/rbkmoney/scoper.git", {ref,"89e1af7422199ea3fa287207300bed1d6e00e5ab"}}, 0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", - {ref,"7f379ad5e389e1c96389a8d60bae8117965d6a6d"}}, + {ref,"de159486ef40cec67074afe71882bdc7f7deab72"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"4eda678c985d2894251b91ae43aacf7941846cc9"}}, + {ref,"846a0819d9b6d09d0c31f160e33a78dbad2067b4"}}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, - {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"d106ef66bdd9ac303e05e1d5cddde85e0fa5f36a"}}, + {git,"https://github.com/rbkmoney/woody_erlang.git", + {ref,"f2cd30883d58eb1c3ab2172556956f757bc27e23"}}, 0}]}. [ {pkg_hash,[ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, - {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, - {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, + {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, + {<<"certifi">>, <<"70BDD7E7188C804F3A30EE0E7C99655BC35D8AC41C23E12325F36AB449B70651">>}, {<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>}, {<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"07E33C794F8F8964EE86CEBEC1A8ED88DB5070E52E904B8F12209773C1036085">>}, - {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, + {<<"hackney">>, <<"717EA195FD2F898D9FE9F1CE0AFCC2621A41ECFE137FAE57E7FE6E9484B9AA99">>}, + {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, - {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, + {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, - {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, - {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} + {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, + {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, +{pkg_hash_ext,[ + {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, + {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, + {<<"certifi">>, <<"ED516ACB3929B101208A9D700062D520F3953DA3B6B918D866106FFA980E1C10">>}, + {<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>}, + {<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>}, + {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, + {<<"hackney">>, <<"64C22225F1EA8855F584720C0E5B3CD14095703AF1C9FBC845BA042811DC671C">>}, + {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, + {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, + {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, + {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, + {<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>}, + {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>}, + {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} ]. diff --git a/src/bouncer_client_woody.erl b/src/bouncer_client_woody.erl index 98b9e7f..0247d9d 100644 --- a/src/bouncer_client_woody.erl +++ b/src/bouncer_client_woody.erl @@ -7,36 +7,47 @@ -define(DEFAULT_DEADLINE, 5000). %% --type service_name() :: atom(). --spec call(service_name(), woody:func(), woody:args(), woody_context:ctx()) -> woody:result(). +-type service_name() :: + org_management + | bouncer. + +-type client_config() :: #{ + url := woody:url(), + timeout => non_neg_integer(), + retries => #{woody:func() | '_' => genlib_retry:strategy()} +}. + +-type context() :: woody_context:ctx(). + +-spec call(service_name(), woody:func(), woody:args(), context()) -> woody:result(). call(ServiceName, Function, Args, Context) -> EventHandler = scoper_woody_event_handler, call(ServiceName, Function, Args, Context, EventHandler). --spec call(service_name(), woody:func(), woody:args(), woody_context:ctx(), woody:ev_handler()) -> woody:result(). +-spec call(service_name(), woody:func(), woody:args(), context(), woody:ev_handler()) -> woody:result(). call(ServiceName, Function, Args, Context0, EventHandler) -> - Deadline = get_service_deadline(ServiceName), - Context1 = set_deadline(Deadline, Context0), - Retry = get_service_retry(ServiceName, Function), - call(ServiceName, Function, Args, Context1, EventHandler, Retry). - -call(ServiceName, Function, Args, Context, EventHandler, Retry) -> - Url = get_service_client_url(ServiceName), + Config = get_service_client_config(ServiceName), + Deadline = get_service_deadline(Config), + Context1 = set_deadline(Deadline, set_default_deadline(Context0)), + Retry = get_service_retry(Function, Config), Service = get_service_modname(ServiceName), Request = {Service, Function, Args}, + Opts = #{ + url => get_service_client_url(Config), + event_handler => EventHandler + }, + call_retry(Request, Context1, Opts, Retry). + +call_retry(Request, Context, Opts, Retry) -> try - woody_client:call( - Request, - #{url => Url, event_handler => EventHandler}, - Context - ) + woody_client:call(Request, Opts, Context) catch error:{woody_error, {_Source, Class, _Details}} = Error when Class =:= resource_unavailable orelse Class =:= result_unknown -> NextRetry = apply_retry_strategy(Retry, Error, Context), - call(ServiceName, Function, Args, Context, EventHandler, NextRetry) + call_retry(Request, Context, Opts, NextRetry) end. apply_retry_strategy(Retry, Error, Context) -> @@ -60,12 +71,13 @@ apply_retry_step({wait, Timeout, Retry}, Deadline0, Error) -> Retry end. +-spec get_service_client_config(service_name()) -> client_config(). get_service_client_config(ServiceName) -> ServiceClients = genlib_app:env(bouncer_client, service_clients, #{}), maps:get(ServiceName, ServiceClients, #{}). -get_service_client_url(ServiceName) -> - maps:get(url, get_service_client_config(ServiceName), undefined). +get_service_client_url(ClientConfig) -> + maps:get(url, ClientConfig). -spec get_service_modname(service_name()) -> woody:service(). get_service_modname(org_management) -> @@ -73,22 +85,27 @@ get_service_modname(org_management) -> get_service_modname(bouncer) -> {bouncer_decisions_thrift, 'Arbiter'}. --spec get_service_deadline(service_name()) -> undefined | woody_deadline:deadline(). -get_service_deadline(ServiceName) -> - ServiceClient = get_service_client_config(ServiceName), - Timeout = maps:get(deadline, ServiceClient, ?DEFAULT_DEADLINE), - woody_deadline:from_timeout(Timeout). +-spec get_service_deadline(client_config()) -> undefined | woody_deadline:deadline(). +get_service_deadline(ClientConfig) -> + case maps:get(timeout, ClientConfig, undefined) of + undefined -> undefined; + Timeout -> woody_deadline:from_timeout(Timeout) + end. +set_deadline(undefined, Context) -> + Context; set_deadline(Deadline, Context) -> + woody_context:set_deadline(Deadline, Context). + +set_default_deadline(Context) -> case woody_context:get_deadline(Context) of undefined -> - woody_context:set_deadline(Deadline, Context); + woody_context:set_deadline(woody_deadline:from_timeout(?DEFAULT_DEADLINE), Context); _AlreadySet -> Context end. -get_service_retry(ServiceName, Function) -> - ServiceRetries = genlib_app:env(?APP, service_retries, #{}), - FunctionReties = maps:get(ServiceName, ServiceRetries, #{}), - DefaultRetry = maps:get('_', FunctionReties, finish), - maps:get(Function, FunctionReties, DefaultRetry). +get_service_retry(Function, ClientConfig) -> + FunctionRetries = maps:get(retries, ClientConfig, #{}), + DefaultRetry = maps:get('_', FunctionRetries, finish), + maps:get(Function, FunctionRetries, DefaultRetry). diff --git a/src/bouncer_context_helpers.erl b/src/bouncer_context_helpers.erl index eaa80c1..7bb2d3f 100644 --- a/src/bouncer_context_helpers.erl +++ b/src/bouncer_context_helpers.erl @@ -167,7 +167,7 @@ get_user_orgs_fragment(UserID, WoodyContext) -> case bouncer_client_woody:call(ServiceName, 'GetUserContext', {UserID}, WoodyContext) of {ok, EncodedFragment} -> {ok, {encoded_fragment, convert_fragment(ServiceName, EncodedFragment)}}; - {exception, {orgmgmt_UserNotFound}} -> + {exception, {'orgmgmt_UserNotFound'}} -> {error, {user, notfound}} end. @@ -180,7 +180,7 @@ get_user_orgs_fragment(UserID, WoodyContext) -> convert_fragment( org_management, - {bctx_ContextFragment, Type = v1_thrift_binary, Content} + {'bctx_ContextFragment', Type = v1_thrift_binary, Content} ) when is_binary(Content) -> #bctx_ContextFragment{ type = Type, diff --git a/test/bouncer_client_SUITE.erl b/test/bouncer_client_SUITE.erl index 4334b0a..0233c40 100644 --- a/test/bouncer_client_SUITE.erl +++ b/test/bouncer_client_SUITE.erl @@ -15,6 +15,8 @@ -export([end_per_testcase/2]). -export([empty_judge/1]). +-export([follows_retries/1]). +-export([follows_timeout/1]). -export([validate_user_fragment/1]). -export([validate_env_fragment/1]). -export([validate_auth_fragment/1]). @@ -40,6 +42,8 @@ groups() -> [ {default, [], [ empty_judge, + follows_retries, + follows_timeout, validate_user_fragment, validate_env_fragment, validate_auth_fragment, @@ -52,6 +56,11 @@ groups() -> -type config() :: [{atom(), any()}]. +-define(TIMEOUT, 1000). +-define(RETRY_NUM, 3). +-define(RETRY_TIMEOUT, 100). +-define(RETRY_STRATEGY, {linear, ?RETRY_NUM, ?RETRY_TIMEOUT}). + -spec init_per_suite(config()) -> config(). init_per_suite(Config) -> Apps = @@ -59,8 +68,9 @@ init_per_suite(Config) -> {service_clients, #{ bouncer => #{ url => <<"http://bouncer:8022/">>, + timeout => ?TIMEOUT, retries => #{ - 'Judge' => {linear, 3, 1000}, + 'Judge' => ?RETRY_STRATEGY, '_' => finish } }, @@ -72,7 +82,7 @@ init_per_suite(Config) -> % default value is 'finish' % for more info look genlib_retry :: strategy() % https://github.com/rbkmoney/genlib/blob/master/src/genlib_retry.erl#L19 - 'GetUserContext' => {linear, 3, 1000}, + 'GetUserContext' => {linear, 3, 100}, '_' => finish } } @@ -111,6 +121,41 @@ empty_judge(C) -> WoodyContext = woody_context:new(), allowed = bouncer_client:judge(?RULESET_ID, #{}, WoodyContext). +-spec follows_retries(config()) -> _. +follows_retries(_C) -> + WoodyContext = woody_context:new(), + T0 = erlang:monotonic_time(millisecond), + ?assertError( + {woody_error, {internal, resource_unavailable, _}}, + bouncer_client:judge(?RULESET_ID, #{}, WoodyContext) + ), + T1 = erlang:monotonic_time(millisecond), + ?assert(T1 - T0 > ?RETRY_NUM * ?RETRY_TIMEOUT), + ?assert(T1 - T0 < ?RETRY_NUM * ?RETRY_TIMEOUT * 1.5). + +-spec follows_timeout(config()) -> _. +follows_timeout(C) -> + mock_services( + [ + {bouncer, fun('Judge', _) -> + ok = timer:sleep(5000), + {ok, #bdcs_Judgement{ + resolution = {allowed, #bdcs_ResolutionAllowed{}} + }} + end} + ], + C + ), + WoodyContext = woody_context:new(), + T0 = erlang:monotonic_time(millisecond), + ?assertError( + {woody_error, {external, result_unknown, _}}, + bouncer_client:judge(?RULESET_ID, #{}, WoodyContext) + ), + T1 = erlang:monotonic_time(millisecond), + ?assert(T1 - T0 > ?TIMEOUT), + ?assert(T1 - T0 < ?TIMEOUT * 1.5). + -spec validate_user_fragment(config()) -> _. validate_user_fragment(C) -> UserID = <<"somebody">>, @@ -368,7 +413,7 @@ validate_remote_user_fragment(C) -> id = UserID } }), - {ok, {bctx_ContextFragment, v1_thrift_binary, Content}} + {ok, {'bctx_ContextFragment', v1_thrift_binary, Content}} end}, {bouncer, fun('Judge', {_RulesetID, Fragments}) -> case get_user_id(Fragments) of @@ -475,21 +520,19 @@ set_cfg(Service, Url) -> mock_services_(Services, Config) when is_list(Config) -> mock_services_(Services, ?config(test_sup, Config)); mock_services_(Services, SupPid) when is_pid(SupPid) -> - Name = lists:map(fun get_service_name/1, Services), - - Port = get_random_port(), + ServerRef = {dummy, lists:map(fun get_service_name/1, Services)}, {ok, IP} = inet:parse_address(?HOST_IP), ChildSpec = woody_server:child_spec( - {dummy, Name}, - #{ + ServerRef, + Options = #{ ip => IP, - port => Port, + port => 0, event_handler => scoper_woody_event_handler, handlers => lists:map(fun mock_service_handler/1, Services) } ), {ok, _} = supervisor:start_child(SupPid, ChildSpec), - + {IP, Port} = woody_server:get_addr(ServerRef, Options), lists:foldl( fun(Service, Acc) -> ServiceName = get_service_name(Service), @@ -517,10 +560,6 @@ get_service_modname(org_management) -> get_service_modname(bouncer) -> {bouncer_decisions_thrift, 'Arbiter'}. -% TODO not so failproof, ideally we need to bind socket first and then give to a ranch listener -get_random_port() -> - rand:uniform(32768) + 32767. - make_url(ServiceName, Port) -> iolist_to_binary(["http://", ?HOST_NAME, ":", integer_to_list(Port), make_path(ServiceName)]).