1: %%
    2: %% %CopyrightBegin%
    3: %% 
    4: %% Copyright Ericsson AB 1997-2012. All Rights Reserved.
    5: %% 
    6: %% The contents of this file are subject to the Erlang Public License,
    7: %% Version 1.1, (the "License"); you may not use this file except in
    8: %% compliance with the License. You should have received a copy of the
    9: %% Erlang Public License along with this software. If not, it can be
   10: %% retrieved online at http://www.erlang.org/.
   11: %% 
   12: %% Software distributed under the License is distributed on an "AS IS"
   13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
   14: %% the License for the specific language governing rights and limitations
   15: %% under the License.
   16: %% 
   17: %% %CopyrightEnd%
   18: %%
   19: %%
   20: -module(orber_SUITE).
   21: -include_lib("test_server/include/test_server.hrl").
   22: 
   23: -define(default_timeout, ?t:minutes(15)).
   24: -define(application, orber).
   25: 
   26: % Test server specific exports
   27: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 
   28: 	 init_per_group/2,end_per_group/2]).
   29: -export([init_per_testcase/2, end_per_testcase/2]).
   30: 
   31: % Test cases must be exported.
   32: -export([app_test/1, undefined_functions/1, install_load_order/1,
   33: 	 install_local_content/1, 
   34:          otp_9887/1]).
   35: 
   36: %% Exporting error handler callbacks for use in otp_9887
   37: -export([init/1, handle_event/2]).
   38: 
   39: %%
   40: %% all/1
   41: %%
   42: suite() -> [{ct_hooks,[ts_install_cth]}].
   43: 
   44: all() -> 
   45:     [app_test, undefined_functions, install_load_order,
   46:      install_local_content,
   47:      otp_9887].
   48: 
   49: groups() -> 
   50:     [].
   51: 
   52: init_per_suite(Config) ->
   53:     Config.
   54: 
   55: end_per_suite(_Config) ->
   56:     ok.
   57: 
   58: init_per_group(_GroupName, Config) ->
   59:     Config.
   60: 
   61: end_per_group(_GroupName, Config) ->
   62:     Config.
   63: 
   64: 
   65: init_per_testcase(_Case, Config) ->
   66:     ?line Dog=test_server:timetrap(?default_timeout),
   67:     [{watchdog, Dog}|Config].
   68: 
   69: end_per_testcase(_Case, Config) ->
   70:     Dog=?config(watchdog, Config),
   71:     test_server:timetrap_cancel(Dog),
   72:     ok.
   73: 
   74: %
   75: % Test cases starts here.
   76: %
   77: app_test(doc) -> [];
   78: app_test(suite) -> [];
   79: app_test(_Config) ->
   80:     ?line ok=?t:app_test(orber),
   81:     ok.
   82: 
   83: otp_9887(_Config) ->
   84:     orber:jump_stop(),
   85:     application:set_env(orber, orber_debug_level, 10),
   86:     orber:jump_start([]),
   87:     
   88:     mnesia:create_table(orber_light_ifr, []),
   89: 
   90:     error_logger:add_report_handler(?MODULE,[self()]),
   91:     catch orber_ifr:get_module(foo, bar),
   92:     
   93:     receive
   94: 	{stolen,Reason} ->
   95:             {error,_Pid1, {_Pid2, _ErrorString, ArgumentList}} = Reason,
   96:             5 = length(ArgumentList)
   97:     after 500 ->
   98:             test_server:fail("OTP_9887 TIMED OUT")
   99:     end,
  100: 
  101:     orber:jump_stop(),
  102:     ok.
  103: 
  104: %% Install Orber using the load_order option.
  105: install_load_order(suite) ->
  106:     [];
  107: install_load_order(doc) ->
  108:     [];
  109: install_load_order(_Config) ->
  110:     orber:jump_stop(),
  111:     case catch install_load_order2() of
  112: 	ok ->
  113: 	    orber:jump_stop();
  114: 	What ->
  115: 	    orber:jump_stop(),
  116: 	    exit(What)
  117:     end.
  118: 
  119: install_load_order2() ->
  120:     application:load(orber),
  121:     mnesia:start(),
  122:     corba:orb_init([{iiop_port, 0}]),
  123:     orber:install([node()], [{ifr_storage_type, ram_copies},
  124: 			     {load_order, 10}]),
  125:     orber:start(),
  126:     [H|_] = orber:get_tables(),
  127:     10 = mnesia:table_info(H, load_order),
  128:     ok.
  129: 
  130: %% Install Orber using the local_content option.
  131: install_local_content(suite) ->
  132:     [];
  133: install_local_content(doc) ->
  134:     [];
  135: install_local_content(_Config) ->
  136:     orber:jump_stop(),
  137:     case catch install_local_content2() of
  138: 	ok ->
  139: 	    orber:jump_stop();
  140: 	What ->
  141: 	    orber:jump_stop(),
  142: 	    exit(What)
  143:     end.
  144: 
  145: install_local_content2() ->
  146:     application:load(orber),
  147:     mnesia:start(),
  148:     corba:orb_init([{iiop_port, 0}]),
  149:     orber:install([node()], [{ifr_storage_type, ram_copies},
  150: 			     {local_content, true}]),
  151:     orber:start(),
  152:     [H|_] = orber:get_tables(),
  153:     true = mnesia:table_info(H, local_content),
  154:     ok.
  155: 
  156: 
  157: 
  158: %% Check for undefined functions
  159: undefined_functions(suite) ->
  160:     [];
  161: undefined_functions(doc) ->
  162:     [];
  163: undefined_functions(_Config) ->
  164:     App            = orber,
  165:     Root           = code:root_dir(),
  166:     LibDir         = code:lib_dir(App),
  167:     EbinDir        = filename:join([LibDir,"ebin"]),
  168:     AppFilePath    = filename:join([LibDir,"ebin", "orber.app"]),
  169:     {ok, [{application,orber,AppFile}]} = file:consult(AppFilePath),
  170:     io:format("Using ~p~n~p~n", [AppFilePath, AppFile]),
  171:     Mods           = key1search(modules, AppFile),
  172:     XRefTestName   = undef_funcs_make_name(App, xref_test_name),
  173:     {ok, XRef}     = xref:start(XRefTestName),
  174:     ok             = xref:set_default(XRef,
  175:                                       [{verbose,false},{warnings,false}]),
  176:     XRefName       = undef_funcs_make_name(App, xref_name),
  177:     {ok, XRefName} = xref:add_release(XRef, Root, {name,XRefName}),
  178:     {ok, App}      = xref:replace_application(XRef, App, EbinDir),
  179:     {ok, Undefs}   = xref:analyze(XRef, undefined_function_calls),
  180:     xref:stop(XRef),
  181:     analyze_undefined_function_calls(Undefs, Mods, []).
  182:  
  183: analyze_undefined_function_calls([], _, []) ->
  184:     ok;
  185: analyze_undefined_function_calls([], _, AppUndefs) ->
  186:     exit({suite_failed, {undefined_function_calls, AppUndefs}});
  187: analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs],
  188:                                  AppModules, AppUndefs) ->
  189:     %% Check that this module is our's
  190:     case lists:member(Mod,AppModules) of
  191:         true ->
  192:             {Calling,Called} = AppUndef,
  193:             {Mod1,Func1,Ar1} = Calling,
  194:             {Mod2,Func2,Ar2} = Called,
  195:             io:format("undefined function call: "
  196:                       "~n   ~w:~w/~w calls ~w:~w/~w~n",
  197:                       [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
  198:             analyze_undefined_function_calls(Undefs, AppModules,
  199:                                              [AppUndef|AppUndefs]);
  200:         false ->
  201:             io:format("dropping ~p~n", [Mod]),
  202:             analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
  203:     end.
  204:  
  205: %% This function is used simply to avoid cut-and-paste errors later...
  206: undef_funcs_make_name(App, PostFix) ->
  207:     list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)).
  208: 
  209: key1search(Key, L) ->
  210:     case lists:keysearch(Key, 1, L) of
  211:         false ->
  212:             fail({not_found, Key, L});
  213:         {value, {Key, Value}} ->
  214:             Value
  215:     end.
  216: 
  217: fail(Reason) ->
  218:     exit({suite_failed, Reason}).
  219: 
  220: %% Error handler 
  221: 
  222: init([Proc]) -> {ok,Proc}.
  223: 
  224: handle_event(Event, Proc) -> 
  225:     Proc ! {stolen,Event},
  226:     {ok,Proc}.