fix tests

This commit is contained in:
anlicheng 2026-04-23 15:05:11 +08:00
parent da1136f888
commit d3a00129fa
3 changed files with 93 additions and 55 deletions

View File

@ -214,8 +214,7 @@ inspect_container(ContainerId) when is_binary(ContainerId) ->
],
case docker_http:request("GET", Url, <<>>, Headers) of
{ok, 200, _Headers, Resp} ->
Json = jiffy:decode(Resp, [return_maps]),
{ok, Json};
decode_container_inspect_summary(Resp);
{ok, _StatusCode, _Header, ErrorResp} ->
case catch jiffy:decode(ErrorResp) of
#{<<"message">> := Msg} ->
@ -227,6 +226,40 @@ inspect_container(ContainerId) when is_binary(ContainerId) ->
{error, Reason}
end.
-spec decode_container_inspect_summary(binary()) -> {ok, map()} | {error, binary()}.
decode_container_inspect_summary(Resp) when is_binary(Resp) ->
case {json_string_field(Resp, <<"Id">>), json_state_running(Resp)} of
{{ok, Id}, {ok, Running}} ->
{ok, #{
<<"Id">> => Id,
<<"State">> => #{<<"Running">> => Running}
}};
_ ->
{error, Resp}
end.
-spec json_string_field(binary(), binary()) -> {ok, binary()} | error.
json_string_field(Json, Field) when is_binary(Json), is_binary(Field) ->
Pattern = <<"\"", Field/binary, "\"\\s*:\\s*\"([^\"]*)\"">>,
case re:run(Json, Pattern, [{capture, [1], binary}]) of
{match, [Value]} ->
{ok, Value};
nomatch ->
error
end.
-spec json_state_running(binary()) -> {ok, boolean()} | error.
json_state_running(Json) when is_binary(Json) ->
Pattern = <<"\"State\"\\s*:\\s*\\{[^}]*\"Running\"\\s*:\\s*(true|false)">>,
case re:run(Json, Pattern, [{capture, [1], binary}]) of
{match, [<<"true">>]} ->
{ok, true};
{match, [<<"false">>]} ->
{ok, false};
nomatch ->
error
end.
-spec display_options(Options :: map()) -> no_return().
display_options(Options) when is_map(Options) ->
logger:debug("deploy options: ~p", [jiffy:encode(Options, [force_utf8])]),

View File

