diff options
Diffstat (limited to 'lib/reltool')
23 files changed, 1375 insertions, 128 deletions
diff --git a/lib/reltool/doc/src/Makefile b/lib/reltool/doc/src/Makefile index 2c634bdf6c..8bc1488f77 100644 --- a/lib/reltool/doc/src/Makefile +++ b/lib/reltool/doc/src/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 2009-2010. 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% include $(ERL_TOP)/make/target.mk @@ -39,6 +39,10 @@ include files.mk # ---------------------------------------------------- +XML_FILES = \ + $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \ + $(XML_PART_FILES) $(XML_CHAPTER_FILES) + HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \ $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html) @@ -46,10 +50,6 @@ INFO_FILE = ../../info MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3) -XML_FILES = \ - $(BOOK_FILES) $(XML_CHAPTER_FILES) \ - $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES) - HTML_REF_MAN_FILE = $(HTMLDIR)/index.html TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf @@ -72,15 +72,20 @@ $(TOP_PDF_FILE): $(XML_FILES) pdf: $(TOP_PDF_FILE) -html: gifs $(HTML_REF_MAN_FILE) +html:images $(HTML_REF_MAN_FILE) man: $(MAN3_FILES) -gifs: $(GIF_FILES:%=$(HTMLDIR)/%) +images: $(IMAGE_FILES:%=$(HTMLDIR)/%) debug opt: clean clean_docs: + for file in $(XML_FILES); do \ + if [ -f $$file\src ]; then \ + rm -f $$file; \ + fi \ + done rm -rf $(HTMLDIR)/* rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) @@ -95,8 +100,7 @@ release_docs_spec: docs $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf $(INSTALL_DIR) $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html + $(INSTALL_DATA) $(HTMLDIR)/* $(RELSYSDIR)/doc/html $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 diff --git a/lib/reltool/doc/src/book.gif b/lib/reltool/doc/src/book.gif Binary files differdeleted file mode 100644 index 94b3868792..0000000000 --- a/lib/reltool/doc/src/book.gif +++ /dev/null diff --git a/lib/reltool/doc/src/fascicules.xml b/lib/reltool/doc/src/fascicules.xml deleted file mode 100644 index a57808974e..0000000000 --- a/lib/reltool/doc/src/fascicules.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE fascicules SYSTEM "fascicules.dtd"> - -<fascicules> - <fascicule file="part" href="part_frame.html" entry="no"> - User's Guide - </fascicule> - <fascicule file="ref_man" href="ref_man_frame.html" entry="yes"> - Reference Manual - </fascicule> - <fascicule file="part_notes" href="part_notes_frame.html" entry="no"> - Release Notes - </fascicule> - <fascicule file="" href="../../../../doc/print.html" entry="no"> - Off-Print - </fascicule> -</fascicules> diff --git a/lib/reltool/doc/src/files.mk b/lib/reltool/doc/src/files.mk index b2dc06411d..07b52f4934 100644 --- a/lib/reltool/doc/src/files.mk +++ b/lib/reltool/doc/src/files.mk @@ -1,20 +1,20 @@ #-*-makefile-*- ; force emacs to enter makefile-mode # # %CopyrightBegin% -# -# Copyright Ericsson AB 2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 2009-2010. 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% XML_APPLICATION_FILES = \ @@ -24,8 +24,7 @@ XML_REF3_FILES = \ reltool.xml XML_PART_FILES = \ - part.xml \ - part_notes.xml + part.xml XML_CHAPTER_FILES = \ reltool_intro.xml \ @@ -35,11 +34,5 @@ XML_CHAPTER_FILES = \ BOOK_FILES = book.xml -GIF_FILES = \ - book.gif \ - note.gif \ - notes.gif \ - ref_man.gif \ - user_guide.gif \ - warning.gif +IMAGE_FILES = diff --git a/lib/reltool/doc/src/note.gif b/lib/reltool/doc/src/note.gif Binary files differdeleted file mode 100644 index 6fffe30419..0000000000 --- a/lib/reltool/doc/src/note.gif +++ /dev/null diff --git a/lib/reltool/doc/src/notes.gif b/lib/reltool/doc/src/notes.gif Binary files differdeleted file mode 100644 index e000cca26a..0000000000 --- a/lib/reltool/doc/src/notes.gif +++ /dev/null diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml index 293793e900..524d728901 100644 --- a/lib/reltool/doc/src/notes.xml +++ b/lib/reltool/doc/src/notes.xml @@ -38,6 +38,21 @@ section is the version number of Reltool.</p> + <section><title>Reltool 0.5.3</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Removed spurious documentation files.</p> + <p> + Own Id: OTP-8057</p> + </item> + </list> + </section> + + </section> + <section><title>Reltool 0.5.2</title> <section><title>Improvements and New Features</title> diff --git a/lib/reltool/doc/src/part_notes.xml b/lib/reltool/doc/src/part_notes.xml deleted file mode 100644 index 5a2aeecce6..0000000000 --- a/lib/reltool/doc/src/part_notes.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE part SYSTEM "part.dtd"> - -<part xmlns:xi="http://www.w3.org/2001/XInclude"> - <header> - <copyright> - <year>2009</year> - <year>2009</year> - <holder>Ericsson AB, All Rights Reserved</holder> - </copyright> - <legalnotice> - 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. - - The Initial Developer of the Original Code is Ericsson AB. - </legalnotice> - - <title>Reltool Release Notes</title> - <prepared>Håkan Mattsson</prepared> - <docno></docno> - <date></date> - <rev>%VSN%</rev> - </header> - <description> - <p><c>Reltool</c> is a release management tool. It analyses a given - Erlang/OTP installation and determines various dependencies - between applications. The <c>graphical</c> frontend depicts the - dependencies and enables interactive customization of a - target system. The backend provides a <c>batch</c> interface - for generation of customized target systems.</p> - </description> - <xi:include href="notes.xml"/> -</part> diff --git a/lib/reltool/doc/src/ref_man.gif b/lib/reltool/doc/src/ref_man.gif Binary files differdeleted file mode 100644 index b13c4efd53..0000000000 --- a/lib/reltool/doc/src/ref_man.gif +++ /dev/null diff --git a/lib/reltool/doc/src/reltool_examples.xml b/lib/reltool/doc/src/reltool_examples.xml index 3d087862e6..d6db246f6c 100644 --- a/lib/reltool/doc/src/reltool_examples.xml +++ b/lib/reltool/doc/src/reltool_examples.xml @@ -45,7 +45,8 @@ its server can be obtained with <c>reltool:get_server/1</c></p> <pre> -Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false] +Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] + [async-threads:0] [kernel-poll:false] Eshell V5.7.3 (abort with ^G) 1> {ok, Win} = reltool:start([]). @@ -72,10 +73,13 @@ ok <title>Inspecting the configuration</title> <pre> -Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false] +Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] + [async-threads:0] [kernel-poll:false] Eshell V5.7.3 (abort with ^G) -1> Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]}, +1> Config = {sys, [{escript, + "examples/display_args", + [{incl_cond, include}]}, {app, inets, [{incl_cond, include}]}, {app, mnesia, [{incl_cond, exclude}]}, {app, ssl, [{incl_cond, exclude}]}, @@ -244,7 +248,8 @@ Eshell V5.7.3 (abort with ^G) <title>Generate release and script files</title> <pre> 5> {ok, Server} = reltool:start_server([{config, {sys, [{boot_rel, "NAME"}, - {rel, "NAME", "VSN", [kernel, stdlib, sasl]}]}}]). + {rel, "NAME", "VSN", + [kernel, stdlib, sasl]}]}}]). {ok,<0.1288.0>} 6> reltool:get_config(Server). {ok,{sys,[{boot_rel,"NAME"}, @@ -297,10 +302,13 @@ ok <section> <title>Create a target system</title> <pre> -Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false] +Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] + [async-threads:0] [kernel-poll:false] Eshell V5.7.3 (abort with ^G) -1> Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]}, +1> Config = {sys, [{escript, + "examples/display_args", + [{incl_cond, include}]}, {app, inets, [{incl_cond, include}]}, {app, mnesia, [{incl_cond, exclude}]}, {app, ssl, [{incl_cond, exclude}]}, @@ -320,11 +328,11 @@ Eshell V5.7.3 (abort with ^G) [{write_file,"start_erl.data","5.7.3 1.0"}, {create_dir,"1.0", [{write_file,"start_clean.rel", - [37,37,32,114,101,108,32,103,101,110,101,114,97,116|...]}, + [37,37,32,114,101,108,32,103,101,110,101|...]}, {write_file,"start_clean.script", - [37,37,32,115,99,114,105,112,116,32,103,101,110|...]}, + [37,37,32,115,99,114,105,112,116,32|...]}, {write_file,"start_clean.boot", - <<131,104,3,100,0,6,115,99,114,105,112,116,...>>}, + <<131,104,3,100,0,6,115,99,114,...>>}, {write_file,"start_sasl.rel", [37,37,32,114,101,108,32,103,101,110,101|...]}, {write_file,"start_sasl.script", @@ -409,11 +417,13 @@ Eshell V5.7.3 (abort with ^G) {copy_file,...}, {...}|...]}, {create_dir,"src", - [{copy_file,[...]},{copy_file,...},{...}|...]}]}]}, + [{copy_file,[...]}, + {copy_file,...},{...}|...]}]}]}, {archive,"crypto-1.6.1.ez",[], [{create_dir,"crypto-1.6.1", [{create_dir,"ebin", - [{copy_file,[...]},{copy_file,...},{...}|...]}, + [{copy_file,[...]}, + {copy_file,...},{...}|...]}, {create_dir,"src",[{copy_file,...},{...}|...]}]}]}, {create_dir,"crypto-1.6.1", [{create_dir,"priv", diff --git a/lib/reltool/doc/src/user_guide.gif b/lib/reltool/doc/src/user_guide.gif Binary files differdeleted file mode 100644 index e6275a803d..0000000000 --- a/lib/reltool/doc/src/user_guide.gif +++ /dev/null diff --git a/lib/reltool/doc/src/warning.gif b/lib/reltool/doc/src/warning.gif Binary files differdeleted file mode 100644 index 96af52360e..0000000000 --- a/lib/reltool/doc/src/warning.gif +++ /dev/null diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl index 895fc6702b..6d85a98d9f 100644 --- a/lib/reltool/src/reltool_target.erl +++ b/lib/reltool/src/reltool_target.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2009-2010. 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% -module(reltool_target). @@ -966,9 +966,9 @@ do_eval_spec({create_dir, Dir, Files}, OrigSourceDir, SourceDir, TargetDir) -> TargetDir2 = filename:join([TargetDir, Dir]), reltool_utils:create_dir(TargetDir2), do_eval_spec(Files, OrigSourceDir, SourceDir2, TargetDir2); -do_eval_spec({create_dir, NewDir, OldDir, Files}, OrigSourceDir, _SourceDir, TargetDir) -> +do_eval_spec({create_dir, Dir, OldDir, Files}, OrigSourceDir, _SourceDir, TargetDir) -> SourceDir2 = filename:join([OrigSourceDir, OldDir]), - TargetDir2 = filename:join([TargetDir, NewDir]), + TargetDir2 = filename:join([TargetDir, Dir]), reltool_utils:create_dir(TargetDir2), do_eval_spec(Files, SourceDir2, SourceDir2, TargetDir2); do_eval_spec({archive, Archive, Options, Files}, OrigSourceDir, SourceDir, TargetDir) -> @@ -992,9 +992,9 @@ do_eval_spec({copy_file, File}, _OrigSourceDir, SourceDir, TargetDir) -> SourceFile = filename:join([SourceDir, File]), TargetFile = filename:join([TargetDir, File]), reltool_utils:copy_file(SourceFile, TargetFile); -do_eval_spec({copy_file, NewFile, OldFile}, OrigSourceDir, _SourceDir, TargetDir) -> +do_eval_spec({copy_file, File, OldFile}, OrigSourceDir, _SourceDir, TargetDir) -> SourceFile = filename:join([OrigSourceDir, OldFile]), - TargetFile = filename:join([TargetDir, NewFile]), + TargetFile = filename:join([TargetDir, File]), reltool_utils:copy_file(SourceFile, TargetFile); do_eval_spec({write_file, File, IoList}, _OrigSourceDir, _SourceDir, TargetDir) -> TargetFile = filename:join([TargetDir, File]), @@ -1014,8 +1014,8 @@ cleanup_spec({create_dir, Dir, Files}, TargetDir) -> TargetDir2 = filename:join([TargetDir, Dir]), cleanup_spec(Files, TargetDir2), file:del_dir(TargetDir2); -cleanup_spec({create_dir, NewDir, _OldDir, Files}, TargetDir) -> - TargetDir2 = filename:join([TargetDir, NewDir]), +cleanup_spec({create_dir, Dir, _OldDir, Files}, TargetDir) -> + TargetDir2 = filename:join([TargetDir, Dir]), cleanup_spec(Files, TargetDir2), file:del_dir(TargetDir2); cleanup_spec({archive, Archive, _Options, Files}, TargetDir) -> @@ -1125,6 +1125,8 @@ match(String, [#regexp{source = _, compiled = MP} | Regexps]) -> end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Old style installation +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% install(RelName, TargetDir) -> try @@ -1220,7 +1222,6 @@ subst_var([C| Rest], Vars, Result, VarAcc) -> subst_var(Rest, Vars, Result, [C| VarAcc]); subst_var([], Vars, Result, VarAcc) -> subst([], Vars, [VarAcc ++ [$% | Result]]). - start_scripts() -> ["erl", "start", "start_erl"]. diff --git a/lib/reltool/test/Makefile b/lib/reltool/test/Makefile new file mode 100644 index 0000000000..00d2add3e5 --- /dev/null +++ b/lib/reltool/test/Makefile @@ -0,0 +1,82 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 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% + +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +MODULES= \ + rtt \ + reltool_wx_SUITE \ + reltool_server_SUITE \ + reltool_test_lib + + +ERL_FILES= $(MODULES:%=%.erl) + +HRL_FILES= reltool_test_lib.hrl + +TARGET_FILES= \ + $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + +INSTALL_PROGS= $(TARGET_FILES) + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/reltool_test + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +#ERL_COMPILE_FLAGS += + +EBIN = . + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +tests debug opt: $(TARGET_FILES) + +clean: + rm -f $(TARGET_FILES) + rm -f core + +docs: + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + +release_tests_spec: opt + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) reltool.spec $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) + $(INSTALL_PROGRAM) rtt $(INSTALL_PROGS) $(RELSYSDIR) +# chmod -f -R u+w $(RELSYSDIR) +# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + +release_docs_spec: + + diff --git a/lib/reltool/test/README b/lib/reltool/test/README new file mode 100644 index 0000000000..031bd2c961 --- /dev/null +++ b/lib/reltool/test/README @@ -0,0 +1,30 @@ + +Testing and running reltool tests. + +Testing gui api/applications can be hard, but we can at least +test that wxerlang behaves as we expected, i.e. that the api +is consistent and that it don't crash. + +The tests are structured as they are because we want you to +be able to run them in three different ways. + - direct via an erlang shell + - via common_test application + - via erlang/OTP inhouse ts tool. + +To run all the tests compile them and on unix +run ./rtt to create an erlang terminal. + +Invoke rtt:t(). in the erlang shell to run all regression tests. +If you want to specific tests invoke rtt:t(Module) +or rtt:t(Module, TestCase). + +To run all tests including the ones that require manual intervention run. +rtt:t(all, [{user,true}]). + +To see every test_case window use +rtt:t(all, [{user,step}]). +This requires that you manually close each window to step to the +next test_case. + +If you want to run specific test_cases use: +rtt:t({Module,TestCase}, [{user,step}]). diff --git a/lib/reltool/test/reltool.spec b/lib/reltool/test/reltool.spec new file mode 100644 index 0000000000..252232e09d --- /dev/null +++ b/lib/reltool/test/reltool.spec @@ -0,0 +1,2 @@ +{topcase, {dir, "../reltool_test"}}. + diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl new file mode 100644 index 0000000000..cf951191a0 --- /dev/null +++ b/lib/reltool/test/reltool_server_SUITE.erl @@ -0,0 +1,494 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% + +-module(reltool_server_SUITE). + +-export([all/0, init_per_suite/1, end_per_suite/1, + init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]). + +-compile(export_all). + +-include("reltool_test_lib.hrl"). + +-define(NODE_NAME, '__RELTOOL__TEMPORARY_TEST__NODE__'). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Initialization functions. + +init_per_suite(Config) -> + reltool_test_lib:init_per_suite(Config). + +end_per_suite(Config) -> + reltool_test_lib:end_per_suite(Config). + +init_per_testcase(Func,Config) -> + reltool_test_lib:init_per_testcase(Func,Config). +end_per_testcase(Func,Config) -> + reltool_test_lib:end_per_testcase(Func,Config). +fin_per_testcase(Func,Config) -> %% For test_server + reltool_test_lib:end_per_testcase(Func,Config). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% SUITE specification + +all() -> + all(suite). +all(suite) -> + [ + start_server, + set_config, + create_release, + create_script, + create_target, + create_embedded, + create_standalone, + create_old_target + ]. + +%% The test cases + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Start a server process and check that it does not crash + +start_server(TestInfo) when is_atom(TestInfo) -> + reltool_test_lib:tc_info(TestInfo); +start_server(_Config) -> + {ok, Pid} = ?msym({ok, _}, reltool:start_server([])), + Libs = lists:sort(erl_libs()), + StrippedDefault = + case Libs of + [] -> {sys, []}; + _ -> {sys, [{lib_dirs, Libs}]} + end, + ?m({ok, StrippedDefault}, reltool:get_config(Pid)), + ?m(ok, reltool:stop(Pid)), + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Start a server process and check that it does not crash + +set_config(TestInfo) when is_atom(TestInfo) -> + reltool_test_lib:tc_info(TestInfo); +set_config(_Config) -> + Libs = lists:sort(erl_libs()), + Default = + {sys, + [ + {mod_cond, all}, + {incl_cond, derived}, + {root_dir, code:root_dir()}, + {lib_dirs, Libs} + ]}, + {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Default}])), + StrippedDefault = + case Libs of + [] -> {sys, []}; + _ -> {sys, [{lib_dirs, Libs}]} + end, + ?m({ok, StrippedDefault}, reltool:get_config(Pid)), + + ?m(ok, reltool:stop(Pid)), + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Generate releases + +create_release(TestInfo) when is_atom(TestInfo) -> + reltool_test_lib:tc_info(TestInfo); +create_release(_Config) -> + %% Configure the server + RelName = "Just testing...", + RelVsn = "1.0", + Config = + {sys, + [ + {lib_dirs, []}, + {boot_rel, RelName}, + {rel, RelName, RelVsn, [kernel, stdlib]} + ]}, + %% Generate release + ErtsVsn = erlang:system_info(version), + Apps = application:loaded_applications(), + {value, {_, _, KernelVsn}} = lists:keysearch(kernel, 1, Apps), + {value, {_, _, StdlibVsn}} = lists:keysearch(stdlib, 1, Apps), + Rel = {release, {RelName, RelVsn}, + {erts, ErtsVsn}, + [{kernel, KernelVsn}, + {stdlib, StdlibVsn}]}, + ?m({ok, Rel}, reltool:get_rel([{config, Config}], RelName)), + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Generate boot scripts + +create_script(TestInfo) when is_atom(TestInfo) -> + reltool_test_lib:tc_info(TestInfo); +create_script(_Config) -> + %% Configure the server + RelName = "Just testing", + RelVsn = "1.0", + Config = + {sys, + [ + {lib_dirs, []}, + {boot_rel, RelName}, + {rel, RelName, RelVsn, [stdlib, kernel]} + ]}, + {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Config}])), + + %% Generate release file + ErtsVsn = erlang:system_info(version), + Apps = application:loaded_applications(), + {value, {_, _, KernelVsn}} = lists:keysearch(kernel, 1, Apps), + {value, {_, _, StdlibVsn}} = lists:keysearch(stdlib, 1, Apps), + Rel = {release, + {RelName, RelVsn}, + {erts, ErtsVsn}, + [{stdlib, StdlibVsn}, {kernel, KernelVsn}]}, + ?m({ok, Rel}, reltool:get_rel(Pid, RelName)), + RelFile = RelName ++ ".rel", + ?m(ok, file:write_file(RelFile, io_lib:format("~p.\n", [Rel]))), + + %% Generate script file + ?m(ok, systools:make_script(RelName, [])), + ScriptFile = RelName ++ ".script", + {ok, [OrigScript]} = ?msym({ok, [_]}, file:consult(ScriptFile)), + {ok, Script} = ?msym({ok, _}, reltool:get_script(Pid, RelName)), + %% OrigScript2 = sort_script(OrigScript), + %% Script2 = sort_script(Script), + %% ?m(OrigScript2, Script2), + + ?m(equal, diff_script(OrigScript, Script)), + + %% Stop server + ?m(ok, reltool:stop(Pid)), + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Generate target system + +create_target(TestInfo) when is_atom(TestInfo) -> + reltool_test_lib:tc_info(TestInfo); +create_target(_Config) -> + %% Configure the server + RelName1 = "Just testing", + RelName2 = "Just testing with SASL", + RelVsn = "1.0", + Config = + {sys, + [ + {root_dir, code:root_dir()}, + {lib_dirs, []}, + {boot_rel, RelName2}, + {rel, RelName1, RelVsn, [stdlib, kernel]}, + {rel, RelName2, RelVsn, [sasl, stdlib, kernel]}, + {app, sasl, [{incl_cond, include}]} + ]}, + + %% Generate target file + TargetDir = "reltool_target_dir_development", + ?m(ok, reltool_utils:recursive_delete(TargetDir)), + ?m(ok, file:make_dir(TargetDir)), + ?m(ok, reltool:create_target([{config, Config}], TargetDir)), + + Erl = filename:join([TargetDir, "bin", "erl"]), + {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), + ?msym(ok, stop_node(Node)), + + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Generate embedded target system + +create_embedded(TestInfo) when is_atom(TestInfo) -> + reltool_test_lib:tc_info(TestInfo); +create_embedded(_Config) -> + %% Configure the server + RelName1 = "Just testing", + RelName2 = "Just testing with SASL", + RelVsn = "1.0", + Config = + {sys, + [ + {lib_dirs, []}, + {profile, embedded}, + {boot_rel, RelName2}, + {rel, RelName1, RelVsn, [stdlib, kernel]}, + {rel, RelName2, RelVsn, [sasl, stdlib, kernel]}, + {app, sasl, [{incl_cond, include}]} + ]}, + + %% Generate target file + TargetDir = "reltool_target_dir_embedded", + ?m(ok, reltool_utils:recursive_delete(TargetDir)), + ?m(ok, file:make_dir(TargetDir)), + ?m(ok, reltool:create_target([{config, Config}], TargetDir)), + + Erl = filename:join([TargetDir, "bin", "erl"]), + {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), + ?msym(ok, stop_node(Node)), + + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Generate standalone system + +create_standalone(TestInfo) when is_atom(TestInfo) -> + reltool_test_lib:tc_info(TestInfo); +create_standalone(_Config) -> + %% Configure the server + ExDir = code:lib_dir(reltool, examples), + EscriptName = "display_args", + Escript = filename:join([ExDir, EscriptName]), + Config = + {sys, + [ + {lib_dirs, []}, + {escript, Escript, [{incl_cond, include}]}, + {profile, standalone} + ]}, + + %% Generate target file + TargetDir = "reltool_target_dir_standalone", + ?m(ok, reltool_utils:recursive_delete(TargetDir)), + ?m(ok, file:make_dir(TargetDir)), + ?m(ok, reltool:create_target([{config, Config}], TargetDir)), + + BinDir = filename:join([TargetDir, "bin"]), + Erl = filename:join([BinDir, "erl"]), + {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), + RootDir = ?ignore(rpc:call(Node, code, root_dir, [])), + ?msym(ok, stop_node(Node)), + + Expected = iolist_to_binary(["Root dir: ", RootDir, "\n" + "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n", + "Smp: false\n", + "ExitCode:0"]), + io:format("Expected: ~s\n", [Expected]), + ?m(Expected, run(BinDir, EscriptName ++ " -arg1 arg2 arg3")), + + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Generate old type of target system + +create_old_target(TestInfo) when is_atom(TestInfo) -> + reltool_test_lib:tc_info(TestInfo); +create_old_target(_Config) -> + %% Configure the server + RelName1 = "Just testing", + RelName2 = "Just testing with SASL", + RelVsn = "1.0", + Config = + {sys, + [ + {lib_dirs, []}, + {boot_rel, RelName2}, + {rel, RelName1, RelVsn, [stdlib, kernel]}, + {rel, RelName2, RelVsn, [sasl, stdlib, kernel]}, + {relocatable, false}, % Implies explicit old style installation + {app, sasl, [{incl_cond, include}]} + ]}, + + %% Generate target file + TargetDir = "reltool_target_dir_old", + ?m(ok, reltool_utils:recursive_delete(TargetDir)), + ?m(ok, file:make_dir(TargetDir)), + ?m(ok, reltool:create_target([{config, Config}], TargetDir)), + + %% io:format("Will fail on Windows (should patch erl.ini)\n", []), + ?m(ok, reltool:install(RelName2, TargetDir)), + + Erl = filename:join([TargetDir, "bin", "erl"]), + {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), + ?msym(ok, stop_node(Node)), + + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Library functions + +erl_libs() -> + case os:getenv("ERL_LIBS") of + false -> []; + LibStr -> string:tokens(LibStr, ":;") + end. + +diff_script(Script, Script) -> + equal; +diff_script({script, Rel, Commands1}, {script, Rel, Commands2}) -> + diff_cmds(Commands1, Commands2); +diff_script({script, Rel1, _}, {script, Rel2, _}) -> + {error, {Rel1, Rel2}}. + +diff_cmds([Cmd | Commands1], [Cmd | Commands2]) -> + diff_cmds(Commands1, Commands2); +diff_cmds([Cmd1 | _Commands1], [Cmd2 | _Commands2]) -> + {diff, {expected, Cmd1}, {actual, Cmd2}}; +diff_cmds([], []) -> + equal. + +os_cmd(Cmd) when is_list(Cmd) -> + %% Call the plain os:cmd with an echo command appended to print command status + %% io:format("os:cmd(~p).\n", [Cmd]), + case os:cmd(Cmd++";echo \"#$?\"") of + %% There is (as far as I can tell) only one thing that will match this + %% and that is too silly to ever be used, but... + []-> + {99, []}; + Return-> + %% Find the position of the status code wich is last in the string + %% prepended with # + case string:rchr(Return, $#) of + + %% This happens only if the sh command pipe is somehow interrupted + 0-> + {98, Return}; + + Position-> + Result = string:left(Return,Position - 1), + Status = string:substr(Return,Position + 1, length(Return) - Position - 1), + {list_to_integer(Status), Result} + end + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Node handling + +start_node(Name, ErlPath) -> + FullName = full_node_name(Name), + CmdLine = mk_node_cmdline(Name, ErlPath), + io:format("Starting node ~p: ~s~n", [FullName, CmdLine]), + case open_port({spawn, CmdLine}, []) of + Port when is_port(Port) -> + unlink(Port), + erlang:port_close(Port), + case ping_node(FullName, 50) of + ok -> {ok, FullName}; + Other -> exit({failed_to_start_node, FullName, Other}) + end; + Error -> + exit({failed_to_start_node, FullName, Error}) + end. + +stop_node(Node) -> + monitor_node(Node, true), + spawn(Node, fun () -> halt() end), + receive {nodedown, Node} -> ok end. + +mk_node_cmdline(Name) -> + Prog = case catch init:get_argument(progname) of + {ok,[[P]]} -> P; + _ -> exit(no_progname_argument_found) + end, + mk_node_cmdline(Name, Prog). + +mk_node_cmdline(Name, Prog) -> + Static = "-detached -noinput", + Pa = filename:dirname(code:which(?MODULE)), + NameSw = case net_kernel:longnames() of + false -> "-sname "; + true -> "-name "; + _ -> exit(not_distributed_node) + end, + {ok, Pwd} = file:get_cwd(), + NameStr = atom_to_list(Name), + Prog ++ " " + ++ Static ++ " " + ++ NameSw ++ " " ++ NameStr ++ " " + ++ "-pa " ++ Pa ++ " " + ++ "-env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ NameStr ++ " " + ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()). + +full_node_name(PreName) -> + HostSuffix = lists:dropwhile(fun ($@) -> false; (_) -> true end, + atom_to_list(node())), + list_to_atom(atom_to_list(PreName) ++ HostSuffix). + +ping_node(_Node, 0) -> + {error, net_adm}; +ping_node(Node, N) when is_integer(N), N > 0 -> + case catch net_adm:ping(Node) of + pong -> + wait_for_process(Node, code_server, 50); + _ -> + timer:sleep(1000), + ping_node(Node, N-1) + end. + +wait_for_process(_Node, Name, 0) -> + {error, Name}; +wait_for_process(Node, Name, N) when is_integer(N), N > 0 -> + case rpc:call(Node, erlang, whereis, [Name]) of + undefined -> + timer:sleep(1000), + wait_for_process(Node, Name, N-1); + {badrpc, _} = Reason -> + erlang:error({Reason, Node}); + Pid when is_pid(Pid) -> + ok + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Run escript + +run(Dir, Cmd0) -> + Cmd = case os:type() of + {win32,_} -> filename:nativename(Dir) ++ "\\" ++ Cmd0; + _ -> Cmd0 + end, + do_run(Dir, Cmd). + +run(Dir, Opts, Cmd0) -> + Cmd = case os:type() of + {win32,_} -> Opts ++ " " ++ filename:nativename(Dir) ++ "\\" ++ Cmd0; + _ -> Opts ++ " " ++ Dir ++ "/" ++ Cmd0 + end, + do_run(Dir, Cmd). + +do_run(Dir, Cmd) -> + io:format("Run: ~p\n", [Cmd]), + Env = [{"PATH",Dir++":"++os:getenv("PATH")}], + Port = open_port({spawn,Cmd}, [exit_status,eof,in,{env,Env}]), + Res = get_data(Port, []), + receive + {Port,{exit_status,ExitCode}} -> + iolist_to_binary([Res,"ExitCode:"++integer_to_list(ExitCode)]) + end. + +get_data(Port, SoFar) -> + receive + {Port,{data,Bytes}} -> + get_data(Port, [SoFar|Bytes]); + {Port,eof} -> + erlang:port_close(Port), + SoFar + end. + +expected_output([data_dir|T], Data) -> + Slash = case os:type() of + {win32,_} -> "\\"; + _ -> "/" + end, + [filename:nativename(Data)++Slash|expected_output(T, Data)]; +expected_output([H|T], Data) -> + [H|expected_output(T, Data)]; +expected_output([], _) -> + []; +expected_output(Bin, _) when is_binary(Bin) -> + Bin. diff --git a/lib/reltool/test/reltool_test_lib.erl b/lib/reltool/test/reltool_test_lib.erl new file mode 100644 index 0000000000..25978294ee --- /dev/null +++ b/lib/reltool/test/reltool_test_lib.erl @@ -0,0 +1,329 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% + +-module(reltool_test_lib). +-compile(export_all). + +-include("reltool_test_lib.hrl"). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +init_per_suite(Config) when is_list(Config)-> + incr_timetrap(Config, 5). + +end_per_suite(Config) when is_list(Config)-> + ok. + +incr_timetrap(Config, Times) -> + Key = tc_timeout, + KeyPos = 1, + NewTime = + case lists:keysearch(Key, KeyPos, Config) of + {value, {Key, OldTime}} -> + (timer:minutes(1) + OldTime) * Times; + false -> + timer:minutes(1) * Times + end, + lists:keystore(Key, KeyPos, Config, {Key, NewTime}). + +set_kill_timer(Config) -> + case init:get_argument(reltool_test_timeout) of + {ok, _} -> + Config; + _ -> + Time = + case lookup_config(tc_timeout, Config) of + [] -> + timer:minutes(5); + ConfigTime when is_integer(ConfigTime) -> + ConfigTime + end, + WatchDog = test_server:timetrap(Time), + [{kill_timer, WatchDog} | Config] + end. + +reset_kill_timer(Config) -> + DogKiller = + case get(reltool_test_server) of + true -> + fun(P) when is_pid(P) -> P ! stop; + (_) -> ok + end; + _ -> + fun(Ref) -> test_server:timetrap_cancel(Ref) end + end, + case lists:keysearch(kill_timer, 1, Config) of + {value, {kill_timer, WatchDog}} -> + DogKiller(WatchDog), + lists:keydelete(kill_timer, 1, Config); + _ -> + Config + end. + +lookup_config(Key,Config) -> + case lists:keysearch(Key, 1, Config) of + {value,{Key,Val}} -> + Val; + _ -> + [] + end. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +wx_init_per_suite(Config) -> + {_Pid, Ref} = + spawn_monitor(fun() -> + %% Avoid test case crash if wx master process dies + process_flag(trap_exit, true), + try + case os:type() of + {unix,darwin} -> + exit({skipped, "Can not test on MacOSX"}); + {unix, _} -> + io:format("DISPLAY ~s~n", [os:getenv("DISPLAY")]), + case proplists:get_value(xserver, Config, none) of + none -> ignore; + Server -> os:putenv("DISPLAY", Server) + end; + _ -> + ignore + end, + wx:new(), + wx:destroy() + catch + error:undef -> + exit({skipped, "No wx compiled for this platform"}); + _:Reason -> + exit({skipped, lists:flatten(io_lib:format("Start wx failed: ~p", [Reason]))}) + end, + exit(normal) + end), + receive + {'DOWN', Ref, _, _, normal} -> + init_per_suite(Config); + {'DOWN', Ref, _, _, {skipped, _} = Skipped} -> + Skipped; + {'DOWN', Ref, _, _, Reason} -> + exit({wx_init_per_suite, Reason}) + after timer:minutes(1) -> + exit({wx_init_per_suite, timeout}) + end. + +wx_end_per_suite(Config) -> + end_per_suite(Config). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +init_per_testcase(_Func, Config) when is_list(Config) -> + set_kill_timer(Config), + global:register_name(reltool_global_logger, group_leader()), + Config. + +end_per_testcase(_Func, Config) when is_list(Config) -> + global:unregister_name(reltool_global_logger), + reset_kill_timer(Config), + Config. + +%% Backwards compatible with test_server +tc_info(suite) -> []; +tc_info(doc) -> "". + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Use ?log(Format, Args) as wrapper +log(Format, Args, LongFile, Line) -> + File = filename:basename(LongFile), + Format2 = lists:concat([File, "(", Line, ")", ": ", Format]), + log(Format2, Args). + +log(Format, Args) -> + case global:whereis_name(reltool_global_logger) of + undefined -> + io:format(user, Format, Args); + Pid -> + io:format(Pid, Format, Args) + end. + +verbose(Format, Args, File, Line) -> + Arg = reltool_test_verbose, + case get(Arg) of + false -> + ok; + true -> + log(Format, Args, File, Line); + undefined -> + case init:get_argument(Arg) of + {ok, List} when is_list(List) -> + case lists:last(List) of + ["true"] -> + put(Arg, true), + log(Format, Args, File, Line); + _ -> + put(Arg, false), + ok + end; + _ -> + put(Arg, false), + ok + end + end. + +error(Format, Args, File, Line) -> + global:send(reltool_global_logger, {failed, File, Line}), + Fail = {filename:basename(File),Line,Args}, + case global:whereis_name(reltool_test_case_sup) of + undefined -> ignore; + Pid -> Pid ! Fail + %% global:send(reltool_test_case_sup, Fail), + end, + log("<ERROR>~n" ++ Format, Args, File, Line). + + +pick_msg() -> + receive + Message -> Message + after 4000 -> timeout + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Utility functions + +user_available(Config) -> + false /= proplists:get_value(user, Config, false). + + +wx_destroy(Frame, Config) -> + case proplists:get_value(user, Config, false) of + false -> + timer:sleep(100), + ?m(ok, wxFrame:destroy(Frame)), + ?m(ok, wx:destroy()); + true -> + timer:sleep(500), + ?m(ok, wxFrame:destroy(Frame)), + ?m(ok, wx:destroy()); + step -> %% Wait for user to close window + ?m(ok, wxEvtHandler:connect(Frame, close_window, [{skip,true}])), + wait_for_close() + end. + +wait_for_close() -> + receive + #wx{event=#wxClose{}} -> + ?log("Got close~n",[]), + ?m(ok, wx:destroy()); + #wx{obj=Obj, event=Event} -> + try + Name = wxTopLevelWindow:getTitle(Obj), + ?log("~p Event: ~p~n", [Name, Event]) + catch _:_ -> + ?log("Event: ~p~n", [Event]) + end, + wait_for_close(); + Other -> + ?log("Unexpected: ~p~n", [Other]), + wait_for_close() + end. + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% A small test server, which can be run standalone in a shell + +run_test(Test = {_,_},Config) -> + run_test([Test],Config); +run_test([{Module, TC} | Rest], Config) -> + log("\n\n=== Eval test suite: ~w ===~n", [Module]), + case catch Module:init_per_suite(Config) of + {skipped, Reason} -> + log("Test suite skipped: ~s~n", [Reason]), + [{skipped, Reason}]; + NewConfig when is_list(NewConfig) -> + Res = + if + TC =:= all -> + [do_run_test(Module, Test, NewConfig) || Test <- Module:all()]; + is_list(TC) -> + [do_run_test(Module, Test, NewConfig) || Test <- TC]; + true -> + [do_run_test(Module, TC, NewConfig)] + end, + Module:end_per_suite(NewConfig), + Res ++ run_test(Rest, NewConfig); + Error -> + ?error("Test suite skipped: ~w~n", [Error]), + [{skipped, Error}] + end; +run_test([], _Config) -> + []. + +do_run_test(Module, all, Config) -> + All = [{Module, Test} || Test <- Module:all()], + run_test(All, Config); +do_run_test(Module, TestCase, Config) -> + log("Eval test case: ~w~n", [{Module, TestCase}]), + Sec = timer:seconds(1) * 1000, + {T, Res} = + timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]), + log("Tested ~w in ~w sec~n", [TestCase, T div Sec]), + {T div Sec, Res}. + +eval_test_case(Mod, Fun, Config) -> + flush(), + global:register_name(reltool_test_case_sup, self()), + Flag = process_flag(trap_exit, true), + Pid = spawn_link(?MODULE, test_case_evaluator, [Mod, Fun, [Config]]), + R = wait_for_evaluator(Pid, Mod, Fun, Config), + global:unregister_name(reltool_test_case_sup), + process_flag(trap_exit, Flag), + R. + +test_case_evaluator(Mod, Fun, [Config]) -> + NewConfig = Mod:init_per_testcase(Fun, Config), + R = apply(Mod, Fun, [NewConfig]), + Mod:fin_per_testcase(Fun, NewConfig), + exit({test_case_ok, R}). + +wait_for_evaluator(Pid, Mod, Fun, Config) -> + receive + {'EXIT', Pid, {test_case_ok, _PidRes}} -> + Errors = flush(), + Res = + case Errors of + [] -> ok; + Errors -> failed + end, + {Res, {Mod, Fun}, Errors}; + {'EXIT', Pid, {skipped, Reason}} -> + log("<WARNING> Test case ~w skipped, because ~p~n", + [{Mod, Fun}, Reason]), + Mod:fin_per_testcase(Fun, Config), + {skip, {Mod, Fun}, Reason}; + {'EXIT', Pid, Reason} -> + log("<ERROR> Eval process ~w exited, because\n\t~p~n", + [{Mod, Fun}, Reason]), + Mod:fin_per_testcase(Fun, Config), + {crash, {Mod, Fun}, Reason} + end. + +flush() -> + receive Msg -> [Msg | flush()] + after 0 -> [] + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/reltool/test/reltool_test_lib.hrl b/lib/reltool/test/reltool_test_lib.hrl new file mode 100644 index 0000000000..93134144ea --- /dev/null +++ b/lib/reltool/test/reltool_test_lib.hrl @@ -0,0 +1,91 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% + +-include_lib("wx/include/wx.hrl"). + +-define(log(Format,Args), reltool_test_lib:log(Format,Args,?FILE,?LINE)). +-define(warning(Format,Args), ?log("<WARNING>\n " ++ Format,Args)). +-define(error(Format,Args), reltool_test_lib:error(Format,Args,?FILE,?LINE)). +-define(verbose(Format,Args), reltool_test_lib:verbose(Format,Args,?FILE,?LINE)). + +-define(fatal(Format,Args), + ?error(Format, Args), + exit({test_case_fatal, Format, Args, ?FILE, ?LINE})). + +-define(skip(Format,Args), + ?warning(Format, Args), + exit({skipped, ?flat_format(Format, Args)})). + +-define(ignore(Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + ?verbose("ok: ~p\n",[AcTuAlReS]), + AcTuAlReS + end()). + +-define(msym(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + ?verbose("ok: ~p\n",[AcTuAlReS]), + AcTuAlReS; + _ -> + reltool_test_lib:error("Not matching actual result was:\n ~p \nExpected ~s\n", + [AcTuAlReS, ??ExpectedRes], + ?FILE, ?LINE), + AcTuAlReS + end + end()). + +-define(m(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + ?verbose("ok: ~p\n",[AcTuAlReS]), + AcTuAlReS; + _ -> + reltool_test_lib:error("Not matching actual result was:\n\t~p \nExpected:\n\t~p\n", + [AcTuAlReS, ExpectedRes], + ?FILE, ?LINE), + AcTuAlReS + end + end()). + +-define(m_receive(ExpectedMsg), + ?m(ExpectedMsg,reltool_test_lib:pick_msg())). + +-define(m_multi_receive(ExpectedMsgs), + fun() -> + TmPeXpCtEdMsGs = lists:sort(ExpectedMsgs), + AcTuAlReS = + lists:sort(lists:map(fun(_) -> + reltool_test_lib:pick_msg() + end, TmPeXpCtEdMsGs)), + case AcTuAlReS of + TmPeXpCtEdMsGs -> + ?verbose("ok: ~p\n",[AcTuAlReS]), + AcTuAlReS; + _ -> + reltool_test_lib:error("Not matching actual result was:\n ~p \nExpected ~p\n", + [AcTuAlReS, ExpectedMsgs], + ?FILE, ?LINE), + AcTuAlReS + end + end()). diff --git a/lib/reltool/test/reltool_wx_SUITE.erl b/lib/reltool/test/reltool_wx_SUITE.erl new file mode 100644 index 0000000000..2e2b355e07 --- /dev/null +++ b/lib/reltool/test/reltool_wx_SUITE.erl @@ -0,0 +1,62 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% + +-module(reltool_wx_SUITE). + +-export([all/0, init_per_suite/1, end_per_suite/1, + init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]). + +-compile(export_all). + +-include("reltool_test_lib.hrl"). + +%% Initialization functions. +init_per_suite(Config) -> + reltool_test_lib:wx_init_per_suite(Config). + +end_per_suite(Config) -> + reltool_test_lib:wx_end_per_suite(Config). + +init_per_testcase(Func,Config) -> + reltool_test_lib:init_per_testcase(Func,Config). +end_per_testcase(Func,Config) -> + reltool_test_lib:end_per_testcase(Func,Config). +fin_per_testcase(Func,Config) -> %% For test_server + reltool_test_lib:end_per_testcase(Func,Config). + +%% SUITE specification +all() -> + all(suite). +all(suite) -> + [ + start_all_windows + ]. + +%% The test cases + +%% Display all windows and see if something crashes +start_all_windows(TestInfo) when is_atom(TestInfo) -> + reltool_test_lib:tc_info(TestInfo); +start_all_windows(_Config) -> + {ok, SysPid} = ?msym({ok, _}, reltool:start([{trap_exit, false}])), + {ok, AppPid} = ?msym({ok, _}, reltool_sys_win:open_app(SysPid, stdlib)), + ?msym({ok, _}, reltool_app_win:open_mod(AppPid, escript)), + timer:sleep(timer:seconds(10)), + ?m(ok, reltool:stop(SysPid)), + + ok. diff --git a/lib/reltool/test/rtt b/lib/reltool/test/rtt new file mode 100755 index 0000000000..2411195338 --- /dev/null +++ b/lib/reltool/test/rtt @@ -0,0 +1,55 @@ +#! /bin/sh -f +# %CopyrightBegin% +# +# Copyright Ericsson AB 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% + +# Usage: rtt [-cerl] <args to erlang startup script> + +emu=erl +while [ $# -gt 0 ]; do + case "$1" in + "-cerl") + shift + emu=cerl + ;; + *) + break + ;; + esac +done + +log=test_log_$$ +latest=test_log_latest +args=${1+"$@"} + +erlcmd="$emu -sname test_server -smp -pa ../../reltool/ebin $p $args -reltool_test_verbose true -reltool_test_timeout" + +echo "Give the following command in order to see the outcome:" +echo "" +echo " less $log" + +rm "$latest" 2>/dev/null +ln -s "$log" "$latest" +touch "$log" + +ostype=`uname -s` +if [ "$ostype" = "SunOS" ] ; then + /usr/openwin/bin/xterm -T "Testing reltool" -l -lf "$log" -e $erlcmd & +else + xterm -T "Testing reltool" -e script -f -c "$erlcmd" "$log" & +fi + +tail -f "$log" | egrep 'Eval|<ERROR>|NYI' diff --git a/lib/reltool/test/rtt.erl b/lib/reltool/test/rtt.erl new file mode 100644 index 0000000000..6755b8400f --- /dev/null +++ b/lib/reltool/test/rtt.erl @@ -0,0 +1,154 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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% + +-module(rtt). +-compile(export_all). + +%% Modules or suites can be shortcuts, for example server expands to reltool_server_SUITE. +%% +%% t(Tests) run reltool testcases. +%% Tests can be module, {module, test_case} or [module|{module,test_case}] + +t() -> + t(read_test_case()). +t(Test) -> + t(Test, []). + +t(Mod, TC) when is_atom(Mod), is_atom(TC) -> + t({Mod,TC}, []); +t(all, Config) when is_list(Config) -> + Fs = filelib:wildcard("reltool_*_SUITE.erl"), + t([list_to_atom(filename:rootname(File)) || File <- Fs], Config); +t(Test,Config) when is_list(Config) -> + Tests = resolve(Test), + write_test_case(Test), + Res = reltool_test_lib:run_test(Tests, Config), + append_test_case_info(Test, Res). + +user() -> + user(read_test_case()). +user(Mod) -> + t(Mod, [{user,step}]). +user(Mod,Tc) when is_atom(Tc) -> + t({Mod,Tc}, [{user,step}]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Resolves the name of test suites and test cases +%% according to the alias definitions. Single atoms +%% are assumed to be the name of a test suite. + +resolve(Suite0) when is_atom(Suite0) -> + case alias(Suite0) of + Suite when is_atom(Suite) -> + {Suite, all}; + {Suite, Case} -> + {Suite, Case} + end; +resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) -> + case alias(Suite0) of + Suite when is_atom(Suite) -> + {Suite, Case}; + {Suite, Case2} -> + {Suite, Case2} + end; +resolve(List) when is_list(List) -> + [resolve(Case) || Case <- List]. + +alias(Suite) when is_atom(Suite) -> + Str = atom_to_list(Suite), + case {Str, lists:reverse(Str)} of + {"reltool" ++ _, "ETIUS" ++ _} -> + Suite; + _ -> + list_to_atom("reltool_" ++ Str ++ "_SUITE") + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +config_fname() -> + "reltool_test_case_config". + +%% Read default config file +read_config() -> + Fname = config_fname(), + reltool_test_lib:log("Consulting file ~s...~n", [Fname]), + case file:consult(Fname) of + {ok, Config} -> + reltool_test_lib:log("Read config ~w~n", [Config]), + Config; + _Error -> + Config = reltool_test_lib:default_config(), + reltool_test_lib:log("<>WARNING<> Using default config: ~w~n", [Config]), + Config + end. + +%% Write new default config file +write_config(Config) when is_list(Config) -> + Fname = config_fname(), + {ok, Fd} = file:open(Fname, write), + write_list(Fd, Config), + file:close(Fd). + +write_list(Fd, [H | T]) -> + ok = io:format(Fd, "~p.~n",[H]), + write_list(Fd, T); +write_list(_, []) -> + ok. + +test_case_fname() -> + "reltool_test_case_info". + +%% Read name of test case +read_test_case() -> + Fname = test_case_fname(), + case file:open(Fname, [read]) of + {ok, Fd} -> + Res = io:read(Fd, []), + file:close(Fd), + case Res of + {ok, TestCase} -> + reltool_test_lib:log("Using test case ~w from file ~s~n", + [TestCase, Fname]), + TestCase; + {error, _} -> + default_test_case(Fname) + end; + {error, _} -> + default_test_case(Fname) + end. + +default_test_case(Fname) -> + TestCase = all, + reltool_test_lib:log("<>WARNING<> Cannot read file ~s, " + "using default test case: ~w~n", + [Fname, TestCase]), + TestCase. + +write_test_case(TestCase) -> + Fname = test_case_fname(), + {ok, Fd} = file:open(Fname, write), + ok = io:format(Fd, "~p.~n",[TestCase]), + file:close(Fd). + +append_test_case_info(TestCase, TestCaseInfo) -> + Fname = test_case_fname(), + {ok, Fd} = file:open(Fname, [read, write]), + ok = io:format(Fd, "~p.~n",[TestCase]), + ok = io:format(Fd, "~p.~n",[TestCaseInfo]), + file:close(Fd), + TestCaseInfo. diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk index d5ca40619c..118827a449 100644 --- a/lib/reltool/vsn.mk +++ b/lib/reltool/vsn.mk @@ -1,24 +1,7 @@ -# This is an -*-makefile-*- file. -# %CopyrightBegin% -# -# Copyright Ericsson AB 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% +RELTOOL_VSN = 0.5.3 -RELTOOL_VSN = 0.5.2 - -TICKETS = OTP-8254 +TICKETS = OTP-8057 +TICKETS_0_5_2 = OTP-8254 TICKETS_0_5_1 = OTP-8199 TICKETS_0_5 = OTP-7949 TICKETS_0_2_2 = OTP-7999 |