diff options
Diffstat (limited to 'erts/emulator/test/ddll_SUITE.erl')
-rw-r--r-- | erts/emulator/test/ddll_SUITE.erl | 1632 |
1 files changed, 754 insertions, 878 deletions
diff --git a/erts/emulator/test/ddll_SUITE.erl b/erts/emulator/test/ddll_SUITE.erl index ffb68ed4ee..93b6f2d956 100644 --- a/erts/emulator/test/ddll_SUITE.erl +++ b/erts/emulator/test/ddll_SUITE.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% 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. +%% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% %% %CopyrightEnd% %% @@ -30,30 +31,31 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, ddll_test/1, errors/1, - reference_count/1, - kill_port/1, dont_kill_port/1]). +-export([all/0, suite/0, + ddll_test/1, errors/1, reference_count/1, + kill_port/1, dont_kill_port/1]). -export([unload_on_process_exit/1, delayed_unload_with_ports/1, - unload_due_to_process_exit/1, - no_unload_due_to_process_exit/1, no_unload_due_to_process_exit_2/1, - unload_reload_thingie/1, unload_reload_thingie_2/1, - unload_reload_thingie_3/1, reload_pending/1, reload_pending_kill/1, - load_fail_init/1, - reload_pending_fail_init/1, - more_error_codes/1, forced_port_killing/1, - no_trap_exit_and_kill_ports/1, - monitor_demonitor/1, monitor_demonitor_load/1, new_interface/1, - lock_driver/1]). + unload_due_to_process_exit/1, + no_unload_due_to_process_exit/1, no_unload_due_to_process_exit_2/1, + unload_reload_thingie/1, unload_reload_thingie_2/1, + unload_reload_thingie_3/1, reload_pending/1, reload_pending_kill/1, + load_fail_init/1, + reload_pending_fail_init/1, + more_error_codes/1, forced_port_killing/1, + no_trap_exit_and_kill_ports/1, + monitor_demonitor/1, monitor_demonitor_load/1, new_interface/1, + lock_driver/1]). % Private exports -export([echo_loader/2, nice_echo_loader/2 ,properties/1, load_and_unload/1]). -import(ordsets, [subtract/2]). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {seconds, 10}}]. all() -> [ddll_test, errors, reference_count, kill_port, @@ -69,1057 +71,931 @@ all() -> no_trap_exit_and_kill_ports, monitor_demonitor, monitor_demonitor_load, new_interface, lock_driver]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -unload_on_process_exit(suite) -> - []; -unload_on_process_exit(doc) -> - ["Check that the driver is unloaded on process exit"]; +%% Check that the driver is unloaded on process exit unload_on_process_exit(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line false = lists:member("echo_drv",element(2,erl_ddll:loaded_drivers())), + Path = proplists:get_value(data_dir, Config), + false = lists:member("echo_drv",element(2,erl_ddll:loaded_drivers())), Parent = self(), - ?line Pid = spawn(fun() -> - receive go -> ok end, - erl_ddll:try_load(Path, echo_drv, []), - Parent ! gone, - receive go -> ok end, - erl_ddll:loaded_drivers(), - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), - ?line false = lists:member("echo_drv",element(2,erl_ddll:loaded_drivers())), + Pid = spawn(fun() -> + receive go -> ok end, + erl_ddll:try_load(Path, echo_drv, []), + Parent ! gone, + receive go -> ok end, + erl_ddll:loaded_drivers(), + exit(banan) + end), + Ref = erlang:monitor(process,Pid), + false = lists:member("echo_drv",element(2,erl_ddll:loaded_drivers())), Pid ! go, - ?line receive - gone -> ok + receive + gone -> ok end, - ?line true = lists:member("echo_drv",element(2,erl_ddll:loaded_drivers())), + true = lists:member("echo_drv",element(2,erl_ddll:loaded_drivers())), Pid ! go, - ?line receive - {'DOWN', Ref, process, Pid, banan} -> - ok + receive + {'DOWN', Ref, process, Pid, banan} -> + ok end, receive after 500 -> ok end, - ?line false = lists:member("echo_drv",element(2,erl_ddll:loaded_drivers())), - ?line test_server:timetrap_cancel(Dog), + false = lists:member("echo_drv",element(2,erl_ddll:loaded_drivers())), ok. -delayed_unload_with_ports(suite) -> - []; -delayed_unload_with_ports(doc) -> - ["Check that the driver is unloaded when the last port is closed"]; +%% Check that the driver is unloaded when the last port is closed delayed_unload_with_ports(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line erl_ddll:try_load(Path, echo_drv, []), - ?line erl_ddll:try_load(Path, echo_drv, []), - ?line Port = open_port({spawn, echo_drv}, [eof]), - ?line 1 = erl_ddll:info(echo_drv, port_count), - ?line Port2 = open_port({spawn, echo_drv}, [eof]), - ?line 2 = erl_ddll:info(echo_drv, port_count), - ?line {ok,pending_process} = erl_ddll:try_unload(echo_drv,[{monitor, pending_driver}]), - ?line {ok,pending_driver,Ref} = erl_ddll:try_unload(echo_drv,[{monitor, pending_driver}]), - ?line ok = receive _ -> false after 0 -> ok end, - ?line Port ! {self(), close}, - ?line ok = receive {Port,closed} -> ok after 1000 -> false end, - ?line 1 = erl_ddll:info(echo_drv, port_count), - ?line Port2 ! {self(), close}, - ?line ok = receive {Port2,closed} -> ok after 1000 -> false end, - ?line ok = receive {'DOWN', Ref, driver, echo_drv, unloaded} -> ok after 1000 -> false end, - ?line test_server:timetrap_cancel(Dog), + Path = proplists:get_value(data_dir, Config), + erl_ddll:try_load(Path, echo_drv, []), + erl_ddll:try_load(Path, echo_drv, []), + Port = open_port({spawn, echo_drv}, [eof]), + 1 = erl_ddll:info(echo_drv, port_count), + Port2 = open_port({spawn, echo_drv}, [eof]), + 2 = erl_ddll:info(echo_drv, port_count), + {ok,pending_process} = erl_ddll:try_unload(echo_drv,[{monitor, pending_driver}]), + {ok,pending_driver,Ref} = erl_ddll:try_unload(echo_drv,[{monitor, pending_driver}]), + ok = receive _ -> false after 0 -> ok end, + Port ! {self(), close}, + ok = receive {Port,closed} -> ok after 1000 -> false end, + 1 = erl_ddll:info(echo_drv, port_count), + Port2 ! {self(), close}, + ok = receive {Port2,closed} -> ok after 1000 -> false end, + ok = receive {'DOWN', Ref, driver, echo_drv, unloaded} -> ok after 1000 -> false end, ok. -unload_due_to_process_exit(suite) -> - []; -unload_due_to_process_exit(doc) -> - ["Check that the driver with ports is unloaded on process exit"]; +%% Check that the driver with ports is unloaded on process exit unload_due_to_process_exit(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line Parent = self(), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), - receive X -> Parent ! {got,X} end - end, - ?line Pid = spawn(fun() -> - receive go -> ok end, - {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), - spawn(F3), - receive go -> ok end, - _Port = open_port({spawn, echo_drv}, [eof]), - _Port2 = open_port({spawn, echo_drv}, [eof]), - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), + Path = proplists:get_value(data_dir, Config), + Parent = self(), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), + receive X -> Parent ! {got,X} end + end, + Pid = spawn(fun() -> + receive go -> ok end, + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), + spawn(F3), + receive go -> ok end, + _Port = open_port({spawn, echo_drv}, [eof]), + _Port2 = open_port({spawn, echo_drv}, [eof]), + exit(banan) + end), + Ref = erlang:monitor(process,Pid), Pid ! go, - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, Pid ! go, - ?line ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, - ?line ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, - ?line test_server:timetrap_cancel(Dog), + ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, + ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, ok. -no_unload_due_to_process_exit(suite) -> - []; -no_unload_due_to_process_exit(doc) -> - ["Check that a driver with driver loaded in another process is not unloaded on process exit"]; +%% Check that a driver with driver loaded in another process is not unloaded on process exit no_unload_due_to_process_exit(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line Parent = self(), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), - receive X -> Parent ! {got,X} end - end, - ?line Pid = spawn(fun() -> - receive go -> ok end, - {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), - spawn(F3), - receive go -> ok end, - _Port = open_port({spawn, echo_drv}, [eof]), - _Port2 = open_port({spawn, echo_drv}, [eof]), - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), + Path = proplists:get_value(data_dir, Config), + Parent = self(), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), + receive X -> Parent ! {got,X} end + end, + Pid = spawn(fun() -> + receive go -> ok end, + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), + spawn(F3), + receive go -> ok end, + _Port = open_port({spawn, echo_drv}, [eof]), + _Port2 = open_port({spawn, echo_drv}, [eof]), + exit(banan) + end), + Ref = erlang:monitor(process,Pid), Pid ! go, - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, - ?line {ok, already_loaded} = erl_ddll:try_load(Path, echo_drv, []), + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, + {ok, already_loaded} = erl_ddll:try_load(Path, echo_drv, []), Pid ! go, - ?line ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, - ?line ok = receive X -> {error, X} after 300 -> ok end, - ?line ok = unload_expect_fast(echo_drv,[]), - ?line ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, - ?line test_server:timetrap_cancel(Dog), + ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, + ok = receive X -> {error, X} after 300 -> ok end, + ok = unload_expect_fast(echo_drv,[]), + ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, ok. -no_unload_due_to_process_exit_2(suite) -> - []; -no_unload_due_to_process_exit_2(doc) -> - ["Check that a driver with open ports in another process is not unloaded on process exit"]; +%% Check that a driver with open ports in another process is not unloaded on process exit no_unload_due_to_process_exit_2(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line Parent = self(), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), - receive X -> Parent ! {got,X} end - end, - ?line Pid = spawn(fun() -> - receive go -> ok end, - {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), - spawn(F3), - receive go -> ok end, - _Port = open_port({spawn, echo_drv}, [eof]), - _Port2 = open_port({spawn, echo_drv}, [eof]), - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), + Path = proplists:get_value(data_dir, Config), + Parent = self(), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), + receive X -> Parent ! {got,X} end + end, + Pid = spawn(fun() -> + receive go -> ok end, + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), + spawn(F3), + receive go -> ok end, + _Port = open_port({spawn, echo_drv}, [eof]), + _Port2 = open_port({spawn, echo_drv}, [eof]), + exit(banan) + end), + Ref = erlang:monitor(process,Pid), Pid ! go, - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, - ?line Port = open_port({spawn, echo_drv}, [eof]), + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, + Port = open_port({spawn, echo_drv}, [eof]), Pid ! go, - ?line ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, - ?line ok = receive X -> {error, X} after 300 -> ok end, - ?line erlang:port_close(Port), - ?line ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, - ?line test_server:timetrap_cancel(Dog), + ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, + ok = receive X -> {error, X} after 300 -> ok end, + erlang:port_close(Port), + ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, ok. -unload_reload_thingie(suite) -> - []; -unload_reload_thingie(doc) -> - ["Check delayed unload and reload"]; +%% Check delayed unload and reload unload_reload_thingie(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line Parent = self(), - ?line {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded_only}), - receive X -> Parent ! {got,X} end - end, - ?line Pid = spawn(fun() -> - receive go -> ok end, - _Port = open_port({spawn, echo_drv}, [eof]), - spawn(F3), - receive go -> ok end, - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), + Path = proplists:get_value(data_dir, Config), + Parent = self(), + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded_only}), + receive X -> Parent ! {got,X} end + end, + Pid = spawn(fun() -> + receive go -> ok end, + _Port = open_port({spawn, echo_drv}, [eof]), + spawn(F3), + receive go -> ok end, + exit(banan) + end), + Ref = erlang:monitor(process,Pid), + Pid ! go, + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, + {ok,pending_driver,Ref3} = erl_ddll:try_unload(echo_drv,[{monitor,pending}]), + Ref4 = erl_ddll:monitor(driver,{echo_drv,loaded}), + ok = receive {'DOWN',Ref4, driver,echo_drv,load_cancelled} -> ok after 1000 -> false end, + {ok,already_loaded} = erl_ddll:try_load(Path, echo_drv, []), + ok = receive {'UP',Ref3, driver,echo_drv,unload_cancelled} -> ok after 1000 -> false end, Pid ! go, - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, - ?line {ok,pending_driver,Ref3} = erl_ddll:try_unload(echo_drv,[{monitor,pending}]), - ?line Ref4 = erl_ddll:monitor(driver,{echo_drv,loaded}), - ?line ok = receive {'DOWN',Ref4, driver,echo_drv,load_cancelled} -> ok after 1000 -> false end, - ?line {ok,already_loaded} = erl_ddll:try_load(Path, echo_drv, []), - ?line ok = receive {'UP',Ref3, driver,echo_drv,unload_cancelled} -> ok after 1000 -> false end, - ?line Pid ! go, - ?line ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, - ?line [{Parent,1}] = erl_ddll:info(echo_drv, processes), - ?line 0 = erl_ddll:info(echo_drv, port_count), - ?line ok = unload_expect_fast(echo_drv,[{monitor,pending}]), - ?line ok = receive - {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok - after 300 -> error - end, - ?line ok = receive X -> {error, X} after 300 -> ok end, - ?line test_server:timetrap_cancel(Dog), + ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, + [{Parent,1}] = erl_ddll:info(echo_drv, processes), + 0 = erl_ddll:info(echo_drv, port_count), + ok = unload_expect_fast(echo_drv,[{monitor,pending}]), + ok = receive + {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok + after 300 -> error + end, + ok = receive X -> {error, X} after 300 -> ok end, ok. -unload_reload_thingie_2(suite) -> - []; -unload_reload_thingie_2(doc) -> - ["Check delayed unload and reload"]; +%% Check delayed unload and reload unload_reload_thingie_2(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line Parent = self(), - ?line {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded_only}), - receive X -> Parent ! {got,X} end - end, - ?line Pid = spawn(fun() -> - receive go -> ok end, - _Port = open_port({spawn, echo_drv}, [eof]), - spawn(F3), - receive go -> ok end, - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), + Path = proplists:get_value(data_dir, Config), + Parent = self(), + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded_only}), + receive X -> Parent ! {got,X} end + end, + Pid = spawn(fun() -> + receive go -> ok end, + _Port = open_port({spawn, echo_drv}, [eof]), + spawn(F3), + receive go -> ok end, + exit(banan) + end), + Ref = erlang:monitor(process,Pid), Pid ! go, - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, - ?line {ok,pending_driver,Ref3} = erl_ddll:try_load(Path,echo_drv,[{monitor,pending_driver},{reload,pending_driver}]), - ?line Ref4 = erl_ddll:monitor(driver,{echo_drv,unloaded}), - ?line Pid ! go, - ?line ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, - ?line ok = receive {'DOWN',Ref4, driver,echo_drv,unloaded} -> ok after 1000 -> false end, - ?line ok = receive {'UP',Ref3, driver,echo_drv,loaded} -> ok after 1000 -> false end, - ?line [{Parent,1}] = erl_ddll:info(echo_drv, processes), - ?line 0 = erl_ddll:info(echo_drv, port_count), - ?line ok = receive - {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok - after 300 -> error - end, - ?line ok = unload_expect_fast(echo_drv,[{monitor,pending}]), - ?line ok = receive X -> {error, X} after 300 -> ok end, - ?line test_server:timetrap_cancel(Dog), + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, + {ok,pending_driver,Ref3} = erl_ddll:try_load(Path, echo_drv, + [{monitor,pending_driver},{reload,pending_driver}]), + Ref4 = erl_ddll:monitor(driver,{echo_drv,unloaded}), + Pid ! go, + ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, + ok = receive {'DOWN',Ref4, driver,echo_drv,unloaded} -> ok after 1000 -> false end, + ok = receive {'UP',Ref3, driver,echo_drv,loaded} -> ok after 1000 -> false end, + [{Parent,1}] = erl_ddll:info(echo_drv, processes), + 0 = erl_ddll:info(echo_drv, port_count), + ok = receive + {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok + after 300 -> error + end, + ok = unload_expect_fast(echo_drv,[{monitor,pending}]), + ok = receive X -> {error, X} after 300 -> ok end, ok. -unload_reload_thingie_3(suite) -> - []; -unload_reload_thingie_3(doc) -> - ["Check delayed unload and reload failure"]; +%% Check delayed unload and reload failure unload_reload_thingie_3(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line Parent = self(), - ?line {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), - receive X -> Parent ! {got,X} end - end, - ?line Pid = spawn(fun() -> - receive go -> ok end, - _Port = open_port({spawn, echo_drv}, [eof]), - spawn(F3), - receive go -> ok end, - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), + Path = proplists:get_value(data_dir, Config), + Parent = self(), + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), + receive X -> Parent ! {got,X} end + end, + Pid = spawn(fun() -> + receive go -> ok end, + _Port = open_port({spawn, echo_drv}, [eof]), + spawn(F3), + receive go -> ok end, + exit(banan) + end), + Ref = erlang:monitor(process,Pid), Pid ! go, - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, - ?line {ok,pending_driver,Ref3} = erl_ddll:try_load(filename:join([Path,"skrumpf"]),echo_drv,[{monitor,pending_driver},{reload,pending_driver}]), - ?line Ref4 = erl_ddll:monitor(driver,{echo_drv,unloaded}), - ?line Pid ! go, - ?line ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, - ?line ok = receive - {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok - after 300 -> error - end, - ?line ok = receive {'DOWN',Ref4,driver,echo_drv,unloaded} -> ok after 300 -> false end, - ?line ok = receive - {'DOWN',Ref3, driver,echo_drv,{load_failure,_}} -> ok - after 1000 -> false - end, - ?line {'EXIT',_} = (catch erl_ddll:info(echo_drv, port_count)), - ?line {error, not_loaded} = erl_ddll:try_unload(echo_drv,[{monitor,pending}]), - ?line ok = receive X -> {error, X} after 300 -> ok end, - ?line test_server:timetrap_cancel(Dog), + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, + {ok,pending_driver,Ref3} = erl_ddll:try_load(filename:join([Path,"skrumpf"]), echo_drv, + [{monitor,pending_driver},{reload,pending_driver}]), + Ref4 = erl_ddll:monitor(driver,{echo_drv,unloaded}), + Pid ! go, + ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, + ok = receive + {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok + after 300 -> error + end, + ok = receive {'DOWN',Ref4,driver,echo_drv,unloaded} -> ok after 300 -> false end, + ok = receive + {'DOWN',Ref3, driver,echo_drv,{load_failure,_}} -> ok + after 1000 -> false + end, + {'EXIT',_} = (catch erl_ddll:info(echo_drv, port_count)), + {error, not_loaded} = erl_ddll:try_unload(echo_drv,[{monitor,pending}]), + ok = receive X -> {error, X} after 300 -> ok end, ok. -reload_pending(suite) -> []; -reload_pending(doc) -> ["Reload a driver that is pending on a user"]; +%% Reload a driver that is pending on a user reload_pending(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line Parent = self(), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), - receive X -> Parent ! {got,X} end - end, - ?line Pid = spawn(fun() -> - receive go -> ok end, - {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), - spawn(F3), - receive go -> ok end, - _Port = open_port({spawn, echo_drv}, [eof]), - _Port2 = open_port({spawn, echo_drv}, [eof]), - Parent ! opened, - receive go -> ok end, - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), + Path = proplists:get_value(data_dir, Config), + Parent = self(), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), + receive X -> Parent ! {got,X} end + end, + Pid = spawn(fun() -> + receive go -> ok end, + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), + spawn(F3), + receive go -> ok end, + _Port = open_port({spawn, echo_drv}, [eof]), + _Port2 = open_port({spawn, echo_drv}, [eof]), + Parent ! opened, + receive go -> ok end, + exit(banan) + end), + Ref = erlang:monitor(process,Pid), Pid ! go, - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, - ?line {ok, already_loaded} = erl_ddll:try_load(Path, echo_drv, []), - ?line Port = open_port({spawn, echo_drv}, [eof]), + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, + {ok, already_loaded} = erl_ddll:try_load(Path, echo_drv, []), + Port = open_port({spawn, echo_drv}, [eof]), Pid ! go, - ?line receive opened -> ok end, - ?line {error, pending_process} = - erl_ddll:try_load(Path, echo_drv, - [{reload,pending_driver}, - {monitor,pending_driver}]), - ?line {ok, pending_process, Ref3} = - erl_ddll:try_load(Path, echo_drv, - [{reload,pending}, - {monitor,pending}]), - ?line ok = receive X -> {error, X} after 300 -> ok end, + receive opened -> ok end, + {error, pending_process} = + erl_ddll:try_load(Path, echo_drv, + [{reload,pending_driver}, + {monitor,pending_driver}]), + {ok, pending_process, Ref3} = + erl_ddll:try_load(Path, echo_drv, + [{reload,pending}, + {monitor,pending}]), + ok = receive X -> {error, X} after 300 -> ok end, Pid ! go, - ?line ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, - ?line ok = receive Y -> {error, Y} after 300 -> ok end, - ?line erlang:port_close(Port), - ?line ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, - ?line ok = receive {'UP', Ref3, driver, echo_drv, loaded} -> ok after 300 -> error end, + ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, + ok = receive Y -> {error, Y} after 300 -> ok end, + erlang:port_close(Port), + ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, + ok = receive {'UP', Ref3, driver, echo_drv, loaded} -> ok after 300 -> error end, [{Parent,1}] = erl_ddll:info(echo_drv,processes), - ?line ok = receive Z -> {error, Z} after 300 -> ok end, - ?line test_server:timetrap_cancel(Dog), + ok = receive Z -> {error, Z} after 300 -> ok end, ok. -load_fail_init(suite) -> []; -load_fail_init(doc) -> ["Tests failure in the init in driver struct."]; +%% Tests failure in the init in driver struct. load_fail_init(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line PathFailing = ?config(priv_dir, Config), - ?line [_|_] = AllFailInits = filelib:wildcard("echo_drv_fail_init.*",Path), - ?line lists:foreach(fun(Name) -> - Src = filename:join([Path,Name]), - Ext = filename:extension(Name), - Dst =filename:join([PathFailing,"echo_drv"++Ext]), - file:delete(Dst), - {ok,_} = file:copy(Src,Dst) - end, - AllFailInits), - ?line [_|_] = filelib:wildcard("echo_drv.*",PathFailing), - ?line {error, driver_init_failed} = erl_ddll:try_load(PathFailing, - echo_drv, - [{monitor,pending}]), - ?line ok = receive XX -> - {unexpected,XX} - after 300 -> - ok - end, - ?line test_server:timetrap_cancel(Dog), + Path = proplists:get_value(data_dir, Config), + PathFailing = proplists:get_value(priv_dir, Config), + [_|_] = AllFailInits = filelib:wildcard("echo_drv_fail_init.*",Path), + lists:foreach(fun(Name) -> + Src = filename:join([Path,Name]), + Ext = filename:extension(Name), + Dst =filename:join([PathFailing,"echo_drv"++Ext]), + file:delete(Dst), + {ok,_} = file:copy(Src,Dst) + end, + AllFailInits), + [_|_] = filelib:wildcard("echo_drv.*",PathFailing), + {error, driver_init_failed} = erl_ddll:try_load(PathFailing, + echo_drv, + [{monitor,pending}]), + ok = receive XX -> + {unexpected,XX} + after 300 -> + ok + end, ok. -reload_pending_fail_init(suite) -> []; -reload_pending_fail_init(doc) -> ["Reload a driver that is pending but init fails"]; +%% Reload a driver that is pending but init fails reload_pending_fail_init(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line PathFailing = ?config(priv_dir, Config), - ?line [_|_] = AllFailInits = filelib:wildcard("echo_drv_fail_init.*",Path), - ?line lists:foreach(fun(Name) -> - Src = filename:join([Path,Name]), - Ext = filename:extension(Name), - Dst =filename:join([PathFailing,"echo_drv"++Ext]), - file:delete(Dst), - {ok,_} = file:copy(Src,Dst) - end, - AllFailInits), - ?line [_|_] = filelib:wildcard("echo_drv.*",PathFailing), - ?line Parent = self(), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), - receive X -> Parent ! {got,X} end - end, - ?line Pid = spawn(fun() -> - receive go -> ok end, - {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), - spawn(F3), - receive go -> ok end, - _Port = open_port({spawn, echo_drv}, [eof]), - _Port2 = open_port({spawn, echo_drv}, [eof]), - Parent ! opened, - receive go -> ok end, - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), + Path = proplists:get_value(data_dir, Config), + PathFailing = proplists:get_value(priv_dir, Config), + [_|_] = AllFailInits = filelib:wildcard("echo_drv_fail_init.*",Path), + lists:foreach(fun(Name) -> + Src = filename:join([Path,Name]), + Ext = filename:extension(Name), + Dst =filename:join([PathFailing,"echo_drv"++Ext]), + file:delete(Dst), + {ok,_} = file:copy(Src,Dst) + end, + AllFailInits), + [_|_] = filelib:wildcard("echo_drv.*",PathFailing), + Parent = self(), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), + receive X -> Parent ! {got,X} end + end, + Pid = spawn(fun() -> + receive go -> ok end, + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), + spawn(F3), + receive go -> ok end, + _Port = open_port({spawn, echo_drv}, [eof]), + _Port2 = open_port({spawn, echo_drv}, [eof]), + Parent ! opened, + receive go -> ok end, + exit(banan) + end), + Ref = erlang:monitor(process,Pid), Pid ! go, - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, - ?line {ok, already_loaded} = erl_ddll:try_load(Path, echo_drv, []), - ?line Port = open_port({spawn, echo_drv}, [eof]), + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, + {ok, already_loaded} = erl_ddll:try_load(Path, echo_drv, []), + Port = open_port({spawn, echo_drv}, [eof]), Pid ! go, - ?line receive opened -> ok end, - ?line {ok, pending_process, Ref3} = - erl_ddll:try_load(PathFailing, echo_drv, - [{reload,pending}, - {monitor,pending}]), - ?line ok = receive X -> {error, X} after 300 -> ok end, + receive opened -> ok end, + {ok, pending_process, Ref3} = + erl_ddll:try_load(PathFailing, echo_drv, + [{reload,pending}, + {monitor,pending}]), + ok = receive X -> {error, X} after 300 -> ok end, Pid ! go, - ?line ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, - ?line ok = receive Y -> {error, Y} after 300 -> ok end, - ?line erlang:port_close(Port), - ?line ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, - ?line ok = receive {'DOWN', Ref3, driver, echo_drv, {load_failure,driver_init_failed}} -> ok after 300 -> error end, - ?line {'EXIT',{badarg,_}} = (catch erl_ddll:info(echo_drv,processes)), - - ?line ok = receive Z -> {error, Z} after 300 -> ok end, - ?line test_server:timetrap_cancel(Dog), + ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, + ok = receive Y -> {error, Y} after 300 -> ok end, + erlang:port_close(Port), + ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, + ok = receive {'DOWN', Ref3, driver, echo_drv, {load_failure,driver_init_failed}} -> ok after 300 -> error end, + {'EXIT',{badarg,_}} = (catch erl_ddll:info(echo_drv,processes)), + + ok = receive Z -> {error, Z} after 300 -> ok end, ok. -reload_pending_kill(suite) -> []; -reload_pending_kill(doc) -> ["Reload a driver with kill_ports option " - "that is pending on a user"]; +%% Reload a driver with kill_ports option that is pending on a user reload_pending_kill(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line OldFlag = process_flag(trap_exit,true), - ?line Path = ?config(data_dir, Config), - ?line Parent = self(), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), - receive X -> Parent ! {got,X} end - end, - ?line Pid = spawn(fun() -> - process_flag(trap_exit,true), - receive go -> ok end, - {ok, loaded} = erl_ddll:try_load(Path, echo_drv, [{driver_options,[kill_ports]}]), - spawn(F3), - receive go -> ok end, - Port = open_port({spawn, echo_drv}, [eof]), - Port2 = open_port({spawn, echo_drv}, [eof]), - Parent ! opened, - receive go -> ok end, - receive - {'EXIT', Port2, driver_unloaded} -> - Parent ! first_exit - end, - receive - {'EXIT', Port, driver_unloaded} -> - Parent ! second_exit - end, - receive go -> ok end, - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), + OldFlag = process_flag(trap_exit,true), + Path = proplists:get_value(data_dir, Config), + Parent = self(), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), + receive X -> Parent ! {got,X} end + end, + Pid = spawn(fun() -> + process_flag(trap_exit,true), + receive go -> ok end, + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, [{driver_options,[kill_ports]}]), + spawn(F3), + receive go -> ok end, + Port = open_port({spawn, echo_drv}, [eof]), + Port2 = open_port({spawn, echo_drv}, [eof]), + Parent ! opened, + receive go -> ok end, + receive + {'EXIT', Port2, driver_unloaded} -> + Parent ! first_exit + end, + receive + {'EXIT', Port, driver_unloaded} -> + Parent ! second_exit + end, + receive go -> ok end, + exit(banan) + end), + Ref = erlang:monitor(process,Pid), Pid ! go, - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, - ?line {ok, already_loaded} = erl_ddll:try_load(Path, echo_drv, [{driver_options,[kill_ports]}]), - ?line {error,inconsistent} = erl_ddll:try_load(Path, echo_drv, []), - ?line Port = open_port({spawn, echo_drv}, [eof]), + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, + {ok, already_loaded} = erl_ddll:try_load(Path, echo_drv, [{driver_options,[kill_ports]}]), + {error,inconsistent} = erl_ddll:try_load(Path, echo_drv, []), + Port = open_port({spawn, echo_drv}, [eof]), Pid ! go, - ?line receive opened -> ok end, - ?line {error, pending_process} = - erl_ddll:try_load(Path, echo_drv, - [{driver_options,[kill_ports]}, - {reload,pending_driver}, - {monitor,pending_driver}]), - ?line {ok, pending_process, Ref3} = - erl_ddll:try_load(Path, echo_drv, - [{driver_options,[kill_ports]}, - {reload,pending}, - {monitor,pending}]), - ?line ok = receive - {'EXIT', Port, driver_unloaded} -> - ok - after 300 -> error - end, + receive opened -> ok end, + {error, pending_process} = + erl_ddll:try_load(Path, echo_drv, + [{driver_options,[kill_ports]}, + {reload,pending_driver}, + {monitor,pending_driver}]), + {ok, pending_process, Ref3} = + erl_ddll:try_load(Path, echo_drv, + [{driver_options,[kill_ports]}, + {reload,pending}, + {monitor,pending}]), + ok = receive + {'EXIT', Port, driver_unloaded} -> + ok + after 300 -> error + end, Pid ! go, - ?line ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, - ?line ok = receive {'UP', Ref3, driver, echo_drv, loaded} -> ok after 300 -> error end, - ?line [_,_] = erl_ddll:info(echo_drv,processes), - ?line ok = receive first_exit -> ok after 300 -> error end, - ?line ok = receive second_exit -> ok after 300 -> error end, - ?line 0 = erl_ddll:info(echo_drv,port_count), - ?line ok = receive X -> {error, X} after 300 -> ok end, + ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, + ok = receive {'UP', Ref3, driver, echo_drv, loaded} -> ok after 300 -> error end, + [_,_] = erl_ddll:info(echo_drv,processes), + ok = receive first_exit -> ok after 300 -> error end, + ok = receive second_exit -> ok after 300 -> error end, + 0 = erl_ddll:info(echo_drv,port_count), + ok = receive X -> {error, X} after 300 -> ok end, Pid ! go, - ?line ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, - ?line ok = receive Y -> {error, Y} after 300 -> ok end, - ?line Port2 = open_port({spawn, echo_drv}, [eof]), - ?line true = is_port(Port2), + ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, + ok = receive Y -> {error, Y} after 300 -> ok end, + Port2 = open_port({spawn, echo_drv}, [eof]), + true = is_port(Port2), + [{Parent,1}] = erl_ddll:info(echo_drv,processes), + 1 = erl_ddll:info(echo_drv,port_count), + erlang:port_close(Port2), + ok = receive {'EXIT', Port2, normal} -> ok after 300 -> error end, + 0 = erl_ddll:info(echo_drv,port_count), [{Parent,1}] = erl_ddll:info(echo_drv,processes), - ?line 1 = erl_ddll:info(echo_drv,port_count), - ?line erlang:port_close(Port2), - ?line ok = receive {'EXIT', Port2, normal} -> ok after 300 -> error end, - ?line 0 = erl_ddll:info(echo_drv,port_count), - ?line [{Parent,1}] = erl_ddll:info(echo_drv,processes), - ?line Port3 = open_port({spawn, echo_drv}, [eof]), - ?line {ok, pending_driver, Ref4} = - erl_ddll:try_unload(echo_drv,[{monitor,pending_driver}]), - ?line ok = receive - {'EXIT', Port3, driver_unloaded} -> - ok - after 300 -> error - end, - ?line ok = receive {'DOWN', Ref4, driver, echo_drv, unloaded} -> ok after 300 -> error end, + Port3 = open_port({spawn, echo_drv}, [eof]), + {ok, pending_driver, Ref4} = + erl_ddll:try_unload(echo_drv,[{monitor,pending_driver}]), + ok = receive + {'EXIT', Port3, driver_unloaded} -> + ok + after 300 -> error + end, + ok = receive {'DOWN', Ref4, driver, echo_drv, unloaded} -> ok after 300 -> error end, io:format("Port = ~w, Port2 = ~w, Port3 = ~w~n",[Port,Port2,Port3]), - ?line ok = receive Z -> {error, Z} after 300 -> ok end, - ?line process_flag(trap_exit,OldFlag), - ?line test_server:timetrap_cancel(Dog), + ok = receive Z -> {error, Z} after 300 -> ok end, + process_flag(trap_exit,OldFlag), ok. -more_error_codes(suite) -> - []; -more_error_codes(doc) -> - ["Some more error code checking"]; +%% Some more error code checking more_error_codes(Config) when is_list(Config) -> - ?line {error,Err} = erl_ddll:try_load("./echo_dr",echo_dr,[]), - ?line true = is_list(erl_ddll:format_error(Err)), - ?line true = is_list(erl_ddll:format_error(not_loaded)), + {error,Err} = erl_ddll:try_load("./echo_dr",echo_dr,[]), + true = is_list(erl_ddll:format_error(Err)), + true = is_list(erl_ddll:format_error(not_loaded)), ok. -forced_port_killing(suite) -> - []; -forced_port_killing(doc) -> - ["Check kill_ports option to try_unload "]; +%% Check kill_ports option to try_unload forced_port_killing(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line OldFlag=process_flag(trap_exit,true), - ?line Parent = self(), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), - receive X -> Parent ! {got,X} end - end, - ?line {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), - ?line spawn(F3), - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, - ?line Port = open_port({spawn, echo_drv}, [eof]), - ?line Port2 = open_port({spawn, echo_drv}, [eof]), - ?line {ok, pending_driver, Ref1} = - erl_ddll:try_unload(echo_drv,[{monitor,pending_driver},kill_ports]), - ?line ok = receive - {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok - after 300 -> error - end, - ?line ok = receive {'EXIT',Port,driver_unloaded} -> ok after 300 -> false end, - ?line ok = receive {'EXIT',Port2,driver_unloaded} -> ok after 300 -> false end, - ?line ok = receive {'DOWN',Ref1, driver, echo_drv, unloaded} -> ok after 300 -> false end, - ?line process_flag(trap_exit,OldFlag), - ?line ok = receive X -> {error, X} after 300 -> ok end, - ?line test_server:timetrap_cancel(Dog), + Path = proplists:get_value(data_dir, Config), + OldFlag=process_flag(trap_exit,true), + Parent = self(), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), + receive X -> Parent ! {got,X} end + end, + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, []), + spawn(F3), + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, + Port = open_port({spawn, echo_drv}, [eof]), + Port2 = open_port({spawn, echo_drv}, [eof]), + {ok, pending_driver, Ref1} = + erl_ddll:try_unload(echo_drv,[{monitor,pending_driver},kill_ports]), + ok = receive + {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok + after 300 -> error + end, + ok = receive {'EXIT',Port,driver_unloaded} -> ok after 300 -> false end, + ok = receive {'EXIT',Port2,driver_unloaded} -> ok after 300 -> false end, + ok = receive {'DOWN',Ref1, driver, echo_drv, unloaded} -> ok after 300 -> false end, + process_flag(trap_exit,OldFlag), + ok = receive X -> {error, X} after 300 -> ok end, ok. -no_trap_exit_and_kill_ports(suite) -> - []; -no_trap_exit_and_kill_ports(doc) -> - ["Check delayed unload and reload with no trap_exit"]; +%% Check delayed unload and reload with no trap_exit no_trap_exit_and_kill_ports(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line Parent = self(), - ?line OldFlag=process_flag(trap_exit,true), - ?line F3 = fun() -> - Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), - receive X -> Parent ! {got,X} end - end, - ?line Pid = spawn(fun() -> - process_flag(trap_exit,false), - receive go -> ok end, - {ok, loaded} = erl_ddll:try_load(Path, echo_drv, - [{driver_options,[kill_ports]}]), - spawn(F3), - receive go -> ok end, - _Port = open_port({spawn, echo_drv}, [eof]), - _Port2 = open_port({spawn, echo_drv}, [eof]), - exit(banan) - end), - ?line Ref = erlang:monitor(process,Pid), + Path = proplists:get_value(data_dir, Config), + Parent = self(), + OldFlag=process_flag(trap_exit,true), + F3 = fun() -> + Parent ! erl_ddll:monitor(driver,{echo_drv,unloaded}), + receive X -> Parent ! {got,X} end + end, + Pid = spawn(fun() -> + process_flag(trap_exit,false), + receive go -> ok end, + {ok, loaded} = erl_ddll:try_load(Path, echo_drv, + [{driver_options,[kill_ports]}]), + spawn(F3), + receive go -> ok end, + _Port = open_port({spawn, echo_drv}, [eof]), + _Port2 = open_port({spawn, echo_drv}, [eof]), + exit(banan) + end), + Ref = erlang:monitor(process,Pid), Pid ! go, - ?line {ok,Ref2} = receive - R when is_reference(R) -> {ok,R}; - Other -> {error, Other} - after 500 -> {error, timeout} - end, - ?line {error, inconsistent} = erl_ddll:try_load(Path, echo_drv, []), - ?line MyPort = open_port({spawn, echo_drv}, [eof]), + {ok,Ref2} = receive + R when is_reference(R) -> {ok,R}; + Other -> {error, Other} + after 500 -> {error, timeout} + end, + {error, inconsistent} = erl_ddll:try_load(Path, echo_drv, []), + MyPort = open_port({spawn, echo_drv}, [eof]), Pid ! go, - ?line ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, - ?line ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, - ?line ok = receive {'EXIT',MyPort,driver_unloaded} -> ok after 300 -> error end, - ?line process_flag(trap_exit,OldFlag), - ?line test_server:timetrap_cancel(Dog), + ok = receive {'DOWN', Ref, process, Pid, banan} -> ok after 300 -> error end, + ok = receive {got,{'DOWN', Ref2, driver, echo_drv, unloaded}} -> ok after 300 -> error end, + ok = receive {'EXIT',MyPort,driver_unloaded} -> ok after 300 -> error end, + process_flag(trap_exit,OldFlag), ok. -monitor_demonitor(suite) -> - []; -monitor_demonitor(doc) -> - ["Check monitor and demonitor of drivers"]; +%% Check monitor and demonitor of drivers monitor_demonitor(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line erl_ddll:try_load(Path, echo_drv, []), - ?line Ref = erl_ddll:monitor(driver,{echo_drv,unloaded}), - ?line Self = self(), - ?line [{Self,1}] = erl_ddll:info(echo_drv,awaiting_unload), - ?line true = erl_ddll:demonitor(Ref), - ?line [] = erl_ddll:info(echo_drv,awaiting_unload), - ?line erl_ddll:try_unload(echo_drv,[]), - ?line ok = receive _ -> error after 300 -> ok end, - ?line test_server:timetrap_cancel(Dog), + Path = proplists:get_value(data_dir, Config), + erl_ddll:try_load(Path, echo_drv, []), + Ref = erl_ddll:monitor(driver,{echo_drv,unloaded}), + Self = self(), + [{Self,1}] = erl_ddll:info(echo_drv,awaiting_unload), + true = erl_ddll:demonitor(Ref), + [] = erl_ddll:info(echo_drv,awaiting_unload), + erl_ddll:try_unload(echo_drv,[]), + ok = receive _ -> error after 300 -> ok end, ok. -monitor_demonitor_load(suite) -> - []; -monitor_demonitor_load(doc) -> - ["Check monitor/demonitor of driver loading"]; +%% Check monitor/demonitor of driver loading monitor_demonitor_load(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line {ok,loaded} = erl_ddll:try_load(Path, echo_drv, []), - ?line Port = open_port({spawn, echo_drv}, [eof]), - ?line Ref = erl_ddll:monitor(driver,{echo_drv,loaded}), - ?line ok = receive {'UP',Ref,driver,echo_drv,loaded} -> ok after 500 -> error end, - ?line {ok, pending_driver} = erl_ddll:try_unload(echo_drv,[]), - ?line Ref2 = erl_ddll:monitor(driver,{echo_drv,loaded}), - ?line ok = receive {'DOWN',Ref2,driver,echo_drv,load_cancelled} -> ok after 0 -> error end, - ?line {ok,already_loaded} = erl_ddll:try_load(Path, echo_drv, []), - ?line {ok, pending_driver} = - erl_ddll:try_load(Path, echo_drv, [{reload,pending_driver}]), - ?line Ref3 = erl_ddll:monitor(driver,{echo_drv,loaded}), - ?line Ref4 = erl_ddll:monitor(driver,{echo_drv,unloaded}), - ?line ok = receive _ -> error after 300 -> ok end, - ?line Self = self(), - ?line [{Self,1}] = erl_ddll:info(echo_drv,awaiting_load), - ?line true = erl_ddll:demonitor(Ref3), - ?line [] = erl_ddll:info(echo_drv,awaiting_load), - ?line erlang:port_close(Port), - ?line ok = receive {'DOWN',Ref4,driver,echo_drv,unloaded} -> ok after 300 -> error end, - ?line ok = receive _ -> error after 300 -> ok end, - ?line ok = unload_expect_fast(echo_drv,[]), - ?line test_server:timetrap_cancel(Dog), + Path = proplists:get_value(data_dir, Config), + {ok,loaded} = erl_ddll:try_load(Path, echo_drv, []), + Port = open_port({spawn, echo_drv}, [eof]), + Ref = erl_ddll:monitor(driver,{echo_drv,loaded}), + ok = receive {'UP',Ref,driver,echo_drv,loaded} -> ok after 500 -> error end, + {ok, pending_driver} = erl_ddll:try_unload(echo_drv,[]), + Ref2 = erl_ddll:monitor(driver,{echo_drv,loaded}), + ok = receive {'DOWN',Ref2,driver,echo_drv,load_cancelled} -> ok after 0 -> error end, + {ok,already_loaded} = erl_ddll:try_load(Path, echo_drv, []), + {ok, pending_driver} = + erl_ddll:try_load(Path, echo_drv, [{reload,pending_driver}]), + Ref3 = erl_ddll:monitor(driver,{echo_drv,loaded}), + Ref4 = erl_ddll:monitor(driver,{echo_drv,unloaded}), + ok = receive _ -> error after 300 -> ok end, + Self = self(), + [{Self,1}] = erl_ddll:info(echo_drv,awaiting_load), + true = erl_ddll:demonitor(Ref3), + [] = erl_ddll:info(echo_drv,awaiting_load), + erlang:port_close(Port), + ok = receive {'DOWN',Ref4,driver,echo_drv,unloaded} -> ok after 300 -> error end, + ok = receive _ -> error after 300 -> ok end, + ok = unload_expect_fast(echo_drv,[]), ok. -new_interface(suite) -> - []; -new_interface(doc) -> - ["Test the new load/unload/reload interface"]; +%% Test the new load/unload/reload interface new_interface(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), % Typical scenario - ?line ok = erl_ddll:load(Path, echo_drv), - ?line Port = open_port({spawn, echo_drv}, [eof]), - ?line ok = erl_ddll:unload(echo_drv), - ?line Port ! {self(), {command, "text"}}, - ?line ok = receive - {Port, {data, "text"}} -> ok; - _ -> error - after - 1000 -> error - end, - ?line Ref = erl_ddll:monitor(driver,{echo_drv,unloaded}), - ?line ok = receive X -> {error, X} after 300 -> ok end, - ?line erlang:port_close(Port), - ?line ok = receive {'DOWN', Ref, driver, echo_drv, unloaded} -> ok after 300 -> error end, + ok = erl_ddll:load(Path, echo_drv), + Port = open_port({spawn, echo_drv}, [eof]), + ok = erl_ddll:unload(echo_drv), + Port ! {self(), {command, "text"}}, + ok = receive + {Port, {data, "text"}} -> ok; + _ -> error + after + 1000 -> error + end, + Ref = erl_ddll:monitor(driver,{echo_drv,unloaded}), + ok = receive X -> {error, X} after 300 -> ok end, + erlang:port_close(Port), + ok = receive {'DOWN', Ref, driver, echo_drv, unloaded} -> ok after 300 -> error end, % More than one user - ?line ok = erl_ddll:load(Path, echo_drv), - ?line Ref2 = erl_ddll:monitor(driver,{echo_drv,unloaded}), - ?line ok = erl_ddll:load(Path, echo_drv), - ?line ok = erl_ddll:load(Path, echo_drv), - ?line Port2 = open_port({spawn, echo_drv}, [eof]), - ?line ok = erl_ddll:unload(echo_drv), - ?line Port2 ! {self(), {command, "text"}}, - ?line ok = receive - {Port2, {data, "text"}} -> ok; - _ -> error - after - 1000 -> error - end, - ?line ok = erl_ddll:unload(echo_drv), - ?line Port2 ! {self(), {command, "text"}}, - ?line ok = receive - {Port2, {data, "text"}} -> ok; - _ -> error - after - 1000 -> error - end, - ?line ok = erl_ddll:unload(echo_drv), - ?line Port2 ! {self(), {command, "text"}}, - ?line ok = receive - {Port2, {data, "text"}} -> ok; - _ -> error - after - 1000 -> error - end, - ?line ok = receive X2 -> {error, X2} after 300 -> ok end, - ?line ok = erl_ddll:load(Path, echo_drv), - ?line ok = receive {'UP', Ref2, driver, echo_drv, unload_cancelled} -> ok after 300 -> error end, - ?line Ref3 = erl_ddll:monitor(driver,{echo_drv,unloaded_only}), - ?line erlang:port_close(Port2), - ?line ok = receive X3 -> {error, X3} after 300 -> ok end, - ?line ok = erl_ddll:unload(echo_drv), - ?line ok = receive {'DOWN', Ref3, driver, echo_drv, unloaded} -> ok after 300 -> error end, - ?line test_server:timetrap_cancel(Dog), + ok = erl_ddll:load(Path, echo_drv), + Ref2 = erl_ddll:monitor(driver,{echo_drv,unloaded}), + ok = erl_ddll:load(Path, echo_drv), + ok = erl_ddll:load(Path, echo_drv), + Port2 = open_port({spawn, echo_drv}, [eof]), + ok = erl_ddll:unload(echo_drv), + Port2 ! {self(), {command, "text"}}, + ok = receive + {Port2, {data, "text"}} -> ok; + _ -> error + after + 1000 -> error + end, + ok = erl_ddll:unload(echo_drv), + Port2 ! {self(), {command, "text"}}, + ok = receive + {Port2, {data, "text"}} -> ok; + _ -> error + after + 1000 -> error + end, + ok = erl_ddll:unload(echo_drv), + Port2 ! {self(), {command, "text"}}, + ok = receive + {Port2, {data, "text"}} -> ok; + _ -> error + after + 1000 -> error + end, + ok = receive X2 -> {error, X2} after 300 -> ok end, + ok = erl_ddll:load(Path, echo_drv), + ok = receive {'UP', Ref2, driver, echo_drv, unload_cancelled} -> ok after 300 -> error end, + Ref3 = erl_ddll:monitor(driver,{echo_drv,unloaded_only}), + erlang:port_close(Port2), + ok = receive X3 -> {error, X3} after 300 -> ok end, + ok = erl_ddll:unload(echo_drv), + ok = receive {'DOWN', Ref3, driver, echo_drv, unloaded} -> ok after 300 -> error end, ok. - - + + ddll_test(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), - %?line {error,{already_started,ErlDdllPid}} = erl_ddll:start(), - %?line ErlDdllPid = whereis(ddll_server), + %{error,{already_started,ErlDdllPid}} = erl_ddll:start(), + %ErlDdllPid = whereis(ddll_server), %% Load the echo driver and verify that it was loaded. {ok,L1,L2}=load_echo_driver(Path), %% Verify that the driver works. - ?line Port = open_port({spawn, echo_drv}, [eof]), - ?line {hej, "hopp",4711,123445567436543653} = - erlang:port_call(Port,{hej, "hopp",4711,123445567436543653}), - ?line {hej, "hopp",4711,123445567436543653} = - erlang:port_call(Port,47,{hej, "hopp",4711,123445567436543653}), - ?line Port ! {self(), {command, "text"}}, - ?line 1 = receive - {Port, {data, "text"}} -> 1; - _Other -> 2 - after - 1000 -> 2 - end, - ?line Port ! {self(), close}, - ?line receive {Port, closed} -> ok end, - -%% %% Unload the driver and verify that it was unloaded. - ok = unload_echo_driver(L1,L2), - -%% %?line {error, {already_started, _}} = erl_ddll:start(), - - ?line test_server:timetrap_cancel(Dog), + Port = open_port({spawn, echo_drv}, [eof]), + {hej, "hopp",4711,123445567436543653} = + erlang:port_call(Port,{hej, "hopp",4711,123445567436543653}), + {hej, "hopp",4711,123445567436543653} = + erlang:port_call(Port,47,{hej, "hopp",4711,123445567436543653}), + Port ! {self(), {command, "text"}}, + 1 = receive + {Port, {data, "text"}} -> 1; + _Other -> 2 + after + 1000 -> 2 + end, + Port ! {self(), close}, + receive {Port, closed} -> ok end, + + %% %% Unload the driver and verify that it was unloaded. + ok = unload_echo_driver(L1,L2), + + %% %{error, {already_started, _}} = erl_ddll:start(), ok. %% Tests errors having to do with bad drivers. errors(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), - ?line {ok, L1} = erl_ddll:loaded_drivers(), + {ok, L1} = erl_ddll:loaded_drivers(), - ?line {error, {open_error, _}} = erl_ddll:load_driver(Path, bad_name), - ?line {error, driver_init_failed} = erl_ddll:load_driver(Path, initfail_drv), - ?line {error, bad_driver_name} = erl_ddll:load_driver(Path, wrongname_drv), + {error, {open_error, _}} = erl_ddll:load_driver(Path, bad_name), + {error, driver_init_failed} = erl_ddll:load_driver(Path, initfail_drv), + {error, bad_driver_name} = erl_ddll:load_driver(Path, wrongname_drv), %% We assume that there is a statically linked driver named "ddll": - ?line {error, linked_in_driver} = erl_ddll:unload_driver(efile), - ?line {error, not_loaded} = erl_ddll:unload_driver("__pucko_driver__"), - + {error, linked_in_driver} = erl_ddll:unload_driver(efile), + {error, not_loaded} = erl_ddll:unload_driver("__pucko_driver__"), + case os:type() of - {unix, _} -> - ?line {error, no_driver_init} = - erl_ddll:load_driver(Path, noinit_drv); - _ -> - ok + {unix, _} -> + {error, no_driver_init} = + erl_ddll:load_driver(Path, noinit_drv); + _ -> + ok end, - ?line {ok, L1} = erl_ddll:loaded_drivers(), - - ?line test_server:timetrap_cancel(Dog), + {ok, L1} = erl_ddll:loaded_drivers(), ok. -reference_count(doc) -> - ["Check that drivers are unloaded when their reference count ", - "reaches zero, and that they cannot be unloaded while ", - "they are still referenced."]; +%% Check that drivers are unloaded when their reference count +%% reaches zero, and that they cannot be unloaded while +%% they are still referenced. reference_count(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), %% Spawn a process that loads the driver (and holds a reference %% to it). Pid1=spawn_link(?MODULE, echo_loader, [Path, self()]), receive - {Pid1, echo_loaded} -> ok - after 2000 -> test_server:fail("echo_loader failed to start.") + {Pid1, echo_loaded} -> ok + after 2000 -> ct:fail("echo_loader failed to start.") end, Pid1 ! {self(), die}, - ?line test_server:sleep(200), % Give time to unload. + test_server:sleep(200), % Give time to unload. % Verify that the driver was automaticly unloaded when the % process died. - ?line {error, not_loaded}=erl_ddll:unload_driver(echo_drv), - - ?line test_server:timetrap_cancel(Dog), + {error, not_loaded}=erl_ddll:unload_driver(echo_drv), ok. % Loads the echo driver, send msg to started, sits and waits to % get a signal to die, then unloads the driver and terminates. echo_loader(Path, Starter) -> - ?line {ok, L1, L2}=load_echo_driver(Path), - ?line Starter ! {self(), echo_loaded}, + {ok, L1, L2}=load_echo_driver(Path), + Starter ! {self(), echo_loaded}, receive - {Starter, die} -> - ?line unload_echo_driver(L1,L2) + {Starter, die} -> + unload_echo_driver(L1,L2) end. % Loads the echo driver, send msg to started, sits and waits to % get a signal to die, then unloads the driver and terminates. nice_echo_loader(Path, Starter) -> - ?line {ok, L1, L2}=load_nice_echo_driver(Path), - ?line Starter ! {self(), echo_loaded}, + {ok, L1, L2}=load_nice_echo_driver(Path), + Starter ! {self(), echo_loaded}, receive - {Starter, die} -> - ?line unload_echo_driver(L1,L2) + {Starter, die} -> + unload_echo_driver(L1,L2) end. -kill_port(doc) -> - ["Test that a port that uses a driver is killed when the ", - "process that loaded the driver dies."]; +%% Test that a port that uses a driver is killed when the +%% process that loaded the driver dies. kill_port(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), %% Spawn a process that loads the driver (and holds a reference %% to it). - ?line Pid1=spawn(?MODULE, echo_loader, [Path, self()]), - ?line receive - {Pid1, echo_loaded} -> - ok - after 3000 -> - ?line exit(Pid1, kill), - ?line test_server:fail("echo_loader failed to start.") - end, + Pid1=spawn(?MODULE, echo_loader, [Path, self()]), + receive + {Pid1, echo_loaded} -> + ok + after 3000 -> + exit(Pid1, kill), + ct:fail("echo_loader failed to start.") + end, % Spawn off a port that uses the driver. - ?line Port = open_port({spawn, echo_drv}, [eof]), + Port = open_port({spawn, echo_drv}, [eof]), % Kill the process / unload the driver. - ?line process_flag(trap_exit, true), - ?line exit(Pid1, kill), - ?line test_server:sleep(200), % Give some time to unload. - ?line {error, not_loaded} = erl_ddll:unload_driver(echo_drv), + process_flag(trap_exit, true), + exit(Pid1, kill), + test_server:sleep(200), % Give some time to unload. + {error, not_loaded} = erl_ddll:unload_driver(echo_drv), % See if the port is killed. receive - {'EXIT', Port, Reason} -> - io:format("Port exited with reason ~w", [Reason]) + {'EXIT', Port, Reason} -> + io:format("Port exited with reason ~w", [Reason]) after 5000 -> - ?line test_server:fail("Echo port did not terminate.") + ct:fail("Echo port did not terminate.") end, - - %% Cleanup and exit. - ?line test_server:timetrap_cancel(Dog), ok. -dont_kill_port(doc) -> - ["Test that a port that uses a driver is not killed when the ", - "process that loaded the driver dies and it's nicely opened."]; +%% Test that a port that uses a driver is not killed when the +%% process that loaded the driver dies and it's nicely opened. dont_kill_port(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), %% Spawn a process that loads the driver (and holds a reference %% to it). - ?line Pid1=spawn(?MODULE, nice_echo_loader, [Path, self()]), - ?line receive - {Pid1, echo_loaded} -> - ok - after 3000 -> - ?line exit(Pid1, kill), - ?line test_server:fail("echo_loader failed to start.") - end, + Pid1=spawn(?MODULE, nice_echo_loader, [Path, self()]), + receive + {Pid1, echo_loaded} -> + ok + after 3000 -> + exit(Pid1, kill), + ct:fail("echo_loader failed to start.") + end, % Spawn off a port that uses the driver. - ?line Port = open_port({spawn, echo_drv}, [eof]), + Port = open_port({spawn, echo_drv}, [eof]), % Kill the process / unload the driver. - ?line process_flag(trap_exit, true), - ?line exit(Pid1, kill), - ?line test_server:sleep(200), % Give some time to unload. - ?line {hej, "hopp",4711,123445567436543653} = - erlang:port_call(Port,{hej, "hopp",4711,123445567436543653}), - ?line [] = erl_ddll:info(echo_drv,processes), + process_flag(trap_exit, true), + exit(Pid1, kill), + test_server:sleep(200), % Give some time to unload. + {hej, "hopp",4711,123445567436543653} = + erlang:port_call(Port,{hej, "hopp",4711,123445567436543653}), + [] = erl_ddll:info(echo_drv,processes), %% unload should work with no owner - ?line ok = erl_ddll:unload_driver(echo_drv), %Kill ports while at it + ok = erl_ddll:unload_driver(echo_drv), %Kill ports while at it % See if the port is killed. receive - {'EXIT', Port, Reason} -> - io:format("Port exited with reason ~w", [Reason]) + {'EXIT', Port, Reason} -> + io:format("Port exited with reason ~w", [Reason]) after 5000 -> - ?line test_server:fail("Echo port did not terminate.") + ct:fail("Echo port did not terminate.") end, - - %% Cleanup and exit. - ?line test_server:timetrap_cancel(Dog), ok. -properties(doc) -> ["Test that a process that loaded a driver ", - "is the only process that can unload it."]; +%% Test that a process that loaded a driver +%% is the only process that can unload it. properties(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), % Let another process load the echo driver. Pid=spawn_link(?MODULE, echo_loader, [Path, self()]), receive - {Pid, echo_loaded} -> ok - after 2000 -> test_server:fail("echo_loader failed to start.") + {Pid, echo_loaded} -> ok + after 2000 -> ct:fail("echo_loader failed to start.") end, % Try to unload the driver from this process (the wrong one). - ?line {error, _} = erl_ddll:unload_driver(echo_drv), - ?line {ok, Drivers} = erl_ddll:loaded_drivers(), - ?line case lists:member("echo_drv", Drivers) of - true -> - ok; - false -> - test_server:fail("Unload from wrong process " - "succeeded.") - end, + {error, _} = erl_ddll:unload_driver(echo_drv), + {ok, Drivers} = erl_ddll:loaded_drivers(), + case lists:member("echo_drv", Drivers) of + true -> + ok; + false -> + ct:fail("Unload from wrong process succeeded.") + end, % Unload the driver and terminate dummy process. - ?line Pid ! {self(), die}, - ?line test_server:sleep(200), % Give time to unload. - ?line test_server:timetrap_cancel(Dog), + Pid ! {self(), die}, + test_server:sleep(200), % Give time to unload. ok. -load_and_unload(doc) -> ["Load two drivers and unload them in load order."]; +%% Load two drivers and unload them in load order. load_and_unload(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(60)), - ?line Path = ?config(data_dir, Config), - ?line {ok, Loaded_drivers1} = erl_ddll:loaded_drivers(), - ?line ok = erl_ddll:load_driver(Path, echo_drv), - ?line ok = erl_ddll:load_driver(Path, dummy_drv), - ?line ok = erl_ddll:unload_driver(echo_drv), - ?line ok = erl_ddll:unload_driver(dummy_drv), - ?line {ok, Loaded_drivers2} = erl_ddll:loaded_drivers(), - ?line Set1 = ordsets:from_list(Loaded_drivers1), - ?line Set2 = ordsets:from_list(Loaded_drivers2), - ?line io:format("~p == ~p\n", [Loaded_drivers1, Loaded_drivers2]), - ?line [] = ordsets:to_list(ordsets:subtract(Set2, Set1)), - - ?line test_server:timetrap_cancel(Dog), + Path = proplists:get_value(data_dir, Config), + {ok, Loaded_drivers1} = erl_ddll:loaded_drivers(), + ok = erl_ddll:load_driver(Path, echo_drv), + ok = erl_ddll:load_driver(Path, dummy_drv), + ok = erl_ddll:unload_driver(echo_drv), + ok = erl_ddll:unload_driver(dummy_drv), + {ok, Loaded_drivers2} = erl_ddll:loaded_drivers(), + Set1 = ordsets:from_list(Loaded_drivers1), + Set2 = ordsets:from_list(Loaded_drivers2), + io:format("~p == ~p\n", [Loaded_drivers1, Loaded_drivers2]), + [] = ordsets:to_list(ordsets:subtract(Set2, Set1)), ok. -lock_driver(suite) -> - []; -lock_driver(doc) -> - ["Check multiple calls to driver_lock_driver"]; +%% Check multiple calls to driver_lock_driver lock_driver(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), - ?line {ok, _} = erl_ddll:try_load(Path, lock_drv, []), - ?line Port1 = open_port({spawn, lock_drv}, [eof]), - ?line Port2 = open_port({spawn, lock_drv}, [eof]), - ?line true = erl_ddll:info(lock_drv,permanent), - ?line erlang:port_close(Port1), - ?line erlang:port_close(Port2), - ?line test_server:timetrap_cancel(Dog), + Path = proplists:get_value(data_dir, Config), + {ok, _} = erl_ddll:try_load(Path, lock_drv, []), + Port1 = open_port({spawn, lock_drv}, [eof]), + Port2 = open_port({spawn, lock_drv}, [eof]), + true = erl_ddll:info(lock_drv,permanent), + erlang:port_close(Port1), + erlang:port_close(Port2), ok. - + % Load and unload the echo_drv driver. % Make sure that the driver doesn't exist before we load it, % and that it exists before we unload it. load_echo_driver(Path) -> - ?line {ok, L1} = erl_ddll:loaded_drivers(), - ?line ok = erl_ddll:load_driver(Path, echo_drv), - ?line {ok, L2} = erl_ddll:loaded_drivers(), - ?line ["echo_drv"] = ordsets:to_list(subtract(ordsets:from_list(L2), - ordsets:from_list(L1))), + {ok, L1} = erl_ddll:loaded_drivers(), + ok = erl_ddll:load_driver(Path, echo_drv), + {ok, L2} = erl_ddll:loaded_drivers(), + ["echo_drv"] = ordsets:to_list(subtract(ordsets:from_list(L2), + ordsets:from_list(L1))), {ok,L1,L2}. load_nice_echo_driver(Path) -> - ?line {ok, L1} = erl_ddll:loaded_drivers(), - ?line ok = erl_ddll:load(Path, echo_drv), - ?line {ok, L2} = erl_ddll:loaded_drivers(), - ?line ["echo_drv"] = ordsets:to_list(subtract(ordsets:from_list(L2), - ordsets:from_list(L1))), + {ok, L1} = erl_ddll:loaded_drivers(), + ok = erl_ddll:load(Path, echo_drv), + {ok, L2} = erl_ddll:loaded_drivers(), + ["echo_drv"] = ordsets:to_list(subtract(ordsets:from_list(L2), + ordsets:from_list(L1))), {ok,L1,L2}. unload_echo_driver(L1,L2) -> - ?line {ok, L2} = erl_ddll:loaded_drivers(), - ?line ok = erl_ddll:unload_driver(echo_drv), - ?line {ok, L3} = erl_ddll:loaded_drivers(), - ?line [] = ordsets:to_list(subtract(ordsets:from_list(L3), - ordsets:from_list(L1))), + {ok, L2} = erl_ddll:loaded_drivers(), + ok = erl_ddll:unload_driver(echo_drv), + {ok, L3} = erl_ddll:loaded_drivers(), + [] = ordsets:to_list(subtract(ordsets:from_list(L3), + ordsets:from_list(L1))), ok. unload_expect_fast(Driver,XFlags) -> {ok, pending_driver, Ref} = - erl_ddll:try_unload(Driver, - [{monitor,pending_driver}]++XFlags), + erl_ddll:try_unload(Driver, + [{monitor,pending_driver}]++XFlags), receive - {'DOWN', Ref, driver, Driver, unloaded} -> - case lists:member(atom_to_list(Driver),element(2,erl_ddll:loaded_drivers())) of - true -> - {error, {still_there, Driver}}; - false -> - ok - end + {'DOWN', Ref, driver, Driver, unloaded} -> + case lists:member(atom_to_list(Driver),element(2,erl_ddll:loaded_drivers())) of + true -> + {error, {still_there, Driver}}; + false -> + ok + end after 1000 -> - {error,{unable_to_unload, Driver}} + {error,{unable_to_unload, Driver}} end. |