mirror of
https://github.com/valitydev/bouncer-client-erlang.git
synced 2024-11-06 00:25:18 +00:00
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
This commit is contained in:
parent
36cb53a7d4
commit
2c083eb112
5
Makefile
5
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
|
||||
|
55
elvis.config
55
elvis.config
@ -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}
|
||||
]
|
||||
}
|
||||
]}
|
||||
]}
|
||||
].
|
65
rebar.config
65
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}
|
||||
]
|
||||
}
|
||||
]}.
|
||||
|
57
rebar.lock
57
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">>}]}
|
||||
].
|
||||
|
@ -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).
|
||||
|
@ -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,
|
||||
|
@ -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)]).
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user