aboutsummaryrefslogtreecommitdiffstats
path: root/erts/ntbuild.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/ntbuild.erl')
-rw-r--r--erts/ntbuild.erl332
1 files changed, 332 insertions, 0 deletions
diff --git a/erts/ntbuild.erl b/erts/ntbuild.erl
new file mode 100644
index 0000000000..e48be58c17
--- /dev/null
+++ b/erts/ntbuild.erl
@@ -0,0 +1,332 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2009. 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.
+%%
+%% %CopyrightEnd%
+%%
+%% To be used from makefiles on the unix side executing things on the NT-side
+-module(ntbuild).
+
+-export([nmake/1, omake/1, waitnode/1, restart/1,
+ setdir/1, run_tests/1, run_command/1]).
+-export([serv_nmake/2, serv_omake/2, serv_restart/0, serv_run_tests/2,
+ serv_run_command/1]).
+
+waitnode([NtNode]) ->
+ % First, wait for node to disappear.
+ case wait_disappear(NtNode, 0) of
+ ok ->
+ case wait_appear(NtNode, 0) of
+ ok ->
+ halt(0);
+ fail ->
+ halt(1)
+ end;
+ fail ->
+ halt(1)
+ end.
+
+% Wait for nt node to appear within 5 minutes.
+wait_appear(_NtNode, 300) ->
+ fail;
+wait_appear(NtNode, N) ->
+ receive after 1000 -> ok end,
+ case nt_node_alive(NtNode, quiet) of
+ no ->
+ wait_appear(NtNode, N+1);
+ yes ->
+ ok
+ end.
+
+
+
+% Waits for nt node to disappear within 3 minutes.
+wait_disappear(NtNode, 300) ->
+ fail;
+wait_disappear(NtNode, N) ->
+ receive after 1000 -> ok end,
+ case nt_node_alive(NtNode, quiet) of
+ yes ->
+ wait_disappear(NtNode, N+1);
+ no ->
+ ok
+ end.
+
+restart([NtNode]) ->
+ case nt_node_alive(NtNode) of
+ yes ->
+ case rpc:call(NtNode, ntbuild, serv_restart, []) of
+ ok ->
+ io:format("halt(0)~n"),
+ halt();
+ Error ->
+ io:format("halt(1)~n"),
+ halt(1)
+ end;
+ no ->
+ halt(1)
+ end.
+
+
+setdir([NtNode, Dir0]) ->
+ Dir = atom_to_list(Dir0),
+ case nt_node_alive(NtNode) of
+ yes ->
+ case rpc:call(NtNode, file, set_cwd, [Dir]) of
+ ok ->
+ io:format("halt(0)~n"),
+ halt();
+ Error ->
+ io:format("halt(1) (Error: ~p) (~p not found) ~n", [Error, Dir]),
+ halt(1)
+ end;
+ no ->
+ halt(1)
+ end.
+
+run_tests([NtNode, Vsn0, Logdir]) ->
+ Vsn = atom_to_list(Vsn0),
+ case nt_node_alive(NtNode) of
+ yes ->
+ case rpc:call(NtNode, ntbuild, serv_run_tests, [Vsn, Logdir]) of
+ ok ->
+ io:format("halt(0)~n"),
+ halt();
+ Error ->
+ io:format("RPC To Windows Node Failed: ~p~n", [Error]),
+ io:format("halt(1)~n"),
+ halt(1)
+ end;
+ no ->
+ halt(1)
+ end.
+
+run_command([NtNode, Cmd]) ->
+ case nt_node_alive(NtNode) of
+ yes ->
+ case rpc:call(NtNode, ntbuild, serv_run_command, [Cmd]) of
+ ok ->
+ io:format("halt(0)~n"),
+ halt();
+ Error ->
+ io:format("RPC To Windows Node Failed: ~p~n", [Error]),
+ io:format("halt(1)~n"),
+ halt(1)
+ end;
+ no ->
+ halt(1)
+ end.
+
+nmake([NtNode, Path, Options]) ->
+% io:format("nmake2(~w,~w)~n",[Path, Options]),
+ Dir=atom_to_list(Path),
+ Opt=atom_to_list(Options),
+ case nt_node_alive(NtNode) of
+ yes ->
+ case rpc:call(NtNode, ntbuild, serv_nmake, [Dir, Opt]) of
+ ok ->
+ io:format("halt(0)~n"),
+ halt();
+ Error ->
+ io:format("Error: ~n", [Error]),
+ halt(1)
+ end;
+ no ->
+ halt(1)
+ end.
+
+omake([NtNode, Path, Options]) ->
+ Dir=atom_to_list(Path),
+ Opt=atom_to_list(Options),
+ case nt_node_alive(NtNode) of
+ yes ->
+ case rpc:call(NtNode, ntbuild, serv_omake, [Dir, Opt]) of
+ ok ->
+ io:format("halt(0)~n"),
+ halt();
+ Error ->
+ io:format("RPC To Windows Node Failed: ~p~n", [Error]),
+ io:format("~p ~p~n", [Dir, Opt]),
+ io:format("halt(1)~n"),
+ halt(1)
+ end;
+ no ->
+ halt(1)
+ end.
+
+
+
+
+
+nt_node_alive(NtNode) ->
+ case net:ping(NtNode) of
+ pong ->
+ yes;
+ pang ->
+ io:format("The NT node (~p) is not up. ~n",[NtNode]),
+ no
+ end.
+
+nt_node_alive(NtNode, quiet) ->
+ case net:ping(NtNode) of
+ pong ->
+ yes;
+ pang ->
+ no
+ end.
+
+
+
+%%%
+%%% The 'serv_' functions. Theese are the routines run on the WinNT node.
+%%%
+
+%%-----------------------
+%% serv_run_tests()
+%% Runs the tests.
+serv_run_tests(Vsn, Logdir) ->
+ {ok, Cwd}=file:get_cwd(),
+ io:format("serv_run_tests ~p ~p ~n", [Vsn, Logdir]),
+ Cmd0= "set central_log_dir=" ++ Logdir,
+ Erl = "C:/progra~1/erl"++Vsn++"/bin/erl",
+ Cmd1 = Erl++" -sname a -setcookie a -noshell -noinput -s ts install -s ts run -s ts save -s erlang halt",
+%% Dir = "C:/temp/test_suite/test_server",
+ Cmd= Cmd0 ++ "/r/n" ++ Cmd1,
+ Dir = "C:/temp/test_server/p7a/test_server",
+ file:set_cwd(Dir),
+ Res=run_make_bat(Dir, Cmd),
+ file:set_cwd(Cwd),
+ Res.
+
+%%-----------------------
+%% serv_run_command()
+%% Runs a command.
+serv_run_command(Cmd) ->
+ {ok, Cwd}=file:get_cwd(),
+ Res=run_make_bat("", Cmd),
+ file:set_cwd(Cwd),
+ Res.
+
+%%-----------------------
+%% serv_restart()
+%% Reboots the NT machine.
+serv_restart() ->
+ Exe="\\erts\\install_nt\\reboot.exe",
+ open_port({spawn, Exe}, [stream, eof, in]),
+ ok.
+
+
+%%-----------------------
+%% serv_nmake(Path, Options)
+%% Runs `nmake' in the given directory.
+%% Result: ok | error
+serv_nmake(Path, Options) ->
+ {ok, Cwd}=file:get_cwd(),
+ Command="nmake -e -f Makefile.win32 " ++ Options ++ " 2>&1",
+ Res=run_make_bat(Path, Command),
+ file:set_cwd(Cwd),
+ Res.
+
+%%-----------------------
+%% serv_omake(Path, Options)
+%% Runs `omake' in the given directory.
+%% Result: ok | error
+serv_omake(Path, Options) ->
+ {ok, Cwd}=file:get_cwd(),
+ Command="omake -W -E -EN -f Makefile.win32 " ++ Options ++ " 2>&1",
+ Res=run_make_bat(Path, Command),
+ file:set_cwd(Cwd),
+ Res.
+
+
+read_output(Port, SoFar) ->
+% io:format("(read_output)~n"),
+ case get_data_from_port(Port) of
+ eof ->
+ io:format("*** eof ***~n"),
+ io:format("Never reached a real message"),
+ halt(1);
+ {ok, Data} ->
+ case print_line([SoFar|Data]) of
+ {ok, Rest} ->
+ read_output(Port, Rest);
+ {done, Res} ->
+ Res
+ end
+ end.
+
+print_line(Data) ->
+ print_line(Data, []).
+
+print_line([], Acc) ->
+ {ok, lists:reverse(Acc)};
+print_line([$*,$o,$k,$*|Rest], _Acc) ->
+ io:format("*ok*~n"),
+ {done, ok};
+print_line([$*,$e,$r,$r,$o,$r|Rest], _Acc) ->
+ io:format("*error*~n"),
+ {done, error};
+print_line([$\r,$\n|Rest], Acc) ->
+ io:format("~s~n", [lists:reverse(Acc)]),
+ print_line(Rest, []);
+print_line([Chr|Rest], Acc) ->
+ print_line(Rest, [Chr|Acc]).
+
+get_data_from_port(Port) ->
+ receive
+ {Port, {data, Bytes}} ->
+ {ok, Bytes};
+ {Port, eof} ->
+ unlink(Port),
+ exit(Port, die),
+ eof;
+ Other ->
+ io:format("Strange message received: ~p~n", [Other]),
+ get_data_from_port(Port)
+ end.
+
+
+run_make_bat(Dir, Make) ->
+ {Name, Exe, Script}=create_make_script(Dir, Make),
+ io:format("Exe:~p Cwd:~p Script:~p ~n",[Exe, Dir, Script]),
+ case file:write_file(Name, Script) of
+ ok ->
+ case catch open_port({spawn, Exe}, [stderr_to_stdout, stream, hide,
+ eof, in]) of
+ Port when port(Port) ->
+ read_output(Port, []);
+ Other ->
+ io:format("Error, open_port failed: ~p~n", [Other]),
+ {open_port, Other, Exe}
+ end;
+ Error ->
+ {write_file, Error, Name}
+ end.
+
+create_make_script(Dir, Make) when atom(Make) ->
+ create_make_script(Dir, atom_to_list(Make));
+create_make_script(Dir, Make) ->
+ {"run_make_bs.bat",
+ "run_make_bs 2>&1",
+ ["@echo off\r\n",
+ "@cd ", Dir, "\r\n",
+ Make++"\r\n",
+ "if errorlevel 1 echo *run_make_bs error*\r\n",
+ "if not errorlevel 1 echo *ok*\r\n"]}.
+
+
+
+
+