Add a simple test
This commit is contained in:
parent
654a8cd926
commit
61ad821d43
|
|
@ -1,5 +1,6 @@
|
|||
RELEASABLE:=true
|
||||
DEPS:=rabbitmq-management
|
||||
WITH_BROKER_TEST_COMMANDS:=eunit:test(rabbit_tracing_test,[verbose])
|
||||
|
||||
CONSTRUCT_APP_PREREQS:=$(shell find $(PACKAGE_DIR)/priv -type f)
|
||||
define construct_app_commands
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
%% The contents of this file are subject to the Mozilla Public License
|
||||
%% Version 1.1 (the "License"); you may not use this file except in
|
||||
%% compliance with the License. You may obtain a copy of the License
|
||||
%% at http://www.mozilla.org/MPL/
|
||||
%%
|
||||
%% Software distributed under the License is distributed on an "AS IS"
|
||||
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%% the License for the specific language governing rights and
|
||||
%% limitations under the License.
|
||||
%%
|
||||
%% The Original Code is RabbitMQ.
|
||||
%%
|
||||
%% The Initial Developer of the Original Code is VMware, Inc.
|
||||
%% Copyright (c) 2007-2011 VMware, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_tracing_test).
|
||||
|
||||
-define(LOG_DIR, "/tmp/rabbitmq-tracing/").
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("amqp_client/include/amqp_client.hrl").
|
||||
-include_lib("rabbitmq_management/include/rabbit_mgmt_test.hrl").
|
||||
|
||||
-import(rabbit_misc, [pget/2]).
|
||||
|
||||
tracing_test() ->
|
||||
{ok, Files} = file:list_dir(?LOG_DIR),
|
||||
[ok = file:delete(?LOG_DIR ++ F) || F <- Files],
|
||||
|
||||
[] = http_get("/traces/%2f/"),
|
||||
[] = http_get("/trace-files/"),
|
||||
|
||||
Args = [{format, <<"json">>},
|
||||
{pattern, <<"#">>}],
|
||||
http_put("/traces/%2f/test", Args, ?NO_CONTENT),
|
||||
assert_list([[{name, <<"test">>},
|
||||
{format, <<"json">>},
|
||||
{pattern, <<"#">>}]], http_get("/traces/%2f/")),
|
||||
assert_item([{name, <<"test">>},
|
||||
{format, <<"json">>},
|
||||
{pattern, <<"#">>}], http_get("/traces/%2f/test")),
|
||||
|
||||
{ok, Conn} = amqp_connection:start(#amqp_params_network{}),
|
||||
{ok, Ch} = amqp_connection:open_channel(Conn),
|
||||
amqp_channel:cast(Ch, #'basic.publish'{ exchange = <<"amq.topic">>,
|
||||
routing_key = <<"key">> },
|
||||
#amqp_msg{props = #'P_basic'{},
|
||||
payload = <<"Hello world">>}),
|
||||
|
||||
amqp_channel:close(Ch),
|
||||
amqp_connection:close(Conn),
|
||||
|
||||
timer:sleep(100),
|
||||
|
||||
http_delete("/traces/%2f/test", ?NO_CONTENT),
|
||||
[] = http_get("/traces/%2f/"),
|
||||
assert_list([[{name, <<"test.log">>}]], http_get("/trace-files/")),
|
||||
%% This is a bit cheeky as the log is actually one JSON doc per
|
||||
%% line and we assume here it's only one line
|
||||
assert_item([{type, <<"published">>},
|
||||
{exchange, <<"amq.topic">>},
|
||||
{routing_keys, [<<"key">>]},
|
||||
{payload, base64:encode(<<"Hello world">>)}],
|
||||
http_get("/trace-files/test.log")),
|
||||
http_delete("/trace-files/test.log", ?NO_CONTENT),
|
||||
ok.
|
||||
|
||||
%%---------------------------------------------------------------------------
|
||||
%% Below is copypasta from rabbit_mgmt_test_http, it's not obvious how
|
||||
%% to share that given the build system.
|
||||
|
||||
http_get(Path) ->
|
||||
http_get(Path, ?OK).
|
||||
|
||||
http_get(Path, CodeExp) ->
|
||||
http_get(Path, "guest", "guest", CodeExp).
|
||||
|
||||
http_get(Path, User, Pass, CodeExp) ->
|
||||
{ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} =
|
||||
req(get, Path, [auth_header(User, Pass)]),
|
||||
assert_code(CodeExp, CodeAct, "GET", Path, ResBody),
|
||||
decode(CodeExp, Headers, ResBody).
|
||||
|
||||
http_put(Path, List, CodeExp) ->
|
||||
http_put_raw(Path, format_for_upload(List), CodeExp).
|
||||
|
||||
http_put(Path, List, User, Pass, CodeExp) ->
|
||||
http_put_raw(Path, format_for_upload(List), User, Pass, CodeExp).
|
||||
|
||||
http_post(Path, List, CodeExp) ->
|
||||
http_post_raw(Path, format_for_upload(List), CodeExp).
|
||||
|
||||
http_post(Path, List, User, Pass, CodeExp) ->
|
||||
http_post_raw(Path, format_for_upload(List), User, Pass, CodeExp).
|
||||
|
||||
format_for_upload(List) ->
|
||||
iolist_to_binary(mochijson2:encode({struct, List})).
|
||||
|
||||
http_put_raw(Path, Body, CodeExp) ->
|
||||
http_upload_raw(put, Path, Body, "guest", "guest", CodeExp).
|
||||
|
||||
http_put_raw(Path, Body, User, Pass, CodeExp) ->
|
||||
http_upload_raw(put, Path, Body, User, Pass, CodeExp).
|
||||
|
||||
http_post_raw(Path, Body, CodeExp) ->
|
||||
http_upload_raw(post, Path, Body, "guest", "guest", CodeExp).
|
||||
|
||||
http_post_raw(Path, Body, User, Pass, CodeExp) ->
|
||||
http_upload_raw(post, Path, Body, User, Pass, CodeExp).
|
||||
|
||||
http_upload_raw(Type, Path, Body, User, Pass, CodeExp) ->
|
||||
{ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} =
|
||||
req(Type, Path, [auth_header(User, Pass)], Body),
|
||||
assert_code(CodeExp, CodeAct, Type, Path, ResBody),
|
||||
decode(CodeExp, Headers, ResBody).
|
||||
|
||||
http_delete(Path, CodeExp) ->
|
||||
http_delete(Path, "guest", "guest", CodeExp).
|
||||
|
||||
http_delete(Path, User, Pass, CodeExp) ->
|
||||
{ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} =
|
||||
req(delete, Path, [auth_header(User, Pass)]),
|
||||
assert_code(CodeExp, CodeAct, "DELETE", Path, ResBody),
|
||||
decode(CodeExp, Headers, ResBody).
|
||||
|
||||
assert_code(CodeExp, CodeAct, Type, Path, Body) ->
|
||||
case CodeExp of
|
||||
CodeAct -> ok;
|
||||
_ -> throw({expected, CodeExp, got, CodeAct, type, Type,
|
||||
path, Path, body, Body})
|
||||
end.
|
||||
|
||||
req(Type, Path, Headers) ->
|
||||
httpc:request(Type, {?PREFIX ++ Path, Headers}, ?HTTPC_OPTS, []).
|
||||
|
||||
req(Type, Path, Headers, Body) ->
|
||||
httpc:request(Type, {?PREFIX ++ Path, Headers, "application/json", Body},
|
||||
?HTTPC_OPTS, []).
|
||||
|
||||
decode(?OK, _Headers, ResBody) -> cleanup(mochijson2:decode(ResBody));
|
||||
decode(_, Headers, _ResBody) -> Headers.
|
||||
|
||||
cleanup(L) when is_list(L) ->
|
||||
[cleanup(I) || I <- L];
|
||||
cleanup({struct, I}) ->
|
||||
cleanup(I);
|
||||
cleanup({K, V}) when is_binary(K) ->
|
||||
{list_to_atom(binary_to_list(K)), cleanup(V)};
|
||||
cleanup(I) ->
|
||||
I.
|
||||
|
||||
auth_header(Username, Password) ->
|
||||
{"Authorization",
|
||||
"Basic " ++ binary_to_list(base64:encode(Username ++ ":" ++ Password))}.
|
||||
|
||||
%%---------------------------------------------------------------------------
|
||||
|
||||
assert_list(Exp, Act) ->
|
||||
case length(Exp) == length(Act) of
|
||||
true -> ok;
|
||||
false -> throw({expected, Exp, actual, Act})
|
||||
end,
|
||||
[case length(lists:filter(fun(ActI) -> test_item(ExpI, ActI) end, Act)) of
|
||||
1 -> ok;
|
||||
N -> throw({found, N, ExpI, in, Act})
|
||||
end || ExpI <- Exp].
|
||||
|
||||
assert_item(Exp, Act) ->
|
||||
case test_item0(Exp, Act) of
|
||||
[] -> ok;
|
||||
Or -> throw(Or)
|
||||
end.
|
||||
|
||||
test_item(Exp, Act) ->
|
||||
case test_item0(Exp, Act) of
|
||||
[] -> true;
|
||||
_ -> false
|
||||
end.
|
||||
|
||||
test_item0(Exp, Act) ->
|
||||
[{did_not_find, ExpI, in, Act} || ExpI <- Exp,
|
||||
not lists:member(ExpI, Act)].
|
||||
Loading…
Reference in New Issue