diff --git a/big_tests/dynamic_domains.spec b/big_tests/dynamic_domains.spec index 3c773749d9..04e2c40651 100644 --- a/big_tests/dynamic_domains.spec +++ b/big_tests/dynamic_domains.spec @@ -79,6 +79,8 @@ {suites, "tests", offline_stub_SUITE}. +{suites, "tests", persistent_cluster_id_SUITE}. + {suites, "tests", presence_SUITE}. {suites, "tests", privacy_SUITE}. @@ -87,6 +89,8 @@ {suites, "tests", race_conditions_SUITE}. +{suites, "tests", rdbms_SUITE}. + {suites, "tests", rest_SUITE}. {suites, "tests", rest_client_SUITE}. diff --git a/big_tests/tests/mongoose_helper.erl b/big_tests/tests/mongoose_helper.erl index e8716ca760..fb9ffda0a4 100644 --- a/big_tests/tests/mongoose_helper.erl +++ b/big_tests/tests/mongoose_helper.erl @@ -49,9 +49,9 @@ -import(distributed_helper, [mim/0, rpc/4]). --spec is_rdbms_enabled(Host :: binary()) -> boolean(). -is_rdbms_enabled(Host) -> - case rpc(mim(), mongoose_rdbms, sql_transaction, [Host, fun erlang:yield/0]) of +-spec is_rdbms_enabled(HostType :: binary()) -> boolean(). +is_rdbms_enabled(HostType) -> + case rpc(mim(), mongoose_rdbms, sql_transaction, [HostType, fun erlang:yield/0]) of {atomic, _} -> true; _ -> false end. diff --git a/big_tests/tests/persistent_cluster_id_SUITE.erl b/big_tests/tests/persistent_cluster_id_SUITE.erl index 9dccf88207..fc8541cef8 100644 --- a/big_tests/tests/persistent_cluster_id_SUITE.erl +++ b/big_tests/tests/persistent_cluster_id_SUITE.erl @@ -25,6 +25,8 @@ -import(distributed_helper, [mim/0, mim2/0]). +-import(domain_helper, [host_type/0]). + all() -> [ {group, mnesia}, @@ -62,12 +64,12 @@ group(_Groupname) -> []. init_per_group(mnesia, Config) -> - case not mongoose_helper:is_rdbms_enabled(domain()) of + case not mongoose_helper:is_rdbms_enabled(host_type()) of true -> Config; false -> {skip, require_no_rdbms} end; init_per_group(_Groupname, Config) -> - case mongoose_helper:is_rdbms_enabled(domain()) of + case mongoose_helper:is_rdbms_enabled(host_type()) of true -> Config; false -> {skip, require_rdbms} end. @@ -142,7 +144,3 @@ cluster_id_is_restored_to_mnesia_from_rdbms_if_mnesia_lost(_Config) -> {ok, SecondID} = mongoose_helper:successful_rpc( Node, mongoose_cluster_id, get_cached_cluster_id, []), ?assertEqual(FirstID, SecondID). - - -domain() -> - ct:get_config({hosts, mim, domain}). diff --git a/big_tests/tests/rdbms_SUITE.erl b/big_tests/tests/rdbms_SUITE.erl index d776400f4f..cc4de8bc7a 100644 --- a/big_tests/tests/rdbms_SUITE.erl +++ b/big_tests/tests/rdbms_SUITE.erl @@ -24,6 +24,8 @@ %% We need assert from it -include("mam_helper.hrl"). +-import(domain_helper, [host_type/0]). + %%-------------------------------------------------------------------- %% Suite configuration %%-------------------------------------------------------------------- @@ -32,8 +34,7 @@ all() -> [{group, rdbms_queries}]. groups() -> - G = [{rdbms_queries, [], rdbms_queries_cases()}], - ct_helper:repeat_all_until_all_ok(G). + [{rdbms_queries, [], rdbms_queries_cases()}]. rdbms_queries_cases() -> [select_one_works_case, @@ -74,7 +75,8 @@ suite() -> %% Init & teardown %%-------------------------------------------------------------------- init_per_suite(Config) -> - case not ct_helper:is_ct_running() orelse mongoose_helper:is_rdbms_enabled(host()) of + case not ct_helper:is_ct_running() + orelse mongoose_helper:is_rdbms_enabled(host_type()) of false -> {skip, rdbms_or_ct_not_running}; true -> escalus:init_per_suite(Config) end. @@ -340,17 +342,14 @@ select_like_prep_case(Config) -> %% Helpers %%-------------------------------------------------------------------- -host() -> - ct:get_config({hosts, mim, domain}). - sql_query(_Config, Query) -> - slow_rpc(mongoose_rdbms, sql_query, [host(), Query]). + slow_rpc(mongoose_rdbms, sql_query, [host_type(), Query]). sql_prepare(_Config, Name, Table, Fields, Query) -> escalus_ejabberd:rpc(mongoose_rdbms, prepare, [Name, Table, Fields, Query]). sql_execute(_Config, Name, Parameters) -> - slow_rpc(mongoose_rdbms, execute, [host(), Name, Parameters]). + slow_rpc(mongoose_rdbms, execute, [host_type(), Name, Parameters]). escape_null(_Config) -> escalus_ejabberd:rpc(mongoose_rdbms, escape_null, []). @@ -359,7 +358,7 @@ escape_string(_Config, Value) -> escalus_ejabberd:rpc(mongoose_rdbms, escape_string, [Value]). escape_binary(_Config, Value) -> - slow_rpc(mongoose_rdbms, escape_binary, [host(), Value]). + slow_rpc(mongoose_rdbms, escape_binary, [host_type(), Value]). escape_boolean(_Config, Value) -> escalus_ejabberd:rpc(mongoose_rdbms, escape_boolean, [Value]). @@ -371,7 +370,7 @@ escape_prepared_like(_Config, Value) -> escalus_ejabberd:rpc(mongoose_rdbms, escape_prepared_like, [Value]). unescape_binary(_Config, Value) -> - escalus_ejabberd:rpc(mongoose_rdbms, unescape_binary, [host(), Value]). + escalus_ejabberd:rpc(mongoose_rdbms, unescape_binary, [host_type(), Value]). use_escaped(_Config, Value) -> escalus_ejabberd:rpc(mongoose_rdbms, use_escaped, [Value]). @@ -817,10 +816,10 @@ drop_common_prefix(Pos, SelValue, Value) -> expected_suffix => safe_binary(100, Value)}. is_odbc() -> - escalus_ejabberd:rpc(mongoose_rdbms, db_engine, [host()]) == odbc. + escalus_ejabberd:rpc(mongoose_rdbms, db_engine, [host_type()]) == odbc. is_pgsql() -> - escalus_ejabberd:rpc(mongoose_rdbms, db_engine, [host()]) == pgsql. + escalus_ejabberd:rpc(mongoose_rdbms, db_engine, [host_type()]) == pgsql. slow_rpc(M, F, A) -> Node = ct:get_config({hosts, mim, node}), diff --git a/src/rdbms/mongoose_rdbms.erl b/src/rdbms/mongoose_rdbms.erl index 454131528f..44b15504e3 100644 --- a/src/rdbms/mongoose_rdbms.erl +++ b/src/rdbms/mongoose_rdbms.erl @@ -171,7 +171,7 @@ %% the retry counter runs out. We just attempt to reduce log pollution. -define(CONNECT_RETRIES, 5). --type server() :: binary() | global. +-type server() :: mongooseim:host_type() | global. -type rdbms_msg() :: {sql_query, _} | {sql_transaction, fun()} | {sql_dirty, fun()} @@ -211,28 +211,28 @@ prepare(Name, Table, Fields, Statement) when is_atom(Name), is_binary(Table) -> prepared(Name) -> ets:member(prepared_statements, Name). --spec execute(Host :: server(), Name :: atom(), Parameters :: [term()]) -> +-spec execute(HostType :: server(), Name :: atom(), Parameters :: [term()]) -> query_result(). -execute(Host, Name, Parameters) when is_atom(Name), is_list(Parameters) -> - sql_call(Host, {sql_execute, Name, Parameters}). +execute(HostType, Name, Parameters) when is_atom(Name), is_list(Parameters) -> + sql_call(HostType, {sql_execute, Name, Parameters}). %% Same as execute/3, but would fail loudly on any error. --spec execute_successfully(Host :: server(), Name :: atom(), Parameters :: [term()]) -> +-spec execute_successfully(HostType :: server(), Name :: atom(), Parameters :: [term()]) -> query_result(). -execute_successfully(Host, Name, Parameters) -> - try execute(Host, Name, Parameters) of +execute_successfully(HostType, Name, Parameters) -> + try execute(HostType, Name, Parameters) of {selected, _} = Result -> Result; {updated, _} = Result -> Result; Other -> - Log = #{what => sql_execute_failed, host => Host,statement_name => Name, + Log = #{what => sql_execute_failed, host => HostType,statement_name => Name, statement_query => query_name_to_string(Name), statement_params => Parameters, reason => Other}, ?LOG_ERROR(Log), error(Log) catch error:Reason:Stacktrace -> - Log = #{what => sql_execute_failed, host => Host, statement_name => Name, + Log = #{what => sql_execute_failed, host => HostType, statement_name => Name, statement_query => query_name_to_string(Name), statement_params => Parameters, reason => Reason, stacktrace => Stacktrace}, @@ -248,28 +248,28 @@ query_name_to_string(Name) -> Statement end. --spec sql_query(Host :: server(), Query :: any()) -> query_result(). -sql_query(Host, Query) -> - sql_call(Host, {sql_query, Query}). +-spec sql_query(HostType :: server(), Query :: any()) -> query_result(). +sql_query(HostType, Query) -> + sql_call(HostType, {sql_query, Query}). %% @doc SQL transaction based on a list of queries -spec sql_transaction(server(), fun() | maybe_improper_list()) -> transaction_result(). -sql_transaction(Host, Queries) when is_list(Queries) -> +sql_transaction(HostType, Queries) when is_list(Queries) -> F = fun() -> lists:map(fun sql_query_t/1, Queries) end, - sql_transaction(Host, F); + sql_transaction(HostType, F); %% SQL transaction, based on a erlang anonymous function (F = fun) -sql_transaction(Host, F) when is_function(F) -> - sql_call(Host, {sql_transaction, F}). +sql_transaction(HostType, F) when is_function(F) -> + sql_call(HostType, {sql_transaction, F}). %% This function allows to specify delay between retries. -spec transaction_with_delayed_retry(server(), fun() | maybe_improper_list(), map()) -> transaction_result(). -transaction_with_delayed_retry(Host, F, Info) -> +transaction_with_delayed_retry(HostType, F, Info) -> Retries = maps:get(retries, Info), Delay = maps:get(delay, Info), - do_transaction_with_delayed_retry(Host, F, Retries, Delay, Info). + do_transaction_with_delayed_retry(HostType, F, Retries, Delay, Info). -do_transaction_with_delayed_retry(Host, F, Retries, Delay, Info) -> - Result = mongoose_rdbms:sql_transaction(Host, F), +do_transaction_with_delayed_retry(HostType, F, Retries, Delay, Info) -> + Result = mongoose_rdbms:sql_transaction(HostType, F), case Result of {atomic, _} -> Result; @@ -278,7 +278,7 @@ do_transaction_with_delayed_retry(Host, F, Retries, Delay, Info) -> text => <<"Transaction aborted. Restart">>, reason => Reason, retries_left => Retries}), timer:sleep(Delay), - do_transaction_with_delayed_retry(Host, F, Retries - 1, Delay, Info); + do_transaction_with_delayed_retry(HostType, F, Retries - 1, Delay, Info); _ -> Err = Info#{what => mam_transaction_failed, text => <<"Transaction failed. Do not restart">>, @@ -288,34 +288,34 @@ do_transaction_with_delayed_retry(Host, F, Retries, Delay, Info) -> end. -spec sql_dirty(server(), fun()) -> any() | no_return(). -sql_dirty(Host, F) when is_function(F) -> - case sql_call(Host, {sql_dirty, F}) of +sql_dirty(HostType, F) when is_function(F) -> + case sql_call(HostType, {sql_dirty, F}) of {ok, Result} -> Result; {error, Error} -> throw(Error) end. %% TODO: Better spec for RPC calls --spec sql_call(Host :: server(), Msg :: rdbms_msg()) -> any(). -sql_call(Host, Msg) -> +-spec sql_call(HostType :: server(), Msg :: rdbms_msg()) -> any(). +sql_call(HostType, Msg) -> case get_state() of - undefined -> sql_call0(Host, Msg); + undefined -> sql_call0(HostType, Msg); State -> {Res, NewState} = nested_op(Msg, State), put_state(NewState), Res end. --spec sql_call0(Host :: server(), Msg :: rdbms_msg()) -> any(). -sql_call0(Host, Msg) -> +-spec sql_call0(HostType :: server(), Msg :: rdbms_msg()) -> any(). +sql_call0(HostType, Msg) -> Timestamp = erlang:monotonic_time(millisecond), - mongoose_wpool:call(rdbms, Host, {sql_cmd, Msg, Timestamp}). + mongoose_wpool:call(rdbms, HostType, {sql_cmd, Msg, Timestamp}). -spec get_db_info(Target :: server() | pid()) -> {ok, DbType :: atom(), DbRef :: term()} | {error, any()}. get_db_info(Pid) when is_pid(Pid) -> wpool_process:call(Pid, get_db_info, 5000); -get_db_info(Host) -> - mongoose_wpool:call(rdbms, Host, get_db_info). +get_db_info(HostType) -> + mongoose_wpool:call(rdbms, HostType, get_db_info). %% This function is intended to be used from inside an sql_transaction: sql_query_t(Query) -> @@ -358,7 +358,7 @@ escape_like_prefix(S) -> {escaped_like, [$', escape_like_internal(S), $%, $']}. -spec escape_binary(server(), binary()) -> escaped_binary(). -escape_binary(_Host, Bin) when is_binary(Bin) -> +escape_binary(_HostType, Bin) when is_binary(Bin) -> {escaped_binary, mongoose_rdbms_backend:escape_binary(Bin)}. %% @doc The same as escape, but returns value including '' @@ -498,7 +498,7 @@ escape_character(C) -> C. -spec unescape_binary(server(), binary()) -> binary(). -unescape_binary(_Host, Bin) when is_binary(Bin) -> +unescape_binary(_HostType, Bin) when is_binary(Bin) -> mongoose_rdbms_backend:unescape_binary(Bin). @@ -761,8 +761,8 @@ abort_on_driver_error({{error, "Failed sending data on socket" ++ _} = Reply, St abort_on_driver_error({Reply, State}) -> {reply, Reply, State}. --spec db_engine(Host :: server()) -> odbc | mysql | pgsql | undefined. -db_engine(_Host) -> +-spec db_engine(HostType :: server()) -> odbc | mysql | pgsql | undefined. +db_engine(_HostType) -> try mongoose_rdbms_backend:backend_name() catch error:undef -> undefined end.