mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
Add tests for modules using MySQL/PostgreSQL
This commit is contained in:
parent
2ec048a5ae
commit
4f8bb4f918
@ -252,6 +252,9 @@ dialyzer: plt
|
||||
--get_warnings -o dialyzer.log ebin
|
||||
|
||||
test:
|
||||
@echo "************************** NOTICE ***************************************"
|
||||
@cat test/README
|
||||
@echo "*************************************************************************"
|
||||
$(REBAR) skip_deps=true ct
|
||||
|
||||
.PHONY: src doc edoc dialyzer Makefile TAGS clean clean-rel distclean rel plt \
|
||||
|
15
test/README
Normal file
15
test/README
Normal file
@ -0,0 +1,15 @@
|
||||
You need MySQL and PostgreSQL up and running.
|
||||
Both of them should grant access to user 'ejabberd_test' with
|
||||
password 'ejabberd_test' on database 'ejabberd_test'.
|
||||
|
||||
Here is a quick setup example:
|
||||
|
||||
$ psql template1
|
||||
template1=# CREATE USER ejabberd_test WITH PASSWORD 'ejabberd_test';
|
||||
template1=# CREATE DATABASE ejabberd_test;
|
||||
template1=# GRANT ALL PRIVILEGES ON DATABASE ejabberd_test TO ejabberd_test;
|
||||
|
||||
$ mysql
|
||||
mysql> CREATE USER ejabberd_test IDENTIFIED BY 'ejabberd_test';
|
||||
mysql> CREATE DATABASE ejabberd_test;
|
||||
mysql> GRANT ALL ON ejabberd_test.* TO ejabberd_test;
|
@ -65,12 +65,19 @@
|
||||
end
|
||||
end)()).
|
||||
|
||||
-define(COMMON_VHOST, <<"localhost">>).
|
||||
-define(MNESIA_VHOST, <<"mnesia.localhost">>).
|
||||
-define(MYSQL_VHOST, <<"mysql.localhost">>).
|
||||
-define(PGSQL_VHOST, <<"pgsql.localhost">>).
|
||||
|
||||
suite() ->
|
||||
[{timetrap, {seconds,10}}].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
DataDir = proplists:get_value(data_dir, Config),
|
||||
PrivDir = proplists:get_value(priv_dir, Config),
|
||||
[_, _|Tail] = lists:reverse(filename:split(DataDir)),
|
||||
BaseDir = filename:join(lists:reverse(Tail)),
|
||||
ConfigPath = filename:join([DataDir, "ejabberd.cfg"]),
|
||||
LogPath = filename:join([PrivDir, "ejabberd.log"]),
|
||||
SASLPath = filename:join([PrivDir, "sasl.log"]),
|
||||
@ -83,10 +90,12 @@ init_per_suite(Config) ->
|
||||
application:set_env(sasl, sasl_error_logger, {file, SASLPath}),
|
||||
application:set_env(mnesia, dir, MnesiaDir),
|
||||
ok = application:start(ejabberd),
|
||||
[{server, <<"localhost">>},
|
||||
{port, 5222},
|
||||
{host, "localhost"},
|
||||
[{server_port, 5222},
|
||||
{server_host, "localhost"},
|
||||
{server, ?COMMON_VHOST},
|
||||
{user, <<"test_single">>},
|
||||
{certfile, CertFile},
|
||||
{base_dir, BaseDir},
|
||||
{resource, <<"resource">>},
|
||||
{password, <<"password">>}
|
||||
|Config].
|
||||
@ -94,20 +103,47 @@ init_per_suite(Config) ->
|
||||
end_per_suite(_Config) ->
|
||||
ok.
|
||||
|
||||
init_per_group(no_db, Config) ->
|
||||
User = ?config(user, Config),
|
||||
Server = ?config(server, Config),
|
||||
Password = ?config(password, Config),
|
||||
{atomic, ok} = ejabberd_auth:try_register(User, Server, Password),
|
||||
Config;
|
||||
init_per_group(mnesia, Config) ->
|
||||
set_opt(server, ?MNESIA_VHOST, Config);
|
||||
init_per_group(mysql, Config) ->
|
||||
case catch ejabberd_odbc:sql_query(?MYSQL_VHOST, [<<"select 1;">>]) of
|
||||
{selected, _, _} ->
|
||||
create_sql_tables(mysql, ?config(base_dir, Config)),
|
||||
set_opt(server, ?MYSQL_VHOST, Config);
|
||||
Err ->
|
||||
{skip, {mysql_not_available, Err}}
|
||||
end;
|
||||
init_per_group(pgsql, Config) ->
|
||||
case catch ejabberd_odbc:sql_query(?PGSQL_VHOST, [<<"select 1;">>]) of
|
||||
{selected, _, _} ->
|
||||
create_sql_tables(pgsql, ?config(base_dir, Config)),
|
||||
set_opt(server, ?PGSQL_VHOST, Config);
|
||||
Err ->
|
||||
{skip, {pgsql_not_available, Err}}
|
||||
end;
|
||||
init_per_group(_GroupName, Config) ->
|
||||
Pid = start_event_relay(),
|
||||
set_opt(event_relay, Pid, Config).
|
||||
|
||||
end_per_group(mnesia, _Config) ->
|
||||
ok;
|
||||
end_per_group(mysql, _Config) ->
|
||||
ok;
|
||||
end_per_group(pgsql, _Config) ->
|
||||
ok;
|
||||
end_per_group(no_db, _Config) ->
|
||||
ok;
|
||||
end_per_group(_GroupName, Config) ->
|
||||
stop_event_relay(Config),
|
||||
ok.
|
||||
|
||||
init_per_testcase(stop_ejabberd, OrigConfig) ->
|
||||
User = <<"test_stop">>,
|
||||
Config = set_opt(user, User, OrigConfig),
|
||||
ejabberd_auth:try_register(User,
|
||||
?config(server, Config),
|
||||
?config(password, Config)),
|
||||
init_per_testcase(stop_ejabberd, Config) ->
|
||||
open_session(bind(auth(connect(Config))));
|
||||
init_per_testcase(TestCase, OrigConfig) ->
|
||||
subscribe_to_events(OrigConfig),
|
||||
@ -155,49 +191,58 @@ init_per_testcase(TestCase, OrigConfig) ->
|
||||
end_per_testcase(_TestCase, _Config) ->
|
||||
ok.
|
||||
|
||||
groups() ->
|
||||
[{single_user, [sequence],
|
||||
generic_tests() ->
|
||||
[{generic, [sequence],
|
||||
[test_connect,
|
||||
test_starttls,
|
||||
test_zlib,
|
||||
test_register,
|
||||
auth_plain,
|
||||
auth_md5,
|
||||
test_auth,
|
||||
test_bind,
|
||||
test_open_session,
|
||||
roster_get,
|
||||
presence_broadcast,
|
||||
presence,
|
||||
ping,
|
||||
version,
|
||||
time,
|
||||
stats,
|
||||
disco,
|
||||
disco]},
|
||||
{test_proxy65, [parallel],
|
||||
[proxy65_master, proxy65_slave]}].
|
||||
|
||||
tests() ->
|
||||
[{single_user, [sequence],
|
||||
[test_register,
|
||||
auth_plain,
|
||||
auth_md5,
|
||||
presence_broadcast,
|
||||
last,
|
||||
roster_get,
|
||||
private,
|
||||
privacy,
|
||||
blocking,
|
||||
vcard,
|
||||
pubsub,
|
||||
muc_single,
|
||||
pubsub,
|
||||
test_unregister]},
|
||||
{test_roster_subscribe, [parallel],
|
||||
[roster_subscribe_master,
|
||||
roster_subscribe_slave]},
|
||||
{test_proxy65, [parallel],
|
||||
[proxy65_master, proxy65_slave]},
|
||||
{test_offline, [sequence],
|
||||
[offline_master, offline_slave]},
|
||||
{test_roster_remove, [parallel],
|
||||
[roster_remove_master,
|
||||
roster_remove_slave]}].
|
||||
|
||||
groups() ->
|
||||
[{no_db, [sequence], generic_tests()},
|
||||
{mnesia, [sequence], tests()},
|
||||
{mysql, [sequence], tests()},
|
||||
{pgsql, [sequence], tests()}].
|
||||
|
||||
all() ->
|
||||
[{group, single_user},
|
||||
{group, test_roster_subscribe},
|
||||
{group, test_proxy65},
|
||||
{group, test_offline},
|
||||
{group, test_roster_remove},
|
||||
[{group, no_db},
|
||||
{group, mnesia},
|
||||
{group, mysql},
|
||||
{group, pgsql},
|
||||
stop_ejabberd].
|
||||
|
||||
stop_ejabberd(Config) ->
|
||||
@ -211,8 +256,8 @@ test_connect(Config) ->
|
||||
|
||||
connect(Config) ->
|
||||
{ok, Sock} = ejabberd_socket:connect(
|
||||
?config(host, Config),
|
||||
?config(port, Config),
|
||||
?config(server_host, Config),
|
||||
?config(server_port, Config),
|
||||
[binary, {packet, 0}, {active, false}]),
|
||||
init_stream(set_opt(socket, Sock, Config)).
|
||||
|
||||
@ -362,6 +407,12 @@ roster_get(Config) ->
|
||||
send_recv(Config, #iq{type = get, sub_els = [#roster{}]}),
|
||||
disconnect(Config).
|
||||
|
||||
presence(Config) ->
|
||||
send(Config, #presence{}),
|
||||
JID = my_jid(Config),
|
||||
#presence{from = JID, to = JID} = recv(),
|
||||
disconnect(Config).
|
||||
|
||||
presence_broadcast(Config) ->
|
||||
send(Config, #presence{}),
|
||||
JID = my_jid(Config),
|
||||
@ -778,8 +829,7 @@ proxy65_master(Config) ->
|
||||
Peer = ?config(slave, Config),
|
||||
wait_for_slave(Config),
|
||||
send(Config, #presence{}),
|
||||
?recv2(#presence{from = MyJID, type = undefined},
|
||||
#presence{from = Peer, type = undefined}),
|
||||
#presence{from = MyJID, type = undefined} = recv(),
|
||||
true = is_feature_advertised(Config, ?NS_BYTESTREAMS, Proxy),
|
||||
#iq{type = result, sub_els = [#bytestreams{hosts = [StreamHost]}]} =
|
||||
send_recv(
|
||||
@ -795,7 +845,7 @@ proxy65_master(Config) ->
|
||||
#iq{type = set, to = Proxy,
|
||||
sub_els = [#bytestreams{activate = Peer, sid = SID}]}),
|
||||
socks5_send(Socks5, Data),
|
||||
#presence{type = unavailable, from = Peer} = recv(),
|
||||
%%#presence{type = unavailable, from = Peer} = recv(),
|
||||
disconnect(Config).
|
||||
|
||||
proxy65_slave(Config) ->
|
||||
@ -804,7 +854,6 @@ proxy65_slave(Config) ->
|
||||
send(Config, #presence{}),
|
||||
#presence{from = MyJID, type = undefined} = recv(),
|
||||
wait_for_master(Config),
|
||||
#presence{from = Peer, type = undefined} = recv(),
|
||||
{StreamHost, SID, Data} = get_event(Config),
|
||||
Socks5 = socks5_connect(StreamHost, {SID, Peer, MyJID}),
|
||||
wait_for_master(Config),
|
||||
@ -1216,3 +1265,78 @@ insert(Val, N, Tuple) ->
|
||||
L = tuple_to_list(Tuple),
|
||||
{H, T} = lists:split(N-1, L),
|
||||
list_to_tuple(H ++ [Val|T]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% SQL stuff
|
||||
%%%===================================================================
|
||||
create_sql_tables(Type, BaseDir) ->
|
||||
{VHost, File} = case Type of
|
||||
mysql ->
|
||||
{?MYSQL_VHOST, "mysql.sql"};
|
||||
pgsql ->
|
||||
{?PGSQL_VHOST, "pg.sql"}
|
||||
end,
|
||||
SQLFile = filename:join([BaseDir, "sql", File]),
|
||||
CreationQueries = read_sql_queries(SQLFile),
|
||||
DropTableQueries = drop_table_queries(CreationQueries),
|
||||
case ejabberd_odbc:sql_transaction(
|
||||
VHost, DropTableQueries ++ CreationQueries) of
|
||||
{atomic, ok} ->
|
||||
ok;
|
||||
Err ->
|
||||
ct:fail({failed_to_create_sql_tables, Type, Err})
|
||||
end.
|
||||
|
||||
read_sql_queries(File) ->
|
||||
case file:open(File, [read, binary]) of
|
||||
{ok, Fd} ->
|
||||
read_lines(Fd, File, []);
|
||||
Err ->
|
||||
ct:fail({open_file_failed, File, Err})
|
||||
end.
|
||||
|
||||
drop_table_queries(Queries) ->
|
||||
lists:foldl(
|
||||
fun(Query, Acc) ->
|
||||
case split(str:to_lower(Query)) of
|
||||
[<<"create">>, <<"table">>, Table|_] ->
|
||||
[<<"DROP TABLE IF EXISTS ", Table/binary, ";">>|Acc];
|
||||
_ ->
|
||||
Acc
|
||||
end
|
||||
end, [], Queries).
|
||||
|
||||
read_lines(Fd, File, Acc) ->
|
||||
case file:read_line(Fd) of
|
||||
{ok, Line} ->
|
||||
NewAcc = case str:strip(str:strip(Line, both, $\r), both, $\n) of
|
||||
<<"--", _/binary>> ->
|
||||
Acc;
|
||||
<<>> ->
|
||||
Acc;
|
||||
_ ->
|
||||
[Line|Acc]
|
||||
end,
|
||||
read_lines(Fd, File, NewAcc);
|
||||
eof ->
|
||||
QueryList = str:tokens(list_to_binary(lists:reverse(Acc)), <<";">>),
|
||||
lists:flatmap(
|
||||
fun(Query) ->
|
||||
case str:strip(str:strip(Query, both, $\r), both, $\n) of
|
||||
<<>> ->
|
||||
[];
|
||||
Q ->
|
||||
[<<Q/binary, $;>>]
|
||||
end
|
||||
end, QueryList);
|
||||
{error, _} = Err ->
|
||||
ct:fail({read_file_failed, File, Err})
|
||||
end.
|
||||
|
||||
split(Data) ->
|
||||
lists:filter(
|
||||
fun(<<>>) ->
|
||||
false;
|
||||
(_) ->
|
||||
true
|
||||
end, re:split(Data, <<"\s">>)).
|
||||
|
@ -1,5 +1,5 @@
|
||||
{loglevel, 4}.
|
||||
{hosts, ["localhost"]}.
|
||||
{hosts, ["localhost", "mnesia.localhost", "mysql.localhost", "pgsql.localhost"]}.
|
||||
{define_macro, 'CERTFILE', "cert.pem"}.
|
||||
{listen,
|
||||
[
|
||||
@ -18,8 +18,6 @@
|
||||
captcha
|
||||
]}
|
||||
]}.
|
||||
{define_macro, 'DB_TYPE', internal}.
|
||||
{auth_method, 'DB_TYPE'}.
|
||||
{shaper, normal, {maxrate, 1000}}.
|
||||
{shaper, fast, {maxrate, 50000}}.
|
||||
{max_fsm_queue, 1000}.
|
||||
@ -44,35 +42,79 @@
|
||||
{modules,
|
||||
[
|
||||
{mod_adhoc, []},
|
||||
{mod_announce, [{db_type, 'DB_TYPE'}]},
|
||||
{mod_blocking, [{db_type, 'DB_TYPE'}]},
|
||||
{mod_caps, [{db_type, 'DB_TYPE'}]},
|
||||
{mod_configure, []},
|
||||
{mod_disco, []},
|
||||
{mod_last, [{db_type, 'DB_TYPE'}]},
|
||||
{mod_muc, []},
|
||||
{mod_offline, [{db_type, 'DB_TYPE'}]},
|
||||
{mod_ping, []},
|
||||
{mod_privacy, [{db_type, 'DB_TYPE'}]},
|
||||
{mod_private, [{db_type, 'DB_TYPE'}]},
|
||||
{mod_proxy65, []},
|
||||
{mod_pubsub, [
|
||||
{access_createnode, pubsub_createnode},
|
||||
{ignore_pep_from_offline, true},
|
||||
%%{ignore_pep_from_offline, false},
|
||||
{last_item_cache, false},
|
||||
{plugins, ["flat", "hometree", "pep", "public",
|
||||
"private", "mb"]}
|
||||
]},
|
||||
{mod_register, [
|
||||
{welcome_message, {"Welcome!",
|
||||
"Hi.\nWelcome to this XMPP server."}}
|
||||
"Hi.\nWelcome to this XMPP server."}}
|
||||
]},
|
||||
{mod_roster, [{db_type, 'DB_TYPE'}]},
|
||||
{mod_stats, []},
|
||||
{mod_time, []},
|
||||
{mod_vcard, [{db_type, 'DB_TYPE'}]},
|
||||
{mod_version, []}
|
||||
]}.
|
||||
{host_config, "localhost", [{auth_method, internal}]}.
|
||||
{host_config, "mnesia.localhost",
|
||||
[{auth_method, internal},
|
||||
{{add, modules}, [{mod_announce, [{db_type, internal}]},
|
||||
{mod_blocking, [{db_type, internal}]},
|
||||
{mod_caps, [{db_type, internal}]},
|
||||
{mod_last, [{db_type, internal}]},
|
||||
{mod_muc, [{db_type, internal}]},
|
||||
{mod_offline, [{db_type, internal}]},
|
||||
{mod_privacy, [{db_type, internal}]},
|
||||
{mod_private, [{db_type, internal}]},
|
||||
{mod_pubsub, [{access_createnode, pubsub_createnode},
|
||||
{ignore_pep_from_offline, true},
|
||||
{last_item_cache, false},
|
||||
{plugins, ["flat", "hometree", "pep"]}]},
|
||||
{mod_roster, [{db_type, internal}]},
|
||||
{mod_vcard, [{db_type, internal}]}]}
|
||||
]}.
|
||||
{host_config, "mysql.localhost",
|
||||
[{auth_method, odbc},
|
||||
{odbc_pool_size, 1},
|
||||
{odbc_server, {mysql, "localhost", "ejabberd_test",
|
||||
"ejabberd_test", "ejabberd_test"}},
|
||||
{{add, modules}, [{mod_announce, [{db_type, odbc}]},
|
||||
{mod_blocking, [{db_type, odbc}]},
|
||||
{mod_caps, [{db_type, odbc}]},
|
||||
{mod_last, [{db_type, odbc}]},
|
||||
{mod_muc, [{db_type, odbc}]},
|
||||
{mod_offline, [{db_type, odbc}]},
|
||||
{mod_privacy, [{db_type, odbc}]},
|
||||
{mod_private, [{db_type, odbc}]},
|
||||
{mod_pubsub_odbc, [{access_createnode, pubsub_createnode},
|
||||
{ignore_pep_from_offline, true},
|
||||
{last_item_cache, false},
|
||||
{plugins, ["flat_odbc",
|
||||
"hometree_odbc",
|
||||
"pep_odbc"]}]},
|
||||
{mod_roster, [{db_type, odbc}]},
|
||||
{mod_vcard, [{db_type, odbc}]}]}
|
||||
]}.
|
||||
{host_config, "pgsql.localhost",
|
||||
[{auth_method, odbc},
|
||||
{odbc_pool_size, 1},
|
||||
{odbc_server, {pgsql, "localhost", "ejabberd_test",
|
||||
"ejabberd_test", "ejabberd_test"}},
|
||||
{{add, modules}, [{mod_announce, [{db_type, odbc}]},
|
||||
{mod_blocking, [{db_type, odbc}]},
|
||||
{mod_caps, [{db_type, odbc}]},
|
||||
{mod_last, [{db_type, odbc}]},
|
||||
{mod_muc, [{db_type, odbc}]},
|
||||
{mod_offline, [{db_type, odbc}]},
|
||||
{mod_privacy, [{db_type, odbc}]},
|
||||
{mod_private, [{db_type, odbc}]},
|
||||
{mod_pubsub_odbc, [{access_createnode, pubsub_createnode},
|
||||
{ignore_pep_from_offline, true},
|
||||
{last_item_cache, false},
|
||||
{plugins, ["flat_odbc",
|
||||
"hometree_odbc",
|
||||
"pep_odbc"]}]},
|
||||
{mod_roster, [{db_type, odbc}]},
|
||||
{mod_vcard, [{db_type, odbc}]}]}
|
||||
]}.
|
||||
|
||||
%%% Local Variables:
|
||||
|
Loading…
Reference in New Issue
Block a user