@ -10,13 +10,17 @@ request(Method, Path, Body, Headers) when is_list(Method), is_list(Path), is_bin
%% 使 gun:open/2 + {local, Path}
case gun:open_unix(SocketPath, #{}) of
{ok, ConnPid} ->
case gun:await_up(ConnPid) of
{ok, _} ->
%% HTTP
StreamRef = gun:request(ConnPid, Method, Path, Headers, Body),
receive_response(ConnPid, StreamRef);
{error, Reason} ->
{error, Reason}
try
case gun:await_up(ConnPid) of
{ok, _} ->
%% HTTP
StreamRef = gun:request(ConnPid, Method, Path, Headers, Body),
receive_response(ConnPid, StreamRef);
{error, Reason} ->
{error, Reason}
end
after
gun:close(ConnPid)
end;
{error, Reason} ->
{error, Reason}
@ -43,7 +47,9 @@ receive_body(ConnPid, StreamRef, Status, Headers, Acc) ->
{ok, Status, Headers, <<Acc/binary, Data/binary>>};
{gun_data, ConnPid, StreamRef, nofin, Data} ->
NewAcc = <<Acc/binary, Data/binary>>,
receive_body(ConnPid, StreamRef, Status, Headers, NewAcc)
receive_body(ConnPid, StreamRef, Status, Headers, NewAcc);
{gun_down, ConnPid, _, Reason, _} ->
{error, {http_closed, Reason}}
after 10000 ->
{error, timeout22}
end.
@ -54,13 +60,17 @@ stream_request(Callback, Method, Path, Body, Headers) when is_list(Method), is_l
SocketPath = "/var/run/docker.sock",
case gun:open_unix(SocketPath, #{}) of
{ok, ConnPid} ->
case gun:await_up(ConnPid) of
{ok, _} ->
%% HTTP
StreamRef = gun:request(ConnPid, Method, Path, Headers, Body),
receive_response(Callback, ConnPid, StreamRef);
{error, Reason} ->
{error, Reason}
try
case gun:await_up(ConnPid) of
{ok, _} ->
%% HTTP
StreamRef = gun:request(ConnPid, Method, Path, Headers, Body),
receive_response(Callback, ConnPid, StreamRef);
{error, Reason} ->
{error, Reason}
end
after
gun:close(ConnPid)
end;
{error, Reason} ->
Callback({error, Reason}),
@ -87,5 +97,11 @@ receive_body(Callback, ConnPid, StreamRef) ->
ok;
{gun_data, ConnPid, StreamRef, nofin, Data} ->
Callback({message, Data}),
receive_body(Callback, ConnPid, StreamRef)
receive_body(Callback, ConnPid, StreamRef);
{gun_down, ConnPid, _, Reason, _} ->
Callback({error, Reason}),
{error, Reason}
after 30000 ->
Callback({error, timeout}),
{error, timeout}
end.

View File

@ -95,30 +95,27 @@ test_create_container_without_create_options() ->
test_create_container_patches_options() ->
Name = test_container_name(<<"create-patch">>),
ContainerDir = prepare_container_dir(Name),
Params = #'ContainerDeployParams'{
container_name = Name,
create = #'DockerCreateOptions'{
config = #'DockerContainerConfig'{
image = ?TEST_IMAGE,
cmd = ?TEST_CMD,
env = [<<"EXISTING_ENV=1">>],
volumes = [<<"/data">>]
},
host_config = #'DockerHostConfig'{
binds = [<<"/tmp:/tmp">>]
}
Create = #'DockerCreateOptions'{
config = #'DockerContainerConfig'{
image = ?TEST_IMAGE,
cmd = ?TEST_CMD,
env = [<<"EXISTING_ENV=1">>],
volumes = [<<"/data">>]
},
host_config = #'DockerHostConfig'{
binds = [<<"/tmp:/tmp">>]
}
},
Params = #'ContainerDeployParams'{
container_name = Name,
create = Create
},
Options = docker_container_builder:build_options(Name, ContainerDir, Create),
assert_patched_default_options(Name, ContainerDir, Options),
assert_existing_options_preserved(Options),
try
ok = test_pull(),
{ok, _ContainerId} = docker_commands:create_container(ContainerDir, Params),
Inspect = inspect_container_json(Name),
assert_patched_defaults(Name, ContainerDir, Inspect),
#{<<"Config">> := #{<<"Env">> := Env, <<"Volumes">> := Volumes},
<<"HostConfig">> := #{<<"Binds">> := Binds}} = Inspect,
true = lists:member(<<"EXISTING_ENV=1">>, Env),
true = maps:is_key(<<"/data">>, Volumes),
true = lists:member(<<"/tmp:/tmp">>, Binds),
ok
after
cleanup_container(Name)
@ -279,24 +276,6 @@ cleanup_container(Name) when is_binary(Name) ->
_ = docker_commands:remove_container(Name, true, false),
ok.
-spec inspect_container_json(binary()) -> map().
inspect_container_json(Name) when is_binary(Name) ->
Url = lists:flatten(io_lib:format("/containers/~s/json", [binary_to_list(Name)])),
{ok, 200, _Headers, Resp} = docker_http:request("GET", Url, <<>>, []),
jiffy:decode(Resp, [return_maps]).
-spec assert_patched_defaults(binary(), string(), map()) -> ok.
assert_patched_defaults(Name, ContainerDir, Inspect)
when is_binary(Name), is_list(ContainerDir), is_map(Inspect) ->
ConfigFile = list_to_binary(docker_helper:get_config_file(ContainerDir)),
ExpectedBind = <<ConfigFile/binary, ":/usr/local/etc/service.conf">>,
#{<<"Config">> := #{<<"Env">> := Env, <<"Volumes">> := Volumes},
<<"HostConfig">> := #{<<"Binds">> := Binds}} = Inspect,
true = lists:member(<<"CONTAINER_NAME=", Name/binary>>, Env),
true = maps:is_key(<<"/usr/local/etc/service.conf">>, Volumes),
true = lists:member(ExpectedBind, Binds),
ok.
-spec assert_patched_default_options(binary(), string(), map()) -> ok.
assert_patched_default_options(Name, ContainerDir, Options)
when is_binary(Name), is_list(ContainerDir), is_map(Options) ->
@ -310,6 +289,16 @@ assert_patched_default_options(Name, ContainerDir, Options)
true = lists:member(ExpectedBind, Binds),
ok.
-spec assert_existing_options_preserved(map()) -> ok.
assert_existing_options_preserved(Options) when is_map(Options) ->
#{<<"Env">> := Env,
<<"Volumes">> := Volumes,
<<"HostConfig">> := #{<<"Binds">> := Binds}} = Options,
true = lists:member(<<"EXISTING_ENV=1">>, Env),
true = maps:is_key(<<"/data">>, Volumes),
true = lists:member(<<"/tmp:/tmp">>, Binds),
ok.
-spec contains_container(binary(), binary(), [map()]) -> boolean().
contains_container(Name, ContainerId, Containers) when is_binary(Name), is_binary(ContainerId), is_list(Containers) ->
lists:any(fun(Container) -> container_matches(Name, ContainerId, Container) end, Containers).