From e9ece4c817c7ce31ef74034bbd44917d03e3a8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=9F=D1=80=D0=BE?= =?UTF-8?q?=D1=85=D0=BE=D1=80=D0=BE=D0=B2?= Date: Mon, 4 Mar 2019 11:15:07 +0100 Subject: [PATCH] Split mtp_test_middle_server to 2 modules - one with just middle-server implementation - one with proxy config mock and multi-server DC setup --- test/mtp_test_datacenter.erl | 105 +++++++++++++++++++++++++++++++ test/mtp_test_middle_server.erl | 108 +------------------------------- test/single_dc_SUITE.erl | 4 +- 3 files changed, 110 insertions(+), 107 deletions(-) create mode 100644 test/mtp_test_datacenter.erl diff --git a/test/mtp_test_datacenter.erl b/test/mtp_test_datacenter.erl new file mode 100644 index 0000000..41754bf --- /dev/null +++ b/test/mtp_test_datacenter.erl @@ -0,0 +1,105 @@ +%% Fake telegram "datacenters" +%% Mock to emulate core.telegram.org and set of telegram +%% "middle-proxies" for each datacenter ID +-module(mtp_test_datacenter). + +-export([start_dc/0, + start_dc/3, + stop_dc/1, + start_config_server/5, + stop_config_server/1]). +-export([dc_list_to_config/1]). +-export([do/1]). + +-include_lib("inets/include/httpd.hrl"). + +-define(SECRET_PATH, "/getProxySecret"). +-define(CONFIG_PATH, "/getProxyConfig"). + + +start_dc() -> + Secret = crypto:strong_rand_bytes(128), + DcConf = [{1, {127, 0, 0, 1}, 8888}], + {ok, _Cfg} = start_dc(Secret, DcConf, #{}). + +start_dc(Secret, DcConf, Acc) -> + Cfg = dc_list_to_config(DcConf), + {ok, Acc1} = start_config_server({127, 0, 0, 1}, 3333, Secret, Cfg, Acc), + Ids = + [begin + Id = {?MODULE, DcId}, + {ok, _Pid} = mtp_test_middle_server:start(Id, #{port => Port, ip => Ip, secret => Secret}), + Id + end || {DcId, Ip, Port} <- DcConf], + {ok, Acc1#{srv_ids => Ids}}. + +stop_dc(#{srv_ids := Ids} = Acc) -> + {ok, Acc1} = stop_config_server(Acc), + ok = lists:foreach(fun mtp_test_middle_server:stop/1, Ids), + {ok, maps:without([srv_ids], Acc1)}. + +%% +%% Inets HTTPD to use as a mock for https://core.telegram.org +%% + +%% Api +start_config_server(Ip, Port, Secret, DcConfig, Acc) -> + application:load(mtproto_proxy), + Netloc = lists:flatten(io_lib:format("http://~s:~w", [inet:ntoa(Ip), Port])), + Env = [{proxy_secret_url, + Netloc ++ ?SECRET_PATH}, + {proxy_config_url, + Netloc ++ ?CONFIG_PATH}, + {external_ip, "127.0.0.1"}, + {ip_lookup_services, undefined}], + OldEnv = + [begin + %% OldV is undefined | {ok, V} + OldV = application:get_env(mtproto_proxy, K), + case V of + undefined -> application:unset_env(mtproto_proxy, K); + _ -> + application:set_env(mtproto_proxy, K, V) + end, + {K, OldV} + end || {K, V} <- Env], + RootDir = code:lib_dir(mtproto_proxy, test), + {ok, Pid} = + inets:start(httpd, + [{port, Port}, + {server_name, "mtp_config"}, + {server_root, "/tmp"}, + {document_root, RootDir}, + + {bind_address, Ip}, + {modules, [?MODULE]}, + {mtp_secret, Secret}, + {mtp_dc_conf, DcConfig}]), + {ok, Acc#{env => OldEnv, + httpd_pid => Pid}}. + +stop_config_server(#{env := Env, httpd_pid := Pid} = Acc) -> + [case V of + undefined -> + application:unset_env(mtproto_proxy, K); + {ok, Val} -> + application:set_env(mtproto_proxy, K, Val) + end || {K, V} <- Env], + inets:stop(httpd, Pid), + {ok, maps:without([env, httpd_pid], Acc)}. + +dc_list_to_config(List) -> + << + <<(list_to_binary( + io_lib:format("proxy_for ~w ~s:~w;~n", [DcId, inet:ntoa(Ip), Port]) + ))/binary>> + || {DcId, Ip, Port} <- List + >>. + +%% Inets callback +do(#mod{request_uri = ?CONFIG_PATH, config_db = Db}) -> + [{_, DcConf}] = ets:lookup(Db, mtp_dc_conf), + {break, [{response, {200, binary_to_list(DcConf)}}]}; +do(#mod{request_uri = ?SECRET_PATH, config_db = Db}) -> + [{_, Secret}] = ets:lookup(Db, mtp_secret), + {break, [{response, {200, binary_to_list(Secret)}}]}. diff --git a/test/mtp_test_middle_server.erl b/test/mtp_test_middle_server.erl index 08d80be..50bd4a9 100644 --- a/test/mtp_test_middle_server.erl +++ b/test/mtp_test_middle_server.erl @@ -1,19 +1,12 @@ -%% Fake telegram server +%% Fake telegram "middle-proxy" server -module(mtp_test_middle_server). -behaviour(ranch_protocol). -behaviour(gen_statem). --export([start_dc/0, - start_dc/3, - stop_dc/1, - start/2, - stop/1, - start_config_server/5, - stop_config_server/1]). --export([dc_list_to_config/1]). +-export([start/2, + stop/1]). -export([start_link/4, ranch_init/1]). --export([do/1]). -export([init/1, callback_mode/0, %% handle_call/3, @@ -26,7 +19,6 @@ wait_handshake/3, on_tunnel/3]). --include_lib("inets/include/httpd.hrl"). -record(hs_state, {sock, transport, @@ -47,102 +39,8 @@ -define(RPC_HANDSHAKE, 245,238,130,118). -define(RPC_FLAGS, 0, 0, 0, 0). --define(SECRET_PATH, "/getProxySecret"). --define(CONFIG_PATH, "/getProxyConfig"). - %% -type state_name() :: wait_nonce | wait_handshake | on_tunnel. -start_dc() -> - Secret = crypto:strong_rand_bytes(128), - DcConf = [{1, {127, 0, 0, 1}, 8888}], - {ok, _Cfg} = start_dc(Secret, DcConf, #{}). - -start_dc(Secret, DcConf, Acc) -> - Cfg = mtp_test_middle_server:dc_list_to_config(DcConf), - {ok, Acc1} = start_config_server({127, 0, 0, 1}, 3333, Secret, Cfg, Acc), - Ids = - [begin - Id = {?MODULE, DcId}, - {ok, _Pid} = start(Id, #{port => Port, ip => Ip, secret => Secret}), - Id - end || {DcId, Ip, Port} <- DcConf], - {ok, Acc1#{srv_ids => Ids}}. - -stop_dc(#{srv_ids := Ids} = Acc) -> - {ok, Acc1} = stop_config_server(Acc), - ok = lists:foreach(fun stop/1, Ids), - {ok, maps:without([srv_ids], Acc1)}. - -%% -%% Inets HTTPD to use as a mock for https://core.telegram.org -%% - -%% Api -start_config_server(Ip, Port, Secret, DcConfig, Acc) -> - application:load(mtproto_proxy), - Netloc = lists:flatten(io_lib:format("http://~s:~w", [inet:ntoa(Ip), Port])), - Env = [{proxy_secret_url, - Netloc ++ ?SECRET_PATH}, - {proxy_config_url, - Netloc ++ ?CONFIG_PATH}, - {external_ip, "127.0.0.1"}, - {ip_lookup_services, undefined}], - OldEnv = - [begin - %% OldV is undefined | {ok, V} - OldV = application:get_env(mtproto_proxy, K), - case V of - undefined -> application:unset_env(mtproto_proxy, K); - _ -> - application:set_env(mtproto_proxy, K, V) - end, - {K, OldV} - end || {K, V} <- Env], - RootDir = code:lib_dir(mtproto_proxy, test), - {ok, Pid} = - inets:start(httpd, - [{port, Port}, - {server_name, "mtp_config"}, - {server_root, "/tmp"}, - {document_root, RootDir}, - - {bind_address, Ip}, - {modules, [?MODULE]}, - {mtp_secret, Secret}, - {mtp_dc_conf, DcConfig}]), - {ok, Acc#{env => OldEnv, - httpd_pid => Pid}}. - -stop_config_server(#{env := Env, httpd_pid := Pid} = Acc) -> - [case V of - undefined -> - application:unset_env(mtproto_proxy, K); - {ok, Val} -> - application:set_env(mtproto_proxy, K, Val) - end || {K, V} <- Env], - inets:stop(httpd, Pid), - {ok, maps:without([env, httpd_pid], Acc)}. - -dc_list_to_config(List) -> - << - <<(list_to_binary( - io_lib:format("proxy_for ~w ~s:~w;~n", [DcId, inet:ntoa(Ip), Port]) - ))/binary>> - || {DcId, Ip, Port} <- List - >>. - -%% Inets callback -do(#mod{request_uri = ?CONFIG_PATH, config_db = Db}) -> - [{_, DcConf}] = ets:lookup(Db, mtp_dc_conf), - {break, [{response, {200, binary_to_list(DcConf)}}]}; -do(#mod{request_uri = ?SECRET_PATH, config_db = Db}) -> - [{_, Secret}] = ets:lookup(Db, mtp_secret), - {break, [{response, {200, binary_to_list(Secret)}}]}. - -%% -%% Mtproto telegram server -%% - %% Api start(Id, Opts) -> {ok, _} = application:ensure_all_started(ranch), diff --git a/test/single_dc_SUITE.erl b/test/single_dc_SUITE.erl index 548c285..3f1e37a 100644 --- a/test/single_dc_SUITE.erl +++ b/test/single_dc_SUITE.erl @@ -100,7 +100,7 @@ setup_single(Name, Offset, Cfg) -> tag => <<"dcbe8f1493fa4cd9ab300891c0b5b326">>}], application:load(mtproto_proxy), Cfg1 = set_env([{ports, Listeners}], Cfg), - {ok, DcCfg} = mtp_test_middle_server:start_dc(PubKey, DcConf, #{}), + {ok, DcCfg} = mtp_test_datacenter:start_dc(PubKey, DcConf, #{}), application:load(mtproto_proxy), {ok, _} = application:ensure_all_started(mtproto_proxy), [{dc_id, DcId}, @@ -113,7 +113,7 @@ stop_single(Cfg) -> DcCfg = ?config(dc_conf, Cfg), MetricPid = ?config(metric, Cfg), ok = application:stop(mtproto_proxy), - {ok, _} = mtp_test_middle_server:stop_dc(DcCfg), + {ok, _} = mtp_test_datacenter:stop_dc(DcCfg), gen_server:stop(MetricPid), Cfg.