1
0
mirror of https://github.com/ubf/ubf.git synced 2026-04-24 13:45:59 +00:00

rework proto option and add example test_sup

This commit is contained in:
Joseph Wayne Norton
2009-04-21 00:08:06 +09:00
parent 06b68f718e
commit 1bfb7b88ef
11 changed files with 191 additions and 110 deletions

View File

@@ -35,10 +35,11 @@ TESTS = \
socket_test_client \
socket_test_server \
test_plugin \
test_sup \
test_ubf \
test_jsf \
test_ebf \
test_etf \
test_jsf \
ubf_test \
jsf_test
@@ -64,25 +65,12 @@ check: all
$(RUNERL1) -noinput -noshell -pz $(TEST_DIR) \
-s ubf_test tests \
-s test_ubf tests \
-s erlang halt \
> ./check.log
# TEMPORARILY DISABLE jsf_test to avoid failures if erlang-rfc4627 is
# not available
# $(RUNERL1) -noinput -noshell -pz $(TEST_DIR) \
# -s jsf_test tests \
# -s erlang halt \
# >> ./check.log
$(RUNERL1) -noinput -noshell -pz $(TEST_DIR) \
-s test_ebf tests \
-s erlang halt \
>> ./check.log
$(RUNERL1) -noinput -noshell -pz $(TEST_DIR) \
-s test_etf tests \
-s erlang halt \
>> ./check.log
> ./check.log
check-jsf: all
-rm -f ./*.log
$(RUNERL1) -noinput -noshell -pz $(TEST_DIR) \
-s jsf_test tests \
-s erlang halt \

View File

@@ -2,18 +2,19 @@
-compile(export_all).
-include("ubf.hrl").
-import(lists, [map/2, foldl/3, filter/2]).
-import(ubf_client, [rpc/2]).
defaultPlugins() -> [test_plugin, irc_plugin, file_plugin].
defaultServer() -> ubf_server.
defaultOptions() -> [].
defaultOptions() -> [{plugins, defaultPlugins()}].
defaultTimeout() -> 10000.
defaultPort() -> 2001.
tests() ->
proc_socket_server:stop_server(defaultPort()),
catch (erlang:exit(whereis(test_sup))),
sleep(1),
ss(),
sleep(1), %%% we have to wait if we run *immediately* there
@@ -21,37 +22,34 @@ tests() ->
test(),
true.
s(Str) -> {'#S', Str}.
-define(S(Str), {'#S',Str}).
ss() ->
ubf_server:start(defaultPlugins(), defaultPort(), [{ebf,true}]).
test_sup:start_link(defaultOptions()).
test() ->
{ok, Pid, _Name} = ubf_client:connect(host(), defaultPort(), [{ebf,true}], defaultTimeout()),
{ok, Pid, _Name} = ubf_client:connect(host(), defaultPort(), [{proto,ebf}], defaultTimeout()),
Info = ubf_client:rpc(Pid, info),
io:format("Info=~p~n",[Info]),
Services = ubf_client:rpc(Pid, services),
io:format("Services=~p~n",[Services]),
%% Try to start a missing service
R1 = ubf_client:rpc(Pid, {startSession, s("missing"), []}),
R1 = ubf_client:rpc(Pid, {startSession, ?S("missing"), []}),
io:format("R1=~p~n",[R1]),
%% Try to start the test server with the wrong password
R2 = ubf_client:rpc(Pid, {startSession, s("test"), guess}),
R2 = ubf_client:rpc(Pid, {startSession, ?S("test"), guess}),
io:format("R2=~p~n",[R2]),
%% Now the correct password
R3 = ubf_client:rpc(Pid, {startSession, s("test"), secret}),
R3 = ubf_client:rpc(Pid, {startSession, ?S("test"), secret}),
io:format("R3=~p~n",[R3]),
rpc(Pid, {logon,s("joe")}),
rpc(Pid, {logon,?S("joe")}),
{reply, {files, _}, active} = rpc(Pid, ls),
install_single_callback_handler(Pid),
Term = {1,2,cat,rain,dogs},
{reply, callbackOnItsWay, active} = rpc(Pid, {callback,Term}),
{callback, Term} = expect_callback(Pid),
{reply, yes, funny} = rpc(Pid, testAmbiguities),
{reply, ?S("ABC"), funny} = rpc(Pid, s("abc")),
{reply, ?S("ABC"), funny} = rpc(Pid, ?S("abc")),
{reply, [400,800], funny} = rpc(Pid, [200,400]),
{reply, [194,196], funny} = rpc(Pid, "ab"),
ubf_client:stop(Pid),

View File

@@ -2,31 +2,31 @@
-compile(export_all).
-include("ubf.hrl").
-import(lists, [map/2, foldl/3, filter/2]).
-import(ubf_client, [rpc/2]).
defaultPlugins() -> [test_plugin, irc_plugin, file_plugin].
defaultServer() -> ubf_server.
defaultOptions() -> [].
defaultOptions() -> [{plugins, defaultPlugins()}].
defaultTimeout() -> 10000.
defaultPort() -> 2002.
defaultServer() -> [Server] = [ Child || {Id,Child,_Type,_Module} <- supervisor:which_children(test_sup),
Id==ubf_server ],
Server.
tests() ->
catch exit(whereis(defaultServer()),kill),
catch (erlang:exit(whereis(test_sup))),
sleep(1),
ss(),
sleep(1), %%% we have to wait if we run *immediately* there
%% is no way of knowing if the server has started
test(),
true.
s(Str) -> {'#S', Str}.
-define(S(Str), {'#S',Str}).
ss() ->
ubf_server:start(defaultPlugins(),defaultPort()).
test_sup:start_link(defaultOptions()).
test() ->
{ok, Pid, _Name} = ubf_client:connect(defaultPlugins(), defaultServer(), defaultOptions(), defaultTimeout()),
@@ -35,24 +35,24 @@ test() ->
Services = ubf_client:rpc(Pid, services),
io:format("Services=~p~n",[Services]),
%% Try to start a missing service
R1 = ubf_client:rpc(Pid, {startSession, s("missing"), []}),
R1 = ubf_client:rpc(Pid, {startSession, ?S("missing"), []}),
io:format("R1=~p~n",[R1]),
%% Try to start the test server with the wrong password
R2 = ubf_client:rpc(Pid, {startSession, s("test"), guess}),
R2 = ubf_client:rpc(Pid, {startSession, ?S("test"), guess}),
io:format("R2=~p~n",[R2]),
ubf_client:stop(Pid),
%% Now the correct password
{ok, Pid1, _Name} = ubf_client:connect(defaultPlugins(), defaultServer(), defaultOptions(), defaultTimeout()),
R3 = ubf_client:rpc(Pid1, {startSession, s("test"), secret}),
R3 = ubf_client:rpc(Pid1, {startSession, ?S("test"), secret}),
io:format("R3=~p~n",[R3]),
rpc(Pid1, {logon,s("joe")}),
rpc(Pid1, {logon,?S("joe")}),
{reply, {files, _}, active} = rpc(Pid1, ls),
install_single_callback_handler(Pid1),
Term = {1,2,cat,rain,dogs},
{reply, callbackOnItsWay, active} = rpc(Pid1, {callback,Term}),
{callback, Term} = expect_callback(Pid1),
{reply, yes, funny} = rpc(Pid1, testAmbiguities),
{reply, ?S("ABC"), funny} = rpc(Pid1, s("abc")),
{reply, ?S("ABC"), funny} = rpc(Pid1, ?S("abc")),
{reply, [400,800], funny} = rpc(Pid1, [200,400]),
{reply, [194,196], funny} = rpc(Pid1, "ab"),
ubf_client:stop(Pid1),

View File

@@ -2,18 +2,19 @@
-compile(export_all).
-include("ubf.hrl").
-import(lists, [map/2, foldl/3, filter/2]).
-import(ubf_client, [rpc/2]).
defaultPlugins() -> [test_plugin, irc_plugin, file_plugin].
defaultServer() -> ubf_server.
defaultOptions() -> [].
defaultOptions() -> [{plugins, defaultPlugins()}].
defaultTimeout() -> 10000.
defaultPort() -> 2001.
defaultPort() -> 2002.
tests() ->
proc_socket_server:stop_server(defaultPort()),
catch (erlang:exit(whereis(test_sup))),
sleep(1),
ss(),
sleep(1), %%% we have to wait if we run *immediately* there
@@ -21,37 +22,34 @@ tests() ->
test(),
true.
s(Str) -> {'#S', Str}.
-define(S(Str), {'#S',Str}).
ss() ->
ubf_server:start(defaultPlugins(), defaultPort(), [{jsf,true}]).
test_sup:start_link(defaultOptions()).
test() ->
{ok, Pid, _Name} = ubf_client:connect(host(), defaultPort(), [{jsf,true}], defaultTimeout()),
{ok, Pid, _Name} = ubf_client:connect(host(), defaultPort(), [{proto,jsf}], defaultTimeout()),
Info = ubf_client:rpc(Pid, info),
io:format("Info=~p~n",[Info]),
Services = ubf_client:rpc(Pid, services),
io:format("Services=~p~n",[Services]),
%% Try to start a missing service
R1 = ubf_client:rpc(Pid, {startSession, s("missing"), []}),
R1 = ubf_client:rpc(Pid, {startSession, ?S("missing"), []}),
io:format("R1=~p~n",[R1]),
%% Try to start the test server with the wrong password
R2 = ubf_client:rpc(Pid, {startSession, s("test"), guess}),
R2 = ubf_client:rpc(Pid, {startSession, ?S("test"), guess}),
io:format("R2=~p~n",[R2]),
%% Now the correct password
R3 = ubf_client:rpc(Pid, {startSession, s("test"), secret}),
R3 = ubf_client:rpc(Pid, {startSession, ?S("test"), secret}),
io:format("R3=~p~n",[R3]),
rpc(Pid, {logon,s("joe")}),
rpc(Pid, {logon,?S("joe")}),
{reply, {files, _}, active} = rpc(Pid, ls),
install_single_callback_handler(Pid),
Term = {1,2,cat,rain,dogs},
{reply, callbackOnItsWay, active} = rpc(Pid, {callback,Term}),
{callback, Term} = expect_callback(Pid),
{reply, yes, funny} = rpc(Pid, testAmbiguities),
{reply, ?S("ABC"), funny} = rpc(Pid, s("abc")),
{reply, ?S("ABC"), funny} = rpc(Pid, ?S("abc")),
{reply, [400,800], funny} = rpc(Pid, [200,400]),
{reply, [194,196], funny} = rpc(Pid, "ab"),
ubf_client:stop(Pid),

View File

@@ -0,0 +1,108 @@
%%%----------------------------------------------------------------------
%%% File : test_sup.erl
%%% Purpose : test UBF top-level supervisor
%%%----------------------------------------------------------------------
-module(test_sup).
-behaviour(supervisor).
%% External exports
-export([start_link/1]).
%% supervisor callbacks
-export([init/1]).
-define(SERVER, ?MODULE).
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start_link(_Args) ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
%%%----------------------------------------------------------------------
%%% Callback functions from supervisor
%%%----------------------------------------------------------------------
%%----------------------------------------------------------------------
%% Func: init/1
%% Returns: {ok, {SupFlags, [ChildSpec]}} |
%% ignore |
%% {error, Reason}
%%----------------------------------------------------------------------
%% @spec(Args::term()) -> {ok, {supervisor_flags(), child_spec_list()}}
%% @doc The main TEST UBF supervisor.
init(Args) ->
%% seq_trace:set_token(send, true), seq_trace:set_token('receive', true),
%% Child_spec = [Name, {M, F, A},
%% Restart, Shutdown_time, Type, Modules_used]
DefaultMaxConn = 10000,
DefaultTimeout = 60000,
DefaultPlugins = proplists:get_value(plugins, Args, [file_plugin, irc_plugin, irc_plugin, test_plugin]),
CUBF = case proplists:get_value(test_ubf_tcp_port, Args, 2000) of
0 ->
[];
UBFPort ->
UBFMaxConn = proplists:get_value(test_ubf_maxconn, Args, DefaultMaxConn),
UBFIdleTimer = proplists:get_value(test_ubf_timeout, Args, DefaultTimeout),
UBFOptions = [{serverhello, "test_meta_server"}
, {statelessrpc,false}
, {proto,ubf}
, {maxconn,UBFMaxConn}
, {idletimer,UBFIdleTimer}
],
UBFServer =
{ubf_server, {ubf_server, start_link, [DefaultPlugins, UBFPort, UBFOptions]},
permanent, 2000, worker, [ubf_server]},
[UBFServer]
end,
CEBF = case proplists:get_value(test_ebf_tcp_port, Args, 2001) of
0 ->
[];
EBFPort ->
EBFMaxConn = proplists:get_value(test_ebf_maxconn, Args, DefaultMaxConn),
EBFIdleTimer = proplists:get_value(test_ebf_timeout, Args, DefaultTimeout),
EBFOptions = [{serverhello, "test_meta_server"}
, {statelessrpc,false}
, {proto,ebf}
, {maxconn,EBFMaxConn}
, {idletimer,EBFIdleTimer}
],
EBFServer =
{ebf_server, {ubf_server, start_link, [DefaultPlugins, EBFPort, EBFOptions]},
permanent, 2000, worker, [ebf_server]},
[EBFServer]
end,
CJSF = case proplists:get_value(test_jsf_tcp_port, Args, 2002) of
0 ->
[];
JSFPort ->
JSFMaxConn = proplists:get_value(test_jsf_maxconn, Args, DefaultMaxConn),
JSFIdleTimer = proplists:get_value(test_jsf_timeout, Args, DefaultTimeout),
JSFOptions = [{serverhello, "test_meta_server"}
, {statelessrpc,false}
, {proto,jsf}
, {maxconn,JSFMaxConn}
, {idletimer,JSFIdleTimer}
],
JSFServer =
{jsf_server, {ubf_server, start_link, [DefaultPlugins, JSFPort, JSFOptions]},
permanent, 2000, worker, [jsf_server]},
[JSFServer]
end,
{ok, {{one_for_one, 2, 60}, CUBF ++ CEBF ++ CJSF}}.
%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------

View File

@@ -2,18 +2,19 @@
-compile(export_all).
-include("ubf.hrl").
-import(lists, [map/2, foldl/3, filter/2]).
-import(ubf_client, [rpc/2]).
defaultPlugins() -> [test_plugin, irc_plugin, file_plugin].
defaultServer() -> ubf_server.
defaultOptions() -> [].
defaultOptions() -> [{plugins, defaultPlugins()}].
defaultTimeout() -> 10000.
defaultPort() -> 2000.
tests() ->
proc_socket_server:stop_server(defaultPort()),
catch (erlang:exit(whereis(test_sup))),
sleep(1),
ss(),
sleep(1), %%% we have to wait if we run *immediately* there
@@ -21,37 +22,34 @@ tests() ->
test(),
true.
s(Str) -> {'#S', Str}.
-define(S(Str), {'#S',Str}).
ss() ->
ubf_server:start(defaultPlugins(), defaultPort(), [{ebf,false}]).
test_sup:start_link(defaultOptions()).
test() ->
{ok, Pid, _Name} = ubf_client:connect(host(), defaultPort(), [{ebf,false}], defaultTimeout()),
{ok, Pid, _Name} = ubf_client:connect(host(), defaultPort(), [{proto,ubf}], defaultTimeout()),
Info = ubf_client:rpc(Pid, info),
io:format("Info=~p~n",[Info]),
Services = ubf_client:rpc(Pid, services),
io:format("Services=~p~n",[Services]),
%% Try to start a missing service
R1 = ubf_client:rpc(Pid, {startSession, s("missing"), []}),
R1 = ubf_client:rpc(Pid, {startSession, ?S("missing"), []}),
io:format("R1=~p~n",[R1]),
%% Try to start the test server with the wrong password
R2 = ubf_client:rpc(Pid, {startSession, s("test"), guess}),
R2 = ubf_client:rpc(Pid, {startSession, ?S("test"), guess}),
io:format("R2=~p~n",[R2]),
%% Now the correct password
R3 = ubf_client:rpc(Pid, {startSession, s("test"), secret}),
R3 = ubf_client:rpc(Pid, {startSession, ?S("test"), secret}),
io:format("R3=~p~n",[R3]),
rpc(Pid, {logon,s("joe")}),
rpc(Pid, {logon,?S("joe")}),
{reply, {files, _}, active} = rpc(Pid, ls),
install_single_callback_handler(Pid),
Term = {1,2,cat,rain,dogs},
{reply, callbackOnItsWay, active} = rpc(Pid, {callback,Term}),
{callback, Term} = expect_callback(Pid),
{reply, yes, funny} = rpc(Pid, testAmbiguities),
{reply, ?S("ABC"), funny} = rpc(Pid, s("abc")),
{reply, ?S("ABC"), funny} = rpc(Pid, ?S("abc")),
{reply, [400,800], funny} = rpc(Pid, [200,400]),
{reply, [194,196], funny} = rpc(Pid, "ab"),
ubf_client:stop(Pid),

View File

@@ -21,12 +21,12 @@
%% stop(Pid) -> ack.
-export([connect/2, connect/3, connect/4, rpc/2, rpc/3, stop/1,
install_default_handler/1, install_handler/2]).
install_default_handler/1, install_handler/2]).
-import(ubf_utils, [spawn_link_debug/2]).
%% @type address() = string() | ip_address(). A DNS hostname or IP address.
%% @type connect_options() = list(ubf | ebf | jsf).
%% @type connect_options() = list({proto, ubf | ebf | jsf}).
%% An OTP-style property list, see 'proplists' module for details.
%% @type ip_address() = string() | tuple(). An IP address in string form,
%% e.g. "127.0.0.1" (IPv4) or "::1" (IPv6), or in tuple form (see
@@ -114,16 +114,13 @@ ubf_client(Parent, Host, Port, Options, Timeout)
DefaultConnectOptions =
[binary, {nodelay, true}, {active, false}],
{DriverModule, DriverVersion, ConnectOptions} =
case proplists:get_value(ebf,Options,false) of
false ->
case proplists:get_value(jsf,Options,false) of
false ->
{ubf_driver, 'ubf1.0', DefaultConnectOptions};
true ->
{jsf_driver, 'jsf1.0', DefaultConnectOptions}
end;
true ->
{ebf_driver, 'ebf1.0', DefaultConnectOptions++[{packet,4}]}
case proplists:get_value(proto,Options,ubf) of
ubf ->
{ubf_driver, 'ubf1.0', DefaultConnectOptions};
ebf ->
{ebf_driver, 'ebf1.0', DefaultConnectOptions++[{packet,4}]};
jsf ->
{jsf_driver, 'jsf1.0', DefaultConnectOptions}
end,
%% io:format("QQQ: ~p : ~p : ~p ~n", [DriverModule, DriverVersion, ConnectOptions]),
case gen_tcp:connect(Host, Port, ConnectOptions) of

View File

@@ -1,5 +1,5 @@
%%% -*- mode: erlang -*-
%%% $Id: ubf_plugin_meta_server.con 131834 2009-04-11 14:31:28Z norton $
%%% $Id$
%%%
+NAME("meta_server").

View File

@@ -1,5 +1,5 @@
%%% -*- mode: erlang -*-
%%% $Id: ubf_plugin_meta_serverful.erl 132057 2009-04-14 08:22:27Z norton $
%%% $Id$
%%%
-module(ubf_plugin_meta_serverful, [MODULES]).

View File

@@ -1,5 +1,5 @@
%%% -*- mode: erlang -*-
%%% $Id: ubf_plugin_meta_serverless.erl 132057 2009-04-14 08:22:27Z norton $
%%% $Id$
%%%
-module(ubf_plugin_meta_serverless, [MODULES]).

View File

@@ -74,10 +74,9 @@ start(PluginModules, Port) ->
%%
%% Valid properties in the Options proplist are:
%% <ul>
%% <li> {ebf, true | false} ... Enable the EBF version of the protocol's
%% wire format.
%% Only one of ebf, jsf, and ubf should be specified.
%% Default: false. </li>
%% <li> {proto, {ubf | ebf | jsf}} ... Enable the UBF, EBF, or JSF version
%% of the protocol's wire format.
%% Default: ubf. </li>
%% <li> {idletimer, integer() | infinity} ... Maximum time (in milliseconds)
%% that a client connection may remain idle before the server will
%% close the connection.
@@ -85,10 +84,9 @@ start(PluginModules, Port) ->
%% <li> {maxconn, integer()} ... Maximum number of simultaneous TCP
%% connections allowed.
%% Default: 10,000. </li>
%% <li> {jsf, true | false} ... Enable the JSON version of the protocol's
%% wire format.
%% Only one of ebf, jsf, and ubf should be specified.
%% Default: false. </li>
%% <li> {proto, {ubf | ebf | jsf}} ... Enable the UBF, EBF, or JSF version
%% of the protocol's wire format.
%% Default: ubf. </li>
%% <li> {serverhello, string()} ... Meta contract greeting string, sent
%% when a client first connects to the server.
%% Default: "meta_server" </li>
@@ -97,10 +95,9 @@ start(PluginModules, Port) ->
%% Joe Armstrong's original UBF server implementation.
%% Default: false.
%% TO-DO: JoeNorton, add more? </li>
%% <li> {ubf, true | false} ... Enable the JSON version of the protocol's
%% wire format.
%% Only one of ebf, jsf, and ubf should be specified.
%% Default: true. </li>
%% <li> {proto, {ubf | ebf | jsf}} ... Enable the UBF, EBF, or JSF version
%% of the protocol's wire format.
%% Default: ubf. </li>
%% <li> {verboserpc, true | false} ... Set the verbose RPC mode.
%% Default: false.
%% TO-DO: JoeNorton, add more? </li>
@@ -146,16 +143,13 @@ start_ubf_listener(MetaServerModule, Port, Server, Options) ->
proplists:get_value(verboserpc,Options,false),
{DriverModule, DriverVersion, PacketType} =
case proplists:get_value(ebf,Options,false) of
false ->
case proplists:get_value(jsf,Options,false) of
false ->
{ubf_driver, 'ubf1.0', 0};
true ->
{jsf_driver, 'jsf1.0', 0}
end;
true ->
{ebf_driver, 'ebf1.0', 4}
case proplists:get_value(proto,Options,ubf) of
ubf ->
{ubf_driver, 'ubf1.0', 0};
ebf ->
{ebf_driver, 'ebf1.0', 4};
jsf ->
{jsf_driver, 'jsf1.0', 0}
end,
IdleTimer =
case proplists:get_value(idletimer,Options,16#ffffffff) of