test(api): CT на портах 18080/18445 вне docker-dev [skip ci]
This commit is contained in:
@@ -98,11 +98,15 @@ eunit-verbose: ## Запустить EUnit тесты с подробным вы
|
|||||||
@echo "Запуск EUnit тестов (verbose)..."
|
@echo "Запуск EUnit тестов (verbose)..."
|
||||||
@$(REBAR3) eunit --sname $(SNAME)_test --verbose
|
@$(REBAR3) eunit --sname $(SNAME)_test --verbose
|
||||||
|
|
||||||
test-api: ## Запустить Common Test для API
|
test-api: ## Запустить Common Test для API (порты 18080/18081/18445/18446 — не docker 8080/8445)
|
||||||
@echo "Cleaning old data..."
|
@echo "Cleaning old data..."
|
||||||
@rm -rf logs/test/ct/ct_run.*
|
@rm -rf logs/test/ct/ct_run.*
|
||||||
|
@rm -rf data/Mnesia.ct data/Mnesia.ct.* data/mnesia_ct Mnesia.eventhub_api_test@* 2>/dev/null || true
|
||||||
@bash scripts/fix-rebar-unit-symlink.sh
|
@bash scripts/fix-rebar-unit-symlink.sh
|
||||||
@$(REBAR3) ct --sname $(SNAME)_api_test #-v
|
@HTTP_PORT=18080 WS_PORT=18081 ADMIN_HTTP_PORT=18445 ADMIN_WS_PORT=18446 \
|
||||||
|
API_HOST=http://localhost:18080 ADMIN_API_HOST=http://localhost:18445 \
|
||||||
|
WS_HOST=ws://localhost:18081 ADMIN_WS_HOST=ws://localhost:18446 \
|
||||||
|
$(REBAR3) ct --sname $(SNAME)_api_test #-v
|
||||||
|
|
||||||
wsl-ext4-dirs: ## WSL: каталоги logs/data на ext4 (рекомендуется)
|
wsl-ext4-dirs: ## WSL: каталоги logs/data на ext4 (рекомендуется)
|
||||||
@bash scripts/wsl-ext4-dirs.sh
|
@bash scripts/wsl-ext4-dirs.sh
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
%% Common Test / local API suite — ports that don't clash with docker compose (8080/8445).
|
||||||
|
[
|
||||||
|
{eventhub, [
|
||||||
|
{http_port, 18080},
|
||||||
|
{ws_port, 18081},
|
||||||
|
{admin_http_port, 18445},
|
||||||
|
{admin_ws_port, 18446},
|
||||||
|
{swagger_http_port, 18447},
|
||||||
|
{jwt_secret, <<"ct_jwt_secret_change_me">>},
|
||||||
|
{admin_jwt_secret, <<"ct_admin_jwt_secret_change_me">>}
|
||||||
|
]},
|
||||||
|
{kernel, [
|
||||||
|
{logger_level, warning},
|
||||||
|
{logger, [
|
||||||
|
{handler, default, logger_std_h,
|
||||||
|
#{formatter => {logger_formatter, #{template => [time, " ", level, ": ", msg, "\n"]}}}
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
].
|
||||||
@@ -41,9 +41,9 @@ run_ct() {
|
|||||||
rebar3 ct --suite=api_admins_SUITE --case="${case_name}" --verbose
|
rebar3 ct --suite=api_admins_SUITE --case="${case_name}" --verbose
|
||||||
}
|
}
|
||||||
|
|
||||||
if port_busy 8080 || port_busy 8445; then
|
if port_busy 18080 || port_busy 18445; then
|
||||||
echo "=== ct: SKIP (порты 8080/8445 заняты — остановите eventhub и повторите) ==="
|
echo "=== ct: SKIP (порты 18080/18445 заняты — остановите CT-сервер и повторите) ==="
|
||||||
ss -tln 2>/dev/null | grep -E ':8080|:8445' || true
|
ss -tln 2>/dev/null | grep -E ':18080|:18445' || true
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
get_base_url/0,
|
get_base_url/0,
|
||||||
get_base_ws_url/0,
|
get_base_ws_url/0,
|
||||||
get_admin_ws_url/0,
|
get_admin_ws_url/0,
|
||||||
|
ensure_local_app_ports/0,
|
||||||
get_admin_token/0,
|
get_admin_token/0,
|
||||||
get_superadmin_token/0,
|
get_superadmin_token/0,
|
||||||
get_moderator_token/0,
|
get_moderator_token/0,
|
||||||
@@ -57,32 +58,68 @@ ct_mode() ->
|
|||||||
|
|
||||||
-spec get_base_url() -> string().
|
-spec get_base_url() -> string().
|
||||||
get_base_url() ->
|
get_base_url() ->
|
||||||
case ct_mode() of
|
os:getenv("API_HOST", "http://localhost:18080").
|
||||||
"remote" -> os:getenv("API_HOST", "http://localhost:8080");
|
|
||||||
_ -> "http://localhost:8080"
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec get_admin_url() -> string().
|
-spec get_admin_url() -> string().
|
||||||
get_admin_url() ->
|
get_admin_url() ->
|
||||||
case ct_mode() of
|
os:getenv("ADMIN_API_HOST", "http://localhost:18445").
|
||||||
"remote" -> os:getenv("ADMIN_API_HOST", "http://localhost:8445");
|
|
||||||
_ -> "http://localhost:8445"
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec get_base_ws_url() -> string().
|
-spec get_base_ws_url() -> string().
|
||||||
get_base_ws_url() ->
|
get_base_ws_url() ->
|
||||||
case ct_mode() of
|
os:getenv("WS_HOST", "ws://localhost:18081").
|
||||||
"remote" -> os:getenv("WS_HOST", "ws://localhost:8081");
|
|
||||||
_ -> "ws://localhost:8081"
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec get_admin_ws_url() -> string().
|
-spec get_admin_ws_url() -> string().
|
||||||
get_admin_ws_url() ->
|
get_admin_ws_url() ->
|
||||||
case ct_mode() of
|
os:getenv("ADMIN_WS_HOST", "ws://localhost:18446").
|
||||||
"remote" -> os:getenv("ADMIN_WS_HOST", "ws://localhost:8446");
|
|
||||||
_ -> "ws://localhost:8446"
|
%% @doc Порты CT-local (не docker 8080/8445). Вызывать до ensure_all_started(eventhub).
|
||||||
|
-spec ensure_local_app_ports() -> ok.
|
||||||
|
ensure_local_app_ports() ->
|
||||||
|
_ = application:load(eventhub),
|
||||||
|
_ = application:load(mnesia),
|
||||||
|
application:set_env(eventhub, http_port, env_port("HTTP_PORT", 18080)),
|
||||||
|
application:set_env(eventhub, ws_port, env_port("WS_PORT", 18081)),
|
||||||
|
application:set_env(eventhub, admin_http_port, env_port("ADMIN_HTTP_PORT", 18445)),
|
||||||
|
application:set_env(eventhub, admin_ws_port, env_port("ADMIN_WS_PORT", 18446)),
|
||||||
|
application:set_env(eventhub, swagger_http_port, env_port("SWAGGER_HTTP_PORT", 18447)),
|
||||||
|
ensure_fresh_mnesia_dir(),
|
||||||
|
clear_cached_admin_tokens(),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
env_port(Name, Default) ->
|
||||||
|
case os:getenv(Name) of
|
||||||
|
false -> Default;
|
||||||
|
"" -> Default;
|
||||||
|
Val -> list_to_integer(Val)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
ensure_fresh_mnesia_dir() ->
|
||||||
|
%% Absolute path under WSL data (CT cwd is logs/test/ct/ct_run.* — relative data/ is missing).
|
||||||
|
Dir = filename:join([
|
||||||
|
os:getenv("HOME", "/home/alexc"),
|
||||||
|
"eventhub-wsl-data", "data", "mnesia_ct"
|
||||||
|
]),
|
||||||
|
_ = application:load(mnesia),
|
||||||
|
application:set_env(mnesia, dir, Dir),
|
||||||
|
_ = (catch mnesia:stop()),
|
||||||
|
ok = filelib:ensure_dir(filename:join(Dir, ".keep")),
|
||||||
|
_ = file:del_dir_r(Dir),
|
||||||
|
_ = (catch mnesia:delete_schema([node()])),
|
||||||
|
case mnesia:create_schema([node()]) of
|
||||||
|
ok ->
|
||||||
|
ok;
|
||||||
|
{error, {already_exists, _}} ->
|
||||||
|
ok;
|
||||||
|
{error, Reason} ->
|
||||||
|
error({ct_mnesia_create_schema_failed, Reason, Dir, node()})
|
||||||
|
end.
|
||||||
|
|
||||||
|
clear_cached_admin_tokens() ->
|
||||||
|
lists:foreach(
|
||||||
|
fun(Role) -> _ = persistent_term:erase({?MODULE, admin_token, Role}) end,
|
||||||
|
[admin, superadmin, moderator, support]
|
||||||
|
).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Учётные данные администраторов (из переменных окружения)
|
%%% Учётные данные администраторов (из переменных окружения)
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ init_per_suite(Config) ->
|
|||||||
ct:pal("Local mode: application already running"),
|
ct:pal("Local mode: application already running"),
|
||||||
[{started_by_us, false} | Config];
|
[{started_by_us, false} | Config];
|
||||||
false ->
|
false ->
|
||||||
ct:pal("Local mode: starting application..."),
|
ct:pal("Local mode: starting application on CT ports (18080/18445)..."),
|
||||||
|
ok = api_test_runner:ensure_local_app_ports(),
|
||||||
{ok, _} = application:ensure_all_started(eventhub),
|
{ok, _} = application:ensure_all_started(eventhub),
|
||||||
timer:sleep(1000),
|
timer:sleep(1000),
|
||||||
[{started_by_us, true} | Config]
|
[{started_by_us, true} | Config]
|
||||||
@@ -142,7 +143,7 @@ ct_mode() ->
|
|||||||
%% @private Ожидание доступности удалённого API.
|
%% @private Ожидание доступности удалённого API.
|
||||||
-spec wait_for_remote() -> ok.
|
-spec wait_for_remote() -> ok.
|
||||||
wait_for_remote() ->
|
wait_for_remote() ->
|
||||||
URL = os:getenv("ADMIN_API_HOST", "http://localhost:8445") ++ "/admin/health",
|
URL = api_test_runner:get_admin_url() ++ "/admin/health",
|
||||||
ct:pal("Waiting for remote API: ~s", [URL]),
|
ct:pal("Waiting for remote API: ~s", [URL]),
|
||||||
wait_for_health(URL, 30).
|
wait_for_health(URL, 30).
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ init_per_suite(Config) ->
|
|||||||
ct:pal("Local mode: application already running"),
|
ct:pal("Local mode: application already running"),
|
||||||
[{started_by_us, false} | Config];
|
[{started_by_us, false} | Config];
|
||||||
false ->
|
false ->
|
||||||
ct:pal("Local mode: starting application..."),
|
ct:pal("Local mode: starting application on CT ports (18080/18445)..."),
|
||||||
|
ok = api_test_runner:ensure_local_app_ports(),
|
||||||
{ok, _} = application:ensure_all_started(eventhub),
|
{ok, _} = application:ensure_all_started(eventhub),
|
||||||
timer:sleep(1000),
|
timer:sleep(1000),
|
||||||
[{started_by_us, true} | Config]
|
[{started_by_us, true} | Config]
|
||||||
@@ -166,7 +167,7 @@ ct_mode() ->
|
|||||||
%% @private Ожидание доступности удалённого API.
|
%% @private Ожидание доступности удалённого API.
|
||||||
-spec wait_for_remote() -> ok.
|
-spec wait_for_remote() -> ok.
|
||||||
wait_for_remote() ->
|
wait_for_remote() ->
|
||||||
URL = os:getenv("API_HOST", "http://localhost:8080") ++ "/health",
|
URL = api_test_runner:get_base_url() ++ "/health",
|
||||||
ct:pal("Waiting for remote API: ~s", [URL]),
|
ct:pal("Waiting for remote API: ~s", [URL]),
|
||||||
wait_for_health(URL, 30).
|
wait_for_health(URL, 30).
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user