1-module(rh_test_lib).
2
3-export([cmd/3]).
4-export([erlsrv/3,
5	 erlsrv/4]).
6-export([get_service_args/3,
7	 get_service_args/4,
8	 get_start_erl_args/1,
9	 get_start_erl_args/3,
10	 get_client_args/3,
11	 get_client_args/4]).
12-export([clean_dir/1,
13	 clean_dir/2]).
14
15-include_lib("kernel/include/file.hrl").
16
17cmd(Cmd,Args,Env) ->
18    case open_port({spawn_executable, Cmd}, [{args,Args},{env,Env}]) of
19        Port when is_port(Port) ->
20            unlink(Port),
21            catch erlang:port_close(Port), % migth already be closed, so catching
22	    ok;
23        Error ->
24            Error
25    end.
26
27erlsrv(Erlsrv,Action,Name) ->
28    erlsrv(Erlsrv,Action,Name,"").
29erlsrv(Erlsrv,Action,Name,Rest) ->
30    Cmd = "\"" ++ Erlsrv ++ "\" " ++ atom_to_list(Action) ++ " " ++
31	Name ++ " " ++ Rest,
32    io:format("erlsrv cmd: ~tp~n",[Cmd]),
33    Port = open_port({spawn, Cmd}, [stream, {line, 100}, eof, in]),
34    Res = recv_prog_output(Port),
35    case Res of
36	[] ->
37	    failed;
38	_Y ->
39	    io:format("erlsrv res: ~p~n",[_Y]),
40	    ok
41    end.
42
43recv_prog_output(Port) ->
44    receive
45	{Port, {data, {eol,Data}}} ->
46	    %%io:format("Got data: ~s~n", [Data]),
47	    [ Data, "\n" | recv_prog_output(Port)];
48	{Port, {data, {noeol,Data}}} ->
49	    %%io:format("Got data: ~s~n", [Data]),
50	    [ Data | recv_prog_output(Port)];
51	{Port, _Other} ->
52	    %%io:format("Got ~p from port~n", [_Other]),
53	    Port ! {self(), close},
54	    receive
55		{Port,closed} ->
56		    []
57	    end
58    end.
59
60get_service_args(RootDir, Sname, StartErlArgs) ->
61    get_service_args(RootDir, "", Sname, StartErlArgs).
62get_service_args(RootDir, RelClientDir, Sname, StartErlArgs) ->
63    LogDir = filename:nativename(filename:join([RootDir,RelClientDir,"log"])),
64    %% start_erl.exe will be found since it is in the same directory as erlsrv.exe
65    %% And heart_restart.bat will be found since the erts bin dir is
66    %% always in the path for the erlang virtual machine.
67    " -machine start_erl.exe -workdir " ++ LogDir ++
68	" -debugtype new -sname " ++ atom_to_list(Sname) ++
69	" -env HEART_COMMAND=heart_restart.bat -args \"" ++ StartErlArgs ++ "\"".
70
71get_start_erl_args(RootDir) ->
72    get_start_erl_args(RootDir,"","").
73get_start_erl_args(RootDir,RelClientDir,ExtraArgs) ->
74    Cookie = atom_to_list(erlang:get_cookie()),
75    RelDir = filename:join([RootDir,RelClientDir,"releases"]),
76    ExtraArgs ++ " -setcookie " ++ Cookie ++
77	" -heart ++ -rootdir " ++ filename:nativename(RootDir) ++
78	" -reldir " ++ filename:nativename(RelDir).
79
80%% Must be called on the master node
81get_client_args(Client,Sname,RootDir) ->
82    get_client_args(Client,Sname,RootDir,node()).
83get_client_args(Client,Sname,RootDir,Master) ->
84    {ok,Host} = inet:gethostname(),
85    Node = atom_to_list(Sname) ++ "@" ++ Host,
86    RelClientDir = filename:join(["clients","type1",Node]),
87    ClientDir = filename:join([RootDir,RelClientDir]),
88    StartPrg = filename:join([ClientDir,"bin","start"]),
89    {" -sasl start_prg \\\\\\\"" ++ StartPrg ++ "\\\\\\\" masters \[" ++
90	 single_quote() ++ atom_to_list(Master) ++ single_quote() ++
91	 get_client_extra_master(Client,Host) ++
92	 "\] client_directory \\\\\\\"" ++ ClientDir ++  "\\\\\\\"" ++
93	 get_client_loader_args(Client,Sname,Host),
94     RelClientDir}.
95
96get_client_loader_args(client1,Sname,Host) ->
97    {ok,IpTuple} = inet:getaddr(Host,inet),
98    IpAddr =  inet_parse:ntoa(IpTuple),
99    " -loader inet -id " ++
100	atom_to_list(Sname) ++ " -hosts " ++ IpAddr;
101get_client_loader_args(_,_,_) ->
102    "".
103
104get_client_extra_master(client2,Host) ->
105    "," ++ single_quote() ++ "master2@" ++ Host ++ single_quote();
106get_client_extra_master(_,_) ->
107    "".
108
109single_quote() ->
110    case os:type() of
111	{win32,_} ->
112	    "\'";
113	_ ->
114	    "\\'"
115    end.
116
117clean_dir(Dir) ->
118    clean_dir(Dir,false).
119clean_dir(Dir,Save) ->
120    test_server:format("========  current dir ~tp~n",[Dir]),
121    Dirs = filelib:wildcard(filename:join(Dir,"*")),
122    test_server:format("========  deleting  ~tp~n",[Dirs]),
123
124    ok = rm_rf(Dirs,Save),
125    Remaining = filelib:wildcard(filename:join(Dir,"*")),
126    test_server:format("========  remaining  ~tp~n",[Remaining]),
127
128    case Remaining of
129	[] ->
130	    ok;
131	_ ->
132	    rm_rf(Remaining,Save),
133	    Remaining2 = filelib:wildcard(filename:join(Dir,"*")),
134	    test_server:format("========  remaining after second try ~tp~n",
135			       [Remaining2])
136    end,
137
138    ok.
139
140
141rm_rf([File|Files],Save) ->
142    case Save andalso filename:basename(File)=="save" of
143	true ->
144	    rm_rf(Files,Save);
145	false ->
146	    case file:read_link_info(File) of
147		{ok,#file_info{type=directory}} ->
148		    MoreFiles = filelib:wildcard(filename:join(File,"*")),
149		    rm_rf(MoreFiles,Save),
150		    file:del_dir(File),
151		    rm_rf(Files,Save);
152		{ok,#file_info{}} ->
153		    file:delete(File),
154		    rm_rf(Files,Save);
155		Other ->
156		    test_server:format("========  could not delete file  ~p~n"
157				       "read_link_info -> ~p~n",[File,Other]),
158		    rm_rf(Files,Save)
159	    end
160    end;
161rm_rf([],_) ->
162    ok.
163