diff options
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | lib/ct_formatter.ex | 130 | ||||
-rw-r--r-- | src/acl.erl | 11 | ||||
-rw-r--r-- | src/mod_admin_extra.erl | 7 | ||||
-rw-r--r-- | test/acl_test.exs | 11 | ||||
-rw-r--r-- | test/elixir_SUITE.erl | 9 | ||||
-rw-r--r-- | test/mod_http_api_test.exs | 2 |
7 files changed, 160 insertions, 11 deletions
diff --git a/.travis.yml b/.travis.yml index ce5aafe5..0dd13892 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,6 +59,7 @@ after_script: - find logs -name suite.log -exec cat '{}' ';' after_failure: + - find logs -name exunit.log -exec cat '{}' ';' # Try checking Riak database logs - tail -n 100000 /var/log/riak/*.log - find logs -name ejabberd.log -exec cat '{}' ';' diff --git a/lib/ct_formatter.ex b/lib/ct_formatter.ex new file mode 100644 index 00000000..47c487ac --- /dev/null +++ b/lib/ct_formatter.ex @@ -0,0 +1,130 @@ +defmodule ExUnit.CTFormatter do + @moduledoc false + + use GenEvent + + import ExUnit.Formatter, only: [format_time: 2, format_filters: 2, format_test_failure: 5, + format_test_case_failure: 5] + + def init(opts) do + file = File.open! "exunit.log", [:append] + # We do not print filter in log file as exclusion of test with tag + # pending: true is always done + config = %{ + file: file, + seed: opts[:seed], + trace: opts[:trace], + colors: Keyword.put_new(opts[:colors], :enabled, false), + width: 80, + tests_counter: 0, + failures_counter: 0, + skipped_counter: 0, + invalids_counter: 0 + } + {:ok, config} + end + + def handle_event({:suite_started, _opts}, config) do + {:ok, config} + end + + def handle_event({:suite_finished, run_us, load_us}, config) do + print_suite(config, run_us, load_us) + File.close config[:file] + :remove_handler + end + + def handle_event({:test_started, %ExUnit.Test{} = test}, config) do + if config.tests_counter == 0, do: IO.binwrite config[:file], "== Running #{test.case} ==\n\n" + {:ok, config} + end + + def handle_event({:test_finished, %ExUnit.Test{state: nil} = _test}, config) do + IO.binwrite config[:file], "." + {:ok, %{config | tests_counter: config.tests_counter + 1}} + end + + def handle_event({:test_finished, %ExUnit.Test{state: {:skip, _}} = _test}, config) do + {:ok, %{config | tests_counter: config.tests_counter + 1, + skipped_counter: config.skipped_counter + 1}} + end + + def handle_event({:test_finished, %ExUnit.Test{state: {:invalid, _}} = _test}, config) do + IO.binwrite config[:file], "?" + {:ok, %{config | tests_counter: config.tests_counter + 1, + invalids_counter: config.invalids_counter + 1}} + end + + def handle_event({:test_finished, %ExUnit.Test{state: {:failed, failures}} = test}, config) do + formatted = format_test_failure(test, failures, config.failures_counter + 1, + config.width, &formatter(&1, &2, config)) + print_failure(formatted, config) + print_logs(test.logs) + + {:ok, %{config | tests_counter: config.tests_counter + 1, + failures_counter: config.failures_counter + 1}} + end + + def handle_event({:case_started, %ExUnit.TestCase{}}, config) do + {:ok, config} + end + + def handle_event({:case_finished, %ExUnit.TestCase{state: nil}}, config) do + {:ok, config} + end + + def handle_event({:case_finished, %ExUnit.TestCase{state: {:failed, failures}} = test_case}, config) do + formatted = format_test_case_failure(test_case, failures, config.failures_counter + 1, + config.width, &formatter(&1, &2, config)) + print_failure(formatted, config) + {:ok, %{config | failures_counter: config.failures_counter + 1}} + end + + ## Printing + + defp print_suite(config, run_us, load_us) do + IO.binwrite config[:file], "\n\n" + IO.binwrite config[:file], format_time(run_us, load_us) + IO.binwrite config[:file], "\n\n" + + # singular/plural + test_pl = pluralize(config.tests_counter, "test", "tests") + failure_pl = pluralize(config.failures_counter, "failure", "failures") + + message = + "#{config.tests_counter} #{test_pl}, #{config.failures_counter} #{failure_pl}" + |> if_true(config.skipped_counter > 0, & &1 <> ", #{config.skipped_counter} skipped") + |> if_true(config.invalids_counter > 0, & &1 <> ", #{config.invalids_counter} invalid") + + cond do + config.failures_counter > 0 -> IO.binwrite config[:file], message + config.invalids_counter > 0 -> IO.binwrite config[:file], message + true -> IO.binwrite config[:file], message + end + + IO.binwrite config[:file], "\nRandomized with seed #{config.seed}\n\n\n\n" + end + + defp if_true(value, false, _fun), do: value + defp if_true(value, true, fun), do: fun.(value) + + defp print_failure(formatted, config) do + IO.binwrite config[:file], "\n" + IO.binwrite config[:file], formatted + IO.binwrite config[:file], "\n" + end + + defp formatter(_, msg, _config), + do: msg + + defp pluralize(1, singular, _plural), do: singular + defp pluralize(_, _singular, plural), do: plural + + defp print_logs(""), do: nil + + defp print_logs(output) do + indent = "\n " + output = String.replace(output, "\n", indent) + IO.puts([" The following output was logged:", indent | output]) + end +end diff --git a/src/acl.erl b/src/acl.erl index 0c1071d1..58b80b6a 100644 --- a/src/acl.erl +++ b/src/acl.erl @@ -34,7 +34,7 @@ match_rule/3, match_acl/3, transform_options/1, opt_type/1]). --export([add_access/3]). +-export([add_access/3, clear/0]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -45,6 +45,7 @@ rules = [] :: [access_rule()]}). -type regexp() :: binary(). +-type iprange() :: {inet:ip_address(), integer()} | binary(). -type glob() :: binary(). -type access_name() :: atom(). -type access_rule() :: {atom(), any()}. @@ -63,7 +64,7 @@ {user_glob, {glob(), host()} | glob()} | {server_glob, glob()} | {resource_glob, glob()} | - {ip, {inet:ip_address(), integer()}} | + {ip, iprange()} | {node_glob, {glob(), glob()}}. -type acl() :: #acl{aclname :: aclname(), @@ -206,6 +207,12 @@ load_from_config() -> end, AccessRules) end, Hosts). +%% Delete all previous set ACLs and Access rules +clear() -> + mnesia:clear_table(acl), + mnesia:clear_table(access), + ok. + b(S) -> iolist_to_binary(S). diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index feff8af8..cb794787 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -600,9 +600,9 @@ check_password_hash(User, Host, PasswordHash, HashMethod) -> {A, _} when is_tuple(A) -> scrammed; {_, <<"md5">>} -> get_md5(AccountPass); {_, <<"sha">>} -> get_sha(AccountPass); - {_, _Method} -> + {_, Method} -> ?ERROR_MSG("check_password_hash called " - "with hash method", [_Method]), + "with hash method: ~p", [Method]), undefined end, case AccountPassHash of @@ -1309,8 +1309,7 @@ srg_get_info(Group, Host) -> Os when is_list(Os) -> Os; error -> [] end, - [{jlib:atom_to_binary(Title), - io_lib:format("~p", [btl(Value)])} || {Title, Value} <- Opts]. + [{jlib:atom_to_binary(Title), btl(Value)} || {Title, Value} <- Opts]. btl([]) -> []; btl([B|L]) -> [btl(B)|btl(L)]; diff --git a/test/acl_test.exs b/test/acl_test.exs index 0aca9bce..663d3bb6 100644 --- a/test/acl_test.exs +++ b/test/acl_test.exs @@ -30,6 +30,10 @@ defmodule ACLTest do :ok = :acl.start end + setup do + :acl.clear + end + test "simple user access rule matches" do :acl.add(:global, :basic_acl_1, {:user, "test1"}) :acl.add_access(:global, :basic_rule_1, [{:basic_acl_1, :allow}]) @@ -38,5 +42,12 @@ defmodule ACLTest do # We match on user part only for local domain. As an implicit rule remote domain are not matched assert :acl.match_rule(:global, :basic_rule_1, :jid.from_string("test1@otherdomain")) == :deny assert :acl.match_rule(:global, :basic_rule_1, :jid.from_string("test11@domain1")) == :deny + + :acl.add(:global, :basic_acl_2, {:user, {"test2", "domain1"}}) + :acl.add_access(:global, :basic_rule_2, [{:basic_acl_2, :allow}]) + assert :acl.match_rule(:global, :basic_rule_2, :jid.from_string("test2@domain1")) == :allow + assert :acl.match_rule(:global, :basic_rule_2, :jid.from_string("test2@domain2")) == :deny + assert :acl.match_rule(:global, :basic_rule_2, :jid.from_string("test2@otherdomain")) == :deny end + end diff --git a/test/elixir_SUITE.erl b/test/elixir_SUITE.erl index 2d8c3c52..48cc94f8 100644 --- a/test/elixir_SUITE.erl +++ b/test/elixir_SUITE.erl @@ -30,7 +30,7 @@ all() -> case is_elixir_available() of true -> Dir = test_dir(), - filelib:fold_files(Dir, ".*\.exs$", false, + filelib:fold_files(Dir, ".*test\.exs$", false, fun(Filename, Acc) -> [list_to_atom(filename:basename(Filename)) | Acc] end, []); false -> @@ -68,7 +68,7 @@ undefined_function(Module, Func, Args) -> run_elixir_test(Func) -> %% Elixir tests can be tagged as follow to be ignored (place before test start) %% @tag pending: true - 'Elixir.ExUnit':start([{exclude, [{pending, true}]}]), + 'Elixir.ExUnit':start([{exclude, [{pending, true}]}, {formatters, ['Elixir.ExUnit.CLIFormatter', 'Elixir.ExUnit.CTFormatter']}]), filelib:fold_files(test_dir(), ".*mock\.exs\$", true, fun (File, N) -> @@ -84,8 +84,9 @@ run_elixir_test(Func) -> %% Zero failures ok; {ok, Failures} -> - ct:print("Elixir tests failed: ~.10B~nSee logs for details", [Failures]), - ct:fail(elixir_test_failure) + ct:print("Tests failed in module '~s': ~.10B failures.~nSee logs for details", [Func, Failures]), + ct:fail(elixir_test_failure), + error end. test_dir() -> diff --git a/test/mod_http_api_test.exs b/test/mod_http_api_test.exs index 55faea83..9432ae47 100644 --- a/test/mod_http_api_test.exs +++ b/test/mod_http_api_test.exs @@ -29,7 +29,7 @@ defmodule ModHttpApiTest do setup_all do :ok = :mnesia.start - :ok = :stringprep.start + :stringprep.start :ok = :ejabberd_config.start(["localhost"], []) :ok = :ejabberd_commands.init |