From fc9ec1d326579b592fd111ac28811fdbf47e00f7 Mon Sep 17 00:00:00 2001 From: Sergey Prokhorov Date: Sun, 5 Apr 2026 01:41:01 +0200 Subject: [PATCH] =?UTF-8?q?Upgrade=20ranch=201.7.0=20=E2=86=92=202.2.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ranch 2.x breaking changes addressed: - Protocol callback changed from start_link/4 (Ref, Socket, Transport, Opts) to start_link/3 (Ref, Transport, Opts); socket obtained via ranch:handshake/1 - ranch:info/0 now returns #{Name => #{...}} instead of [{Name, [proplists]}]; updated mtp_listeners/0, running_ports/0, and config_change_case test Also update AGENTS.md with CT failure debugging workflow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- AGENTS.md | 19 +++++++++++++++++++ rebar.config | 2 +- rebar.lock | 6 +++--- src/mtp_handler.erl | 4 ++-- src/mtproto_proxy_app.erl | 16 +++++++--------- test/mtp_test_middle_server.erl | 4 ++-- test/single_dc_SUITE.erl | 4 ++-- 7 files changed, 36 insertions(+), 19 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 22ff451..fbe14f1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -79,6 +79,25 @@ Individual steps: Always run `make test` before committing. Fix all xref warnings and dialyzer errors — they are treated as errors. +### Debugging CT failures + +When `rebar3 ct` (or `make test`) reports failures, **do not rely on the terminal output** — it is truncated and shows only the last error. Instead, go straight to the HTML logs: + +``` +_build/test/logs/ct_run./lib.mtproto_proxy.logs/run./ +``` + +Key files: +- `suite.log` — machine-readable summary; `=case` lines show test order, `=result failed` shows which failed +- `single_dc_suite..html` — full log for one test case (strip HTML tags to read: `sed 's/<[^>]*>//g'`) +- `suite.log.html` / `index.html` — human-readable in a browser + +Workflow: +1. Run `make test` — note how many pass/fail +2. Check `suite.log` for `=case` ordering and `=result failed` to identify the failing test +3. Read that test's `.html` log for the full stacktrace and system reports +4. Fix, then re-run `make test`. If tests still fail spuriously, try `rm -rf _build/test && make test` to clear stale test artifacts (removing only `_build/test` is faster than a full clean build). + ## Code Style - Language: **Erlang**. Follow standard Erlang OTP conventions. diff --git a/rebar.config b/rebar.config index 1f6a7ae..f16d976 100644 --- a/rebar.config +++ b/rebar.config @@ -1,7 +1,7 @@ % -*- mode: erlang -*- {erl_opts, [debug_info]}. -{deps, [{ranch, "1.7.0"}, +{deps, [{ranch, "2.2.0"}, {erlang_psq, {git, "https://github.com/seriyps/psq", {branch, "master"}}} ]}. {project_plugins, [rebar3_proper, diff --git a/rebar.lock b/rebar.lock index b8ea235..7c8b0bb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,10 +3,10 @@ {git,"https://github.com/seriyps/psq", {ref,"46329ccb60f27d7d4c3f3643441ccef6c5f9c89c"}}, 0}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.0">>},0}]}. + {<<"ranch">>,{pkg,<<"ranch">>,<<"2.2.0">>},0}]}. [ {pkg_hash,[ - {<<"ranch">>, <<"9583F47160CA62AF7F8D5DB11454068EAA32B56EEADF984D4F46E61A076DF5F2">>}]}, + {<<"ranch">>, <<"25528F82BC8D7C6152C57666CA99EC716510FE0925CB188172F41CE93117B1B0">>}]}, {pkg_hash_ext,[ - {<<"ranch">>, <<"59F7501C3A56125B2FC5684C3048FAC9D043C0BF4D173941B12CA927949AF189">>}]} + {<<"ranch">>, <<"FA0B99A1780C80218A4197A59EA8D3BDAE32FBFF7E88527D7D8A4787EFF4F8E7">>}]} ]. diff --git a/src/mtp_handler.erl b/src/mtp_handler.erl index 2a88e34..12d4d1a 100644 --- a/src/mtp_handler.erl +++ b/src/mtp_handler.erl @@ -10,7 +10,7 @@ -behaviour(ranch_protocol). %% API --export([start_link/4, send/2]). +-export([start_link/3, send/2]). -export([hex/1, unhex/1]). -export([keys_str/0]). @@ -65,7 +65,7 @@ %% APIs -start_link(Ref, _Socket, Transport, Opts) -> +start_link(Ref, Transport, Opts) -> {ok, proc_lib:spawn_link(?MODULE, ranch_init, [{Ref, Transport, Opts}])}. keys_str() -> diff --git a/src/mtproto_proxy_app.erl b/src/mtproto_proxy_app.erl index 0b76b40..5102838 100644 --- a/src/mtproto_proxy_app.erl +++ b/src/mtproto_proxy_app.erl @@ -94,21 +94,19 @@ diff_env(NewEnv, OldEnv) -> %% @doc List of ranch listeners running mtproto_proxy -spec mtp_listeners() -> [tuple()]. mtp_listeners() -> - lists:filter( - fun({_Name, Opts}) -> - proplists:get_value(protocol, Opts) == mtp_handler - end, - ranch:info()). + maps:to_list( + maps:filter( + fun(_Name, #{protocol := Protocol}) -> + Protocol == mtp_handler + end, + ranch:info())). %% @doc Currently running listeners in a form of proxy_port() -spec running_ports() -> [proxy_port()]. running_ports() -> lists:map( - fun({Name, Opts}) -> - #{protocol_options := ProtoOpts, - ip := Ip, - port := Port} = maps:from_list(Opts), + fun({Name, #{protocol_options := ProtoOpts, ip := Ip, port := Port}}) -> [Name, Secret, AdTag] = ProtoOpts, case inet:ntoa(Ip) of {error, einval} -> diff --git a/test/mtp_test_middle_server.erl b/test/mtp_test_middle_server.erl index c30d916..b7985ff 100644 --- a/test/mtp_test_middle_server.erl +++ b/test/mtp_test_middle_server.erl @@ -6,7 +6,7 @@ -export([start/2, stop/1, get_rpc_handler_state/1]). --export([start_link/4, +-export([start_link/3, ranch_init/1]). -export([init/1, callback_mode/0, @@ -63,7 +63,7 @@ get_rpc_handler_state(Pid) -> %% Callbacks -start_link(Ref, _, Transport, Opts) -> +start_link(Ref, Transport, Opts) -> {ok, proc_lib:spawn_link(?MODULE, ranch_init, [{Ref, Transport, Opts}])}. ranch_init({Ref, Transport, Opts}) -> diff --git a/test/single_dc_SUITE.erl b/test/single_dc_SUITE.erl index ebbf692..7dea609 100644 --- a/test/single_dc_SUITE.erl +++ b/test/single_dc_SUITE.erl @@ -317,11 +317,11 @@ config_change_case({post, Cfg}) -> stop_single(Cfg); config_change_case(Cfg) when is_list(Cfg) -> %% test "max_connections" - MaxConnsBefore = [{Listener, proplists:get_value(max_connections, Opts)} + MaxConnsBefore = [{Listener, maps:get(max_connections, Opts)} || {Listener, Opts} <- mtproto_proxy_app:mtp_listeners()], NewMaxConns = 10, ok = mtproto_proxy_app:config_change([{max_connections, NewMaxConns}], [], []), - MaxConnsAfter = [{Listener, proplists:get_value(max_connections, Opts)} + MaxConnsAfter = [{Listener, maps:get(max_connections, Opts)} || {Listener, Opts} <- mtproto_proxy_app:mtp_listeners()], ?assertNotEqual(MaxConnsBefore, MaxConnsAfter), ?assert(lists:all(fun({_Listener, MaxConns}) ->