1: %%
    2: %% %CopyrightBegin%
    3: %%
    4: %% Copyright Ericsson AB 1998-2011. 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: -module(instrument_SUITE).
   20: 
   21: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 
   22: 	 init_per_group/2,end_per_group/2,
   23: 	 init_per_testcase/2,end_per_testcase/2]).
   24: 
   25: -export(['+Mim true'/1, '+Mis true'/1]).
   26: 
   27: -include_lib("test_server/include/test_server.hrl").
   28: 
   29: init_per_testcase(_Case, Config) ->
   30:     ?line Dog=?t:timetrap(10000),
   31:     [{watchdog, Dog}|Config].
   32: 
   33: end_per_testcase(_Case, Config) ->
   34:     Dog=?config(watchdog, Config),
   35:     ?t:timetrap_cancel(Dog),
   36:     ok.
   37: 
   38: suite() -> [{ct_hooks,[ts_install_cth]}].
   39: 
   40: all() -> 
   41:     ['+Mim true', '+Mis true'].
   42: 
   43: groups() -> 
   44:     [].
   45: 
   46: init_per_suite(Config) ->
   47:     Config.
   48: 
   49: end_per_suite(_Config) ->
   50:     ok.
   51: 
   52: init_per_group(_GroupName, Config) ->
   53:     Config.
   54: 
   55: end_per_group(_GroupName, Config) ->
   56:     Config.
   57: 
   58: 
   59: '+Mim true'(doc) -> ["Check that memory data can be read and processed"];
   60: '+Mim true'(suite) -> [];
   61: '+Mim true'(Config) when is_list(Config) ->
   62:     ?line Node = start_slave("+Mim true"),
   63:     ?line MD = rpc:call(Node, instrument, memory_data, []),
   64:     ?line [{total,[{sizes,S1,S2,S3},{blocks,B1,B2,B3}]}]
   65: 	= rpc:call(Node, instrument, memory_status, [total]),
   66:     ?line stop_slave(Node),
   67:     ?line true = S1 =< S2,
   68:     ?line true = S2 =< S3,
   69:     ?line true = B1 =< B2,
   70:     ?line true = B2 =< B3,
   71:     ?line MDS = instrument:sort(MD),
   72:     ?line {Low, High} = instrument:mem_limits(MDS),
   73:     ?line true = Low < High,
   74:     ?line {_, AL} = MDS,
   75:     ?line SumBlocks = instrument:sum_blocks(MD),
   76:     ?line case SumBlocks of
   77: 	      N when is_integer(N) ->
   78: 		  ?line N = lists:foldl(fun ({_,_,Size,_}, Sum) ->
   79: 						Size+Sum
   80: 					end,
   81: 					0,
   82: 					AL),
   83: 		  ?line N =< S3;
   84: 	      Other ->
   85: 		  ?line ?t:fail(Other)
   86: 	  end,
   87:     ?line lists:foldl(
   88: 	    fun ({TDescr,Addr,Size,Proc}, MinAddr) ->
   89: 		    ?line true = TDescr /= invalid_type,
   90: 		    ?line true = is_integer(TDescr),
   91: 		    ?line true = is_integer(Addr),
   92: 		    ?line true = is_integer(Size),
   93: 		    ?line true = Addr >= MinAddr,
   94: 		    ?line case Proc of
   95: 			      {0, Number, Serial} ->
   96: 				  ?line true = is_integer(Number),
   97: 				  ?line true = is_integer(Serial);
   98: 			      undefined ->
   99: 				  ok;
  100: 			      BadProc ->
  101: 				  ?line ?t:fail({badproc, BadProc})
  102: 			  end,
  103: 		    ?line NextMinAddr = Addr+Size,
  104: 		    ?line true = NextMinAddr =< High,
  105: 		    ?line NextMinAddr
  106: 	    end,
  107: 	    Low,
  108: 	    AL),
  109:     ?line {_, DAL} = instrument:descr(MDS),
  110:     ?line lists:foreach(
  111: 	    fun ({TDescr,_,_,Proc}) ->
  112: 		    ?line true = TDescr /= invalid_type,
  113: 		    ?line true = is_atom(TDescr) orelse is_list(TDescr),
  114: 		    ?line true = is_pid(Proc) orelse Proc == undefined
  115: 	    end,
  116: 	    DAL),
  117:     ?line ASL = lists:map(fun ({_,A,S,_}) -> {A,S} end, AL),
  118:     ?line ASL = lists:map(fun ({_,A,S,_}) -> {A,S} end, DAL),
  119:     ?line instrument:holes(MDS),
  120:     ?line {comment,
  121: 	   "total status - sum of blocks = " ++ integer_to_list(S1-SumBlocks)}.
  122: 
  123: '+Mis true'(doc) -> ["Check that memory data can be read and processed"];
  124: '+Mis true'(suite) -> [];
  125: '+Mis true'(Config) when is_list(Config) ->
  126:     ?line Node = start_slave("+Mis true"),
  127:     ?line [{total,[{sizes,S1,S2,S3},{blocks,B1,B2,B3}]}]
  128: 	= rpc:call(Node, instrument, memory_status, [total]),
  129:     ?line true = S1 =< S2,
  130:     ?line true = S2 =< S3,
  131:     ?line true = B1 =< B2,
  132:     ?line true = B2 =< B3,
  133:     ?line true = is_list(rpc:call(Node,instrument,memory_status,[allocators])),
  134:     ?line true = is_list(rpc:call(Node,instrument,memory_status,[classes])),
  135:     ?line true = is_list(rpc:call(Node,instrument,memory_status,[types])),
  136:     ?line ok.
  137: 
  138: start_slave(Args) ->
  139:     ?line {A, B, C} = now(),
  140:     ?line MicroSecs = A*1000000000000 + B*1000000 + C,
  141:     ?line Name = "instr_" ++ integer_to_list(MicroSecs),
  142:     ?line Pa = filename:dirname(code:which(?MODULE)),
  143:     ?line {ok, Node} = ?t:start_node(list_to_atom(Name),
  144: 				     slave,
  145: 				     [{args, "-pa " ++ Pa ++ " " ++ Args}]),
  146:     ?line Node.
  147: 
  148: 
  149: stop_slave(Node) ->
  150:     ?line true = ?t:stop_node(Node).