1: %%
    2: %% %CopyrightBegin%
    3: %%
    4: %% Copyright Ericsson AB 1998-2013. 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: %%
   21: -module(int_SUITE).
   22: -include_lib("test_server/include/test_server.hrl").
   23: 
   24: %% Test server specific exports
   25: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 
   26: 	 init_per_group/2,end_per_group/2]).
   27: -export([init_per_testcase/2, end_per_testcase/2]).
   28: 
   29: %% Test cases
   30: -export([interpret/1, guards/1, interpretable/1]).
   31: -export([ append_1/1, append_2/1, member/1, reverse/1]).
   32: 
   33: %% Default timetrap timeout (set in init_per_testcase)
   34: -define(default_timeout, ?t:minutes(1)).
   35: 
   36: init_per_testcase(interpretable, Config) ->
   37:     ?line Dog=test_server:timetrap(?default_timeout),
   38:     [{watchdog, Dog}|Config];
   39: init_per_testcase(_Case, Config) ->
   40: 
   41:     %% Interpret some existing and non-existing modules
   42:     ?line DataDir = ?config(data_dir, Config),
   43:     ?line {module, lists1} = int:i(filename:join([DataDir,lists1])),
   44:     ?line {module, guards} = int:i(filename:join([DataDir,guards])),
   45: 
   46:     ?line Dog=test_server:timetrap(?default_timeout),
   47:     [{watchdog, Dog}|Config].
   48: 
   49: end_per_testcase(interpretable, Config) ->
   50:     ?line Dog=?config(watchdog, Config),
   51:     ?line test_server:timetrap_cancel(Dog),
   52:     ok;
   53: end_per_testcase(_Case, Config) ->
   54: 
   55:     %% Quit interpreting
   56:     ?line ok = int:n(lists1),
   57:     ?line ok = int:n(guards),
   58: 
   59:     ?line Dog=?config(watchdog, Config),
   60:     ?line test_server:timetrap_cancel(Dog),
   61:     ?line ok.
   62: 
   63: suite() -> [{ct_hooks,[ts_install_cth]}].
   64: 
   65: all() -> 
   66:     [interpret, guards, {group, list_suite}, interpretable].
   67: 
   68: groups() -> 
   69:     [{list_suite, [], [{group, append}, reverse, member]},
   70:      {append, [], [append_1, append_2]}].
   71: 
   72: init_per_suite(Config) ->
   73:     Config.
   74: 
   75: end_per_suite(_Config) ->
   76:     ok.
   77: 
   78: init_per_group(_GroupName, Config) ->
   79:     Config.
   80: 
   81: end_per_group(_GroupName, Config) ->
   82:     Config.
   83: 
   84: 
   85: interpret(suite) ->
   86:     [];
   87: interpret(doc) ->
   88:     ["Interpreting modules"];
   89: interpret(Config) when is_list(Config) ->
   90:     ?line int:n(int:interpreted()),
   91: 
   92:     %% Interpret some existing and non-existing modules
   93:     ?line DataDir = ?config(data_dir, Config),
   94:     ?line {module, lists1} = int:i(filename:join([DataDir,lists1])),
   95:     ?line {module, ordsets1} = int:i(filename:join([DataDir,ordsets1])),
   96:     ?line error = int:i(non_existent_module),
   97: 
   98:     %% Check that the interpreter has the right view.
   99:     ?line ExpectedResult = lists:sort([lists1, ordsets1]),
  100:     ?line Result = int:interpreted(),
  101:     ?line ExpectedResult = lists:sort(Result),
  102: 
  103:     %% Uniterpret the modules.
  104:     ?line ok = int:n(non_existent_module),
  105:     ?line ok = int:n(lists1),
  106:     ?line [ordsets1] = int:interpreted(),
  107:     ?line ok = int:n("ordsets1"),
  108:     ?line [] = int:interpreted(),
  109: 
  110:     ok.
  111: 
  112: guards(suite) ->
  113:     [];
  114: guards(doc) ->
  115:     "Evaluate guards.";
  116: guards(Config) when is_list(Config) ->
  117:     ok = guards:guards().
  118: 
  119: 
  120: 
  121: 
  122: append_1(suite) ->
  123:     [];
  124: append_1(doc) ->
  125:     [];
  126: append_1(Config) when is_list(Config) ->
  127:     ?line test_server:format("In append_1~n"),
  128:     ?line test_server:format("code:which(lists1)=~p~n",
  129: 			     [code:which(lists1)]),
  130:     ?line test_server:format("lists1:append([a],[b])=~p~n",
  131: 			     [spawn_eval(lists1,append,[[a],[b]])]),
  132: 
  133:     ?line "abcdef"=spawn_eval(lists1,append,[["abc","def"]]),
  134:     ?line [hej, du,[glade, [bagare]]]=
  135: 	spawn_eval(lists1,append,[[[hej], [du], [[glade, [bagare]]]]]),
  136:     ?line [10, [elem]]=spawn_eval(lists1,append,[[[10], [[elem]]]]),
  137:     ok.
  138: 
  139: append_2(suite) ->
  140:     [];
  141: append_2(doc) ->
  142:     [];
  143: append_2(Config) when is_list(Config) ->
  144:     ?line test_server:format("In append_2~n"),
  145:     ?line test_server:format("code:which(lists1)=~p~n",
  146: 			     [code:which(lists1)]),
  147: 
  148:     ?line "abcdef"=spawn_eval(lists1,append,["abc", "def"]),
  149:     ?line [hej, du]=spawn_eval(lists1,append,[[hej], [du]]),
  150:     ?line [10, [elem]]=spawn_eval(lists1,append,[[10], [[elem]]]),
  151:     ok.
  152: 
  153: reverse(suite) ->
  154:     [];
  155: reverse(doc) ->
  156:     [];
  157: reverse(Config) when is_list(Config) ->
  158:     ?line ok=reverse_test(0),
  159:     ?line ok=reverse_test(1),
  160:     ?line ok=reverse_test(2),
  161:     ?line ok=reverse_test(537),
  162:     ok.
  163: 
  164: reverse_test(0) ->
  165:     case spawn_eval(lists1,reverse,[[]]) of
  166: 	[] ->
  167: 	    ok;
  168: 	_Other ->
  169: 	    error
  170:     end;
  171: reverse_test(Num) ->
  172:     List=spawn_eval(lists1,reverse,
  173: 		    [['The Element'|lists1:duplicate(Num, 'Ele')]]),
  174:     case spawn_eval(lists1,reverse,[List]) of
  175: 	['The Element'|_Rest] ->
  176: 	    ok;
  177: 	_Other ->
  178: 	    error
  179:     end.
  180: 
  181: member(suite) ->
  182:     [];
  183: member(doc) ->
  184:     ["Tests the lists1:member() implementation. The function "
  185:      "is `non-blocking', and only processes 2000 elements "
  186:      "at a time.",
  187:      "This test case depends on lists1:reverse() to work, "
  188:      "wich is tested in a separate test case."];
  189: member(Config) when list(Config) ->
  190:     ?line ok=member_test(0),
  191:     ?line ok=member_test(1),
  192:     ?line ok=member_test(100),
  193:     ?line ok=member_test(537),
  194:     ok.
  195: 
  196: member_test(0) ->
  197:     case spawn_eval(lists1,member,['The Element', []]) of
  198: 	false ->
  199: 	    ok;
  200: 	true ->
  201: 	    {error, 'Found (!?)'}
  202:     end;
  203: member_test(Num) ->
  204:     List=spawn_eval(lists1,reverse,
  205: 		    [['The Element'|spawn_eval(lists1,duplicate,
  206: 					       [Num, 'Elem'])]]),
  207:     case spawn_eval(lists1,member,['The Element', List]) of
  208: 	true ->
  209: 	    ok;
  210: 	false ->
  211: 	    {error, not_found}
  212:     end.
  213: 
  214: spawn_eval(M,F,A) ->
  215:     Self = self(),
  216:     spawn(fun() -> evaluator(Self, M,F,A) end),
  217:     receive
  218: 	Result ->
  219: 	    Result
  220:     end.
  221: 
  222: evaluator(Pid, M,F,A) ->
  223:     Pid ! (catch apply(M,F,A)).
  224: 
  225: interpretable(suite) ->
  226:     [];
  227: interpretable(doc) ->
  228:     ["Test int:interpretable/1"];
  229: interpretable(Config) when is_list(Config) ->
  230: 
  231:     %% First make sure that 'lists1' is not loaded
  232:     case code:is_loaded(lists1) of
  233: 	{file, _Loaded} ->
  234: 	    ?line code:purge(lists1),
  235: 	    ?line code:delete(lists1),
  236: 	    ?line code:purge(lists1);
  237: 	false -> ignore
  238:     end,
  239: 
  240:     %% true
  241:     ?line DataDir = filename:dirname(?config(data_dir, Config)),
  242:     ?line true = code:add_patha(DataDir),
  243:     ?line true = int:interpretable(lists1),
  244:     ?line true = int:interpretable(filename:join([DataDir,lists1])),
  245:     ?line true = code:del_path(DataDir),
  246: 
  247:     %% {error, no_src}
  248:     ?line PrivDir = filename:join(?config(priv_dir, Config), ""),
  249:     ?line {ok, _} = file:copy(filename:join([DataDir,"lists1.beam"]),
  250: 			      filename:join([PrivDir,"lists1.beam"])),
  251:     ?line true = code:add_patha(PrivDir),
  252: 
  253:     ?line {error, no_src} = int:interpretable(lists1),
  254:     ?line ok = file:delete(filename:join([PrivDir,"lists1.beam"])),
  255: 
  256:     %% {error, no_beam}
  257:     Src = filename:join([PrivDir,"lists1.erl"]),
  258:     ?line {ok, _} = file:copy(filename:join([DataDir,"lists1.erl"]),
  259: 			      Src),
  260:     ?line {error, no_beam} = int:interpretable(Src),
  261: 
  262:     %% {error, no_debug_info}
  263:     ?line {ok, _} = compile:file(Src, [{outdir,PrivDir}]),
  264:     ?line {error, no_debug_info} = int:interpretable(Src),
  265:     ?line {error, no_debug_info} = int:interpretable(lists1),
  266:     ?line ok = file:delete(Src),
  267:     ?line true = code:del_path(PrivDir),
  268: 
  269:     %% {error, badarg}
  270:     ?line {error, badarg} = int:interpretable(pride),
  271:     ?line {error, badarg} = int:interpretable("prejudice.erl"),
  272: 
  273:     %% {error, {app,App}}
  274:     ?line {error, {app,_}} = int:interpretable(file),
  275:     ?line {error, {app,_}} = int:interpretable(lists),
  276:     ?line case int:interpretable(dbg_ieval) of
  277: 	      {error, {app,_}} ->
  278: 		  ok;
  279: 	      {error, badarg} ->
  280: 		  case code:which(dbg_ieval) of
  281: 		      cover_compiled ->
  282: 			  ok;
  283: 		      Other1 ->
  284: 			  ?line ?t:fail({unexpected_result, Other1})
  285: 		  end;
  286: 	      Other2 ->
  287: 		  ?line ?t:fail({unexpected_result, Other2})
  288: 	  end,
  289: 
  290:     ok.