1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 2005-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: 20: -module(module_info_SUITE). 21: 22: -include_lib("test_server/include/test_server.hrl"). 23: 24: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 25: init_per_group/2,end_per_group/2, 26: init_per_testcase/2,end_per_testcase/2, 27: exports/1,functions/1,native/1]). 28: 29: %%-compile(native). 30: 31: %% Helper. 32: -export([native_proj/1,native_filter/1]). 33: 34: suite() -> [{ct_hooks,[ts_install_cth]}]. 35: 36: all() -> 37: modules(). 38: 39: groups() -> 40: []. 41: 42: init_per_suite(Config) -> 43: Config. 44: 45: end_per_suite(_Config) -> 46: ok. 47: 48: init_per_group(_GroupName, Config) -> 49: Config. 50: 51: end_per_group(_GroupName, Config) -> 52: Config. 53: 54: 55: modules() -> 56: [exports, functions, native]. 57: 58: init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> 59: Dog = ?t:timetrap(?t:minutes(3)), 60: [{watchdog,Dog}|Config]. 61: 62: end_per_testcase(_Func, Config) -> 63: Dog = ?config(watchdog, Config), 64: ?t:timetrap_cancel(Dog). 65: 66: %% Should return all functions exported from this module. (local) 67: all_exported() -> 68: All = add_arity(modules()), 69: lists:sort([{all,0},{suite,0},{groups,0}, 70: {init_per_suite,1},{end_per_suite,1}, 71: {init_per_group,2},{end_per_group,2}, 72: {init_per_testcase,2},{end_per_testcase,2}, 73: {module_info,0},{module_info,1},{native_proj,1}, 74: {native_filter,1}|All]). 75: 76: %% Should return all functions in this module. (local) 77: all_functions() -> 78: Locals = [{add_arity,1},{add_arity,2},{all_exported,0},{all_functions,0}, 79: {modules,0}], 80: lists:sort(Locals++all_exported()). 81: 82: %% Test that the list of exported functions from this module is correct. 83: exports(Config) when is_list(Config) -> 84: ?line All = all_exported(), 85: ?line All = lists:sort(?MODULE:module_info(exports)), 86: ?line (catch ?MODULE:foo()), 87: ?line All = lists:sort(?MODULE:module_info(exports)), 88: ok. 89: 90: %% Test that the list of exported functions from this module is correct. 91: functions(Config) when is_list(Config) -> 92: ?line All = all_functions(), 93: ?line All = lists:sort(?MODULE:module_info(functions)), 94: ok. 95: 96: %% Test that the list of exported functions from this module is correct. 97: native(Config) when is_list(Config) -> 98: ?line All = all_functions(), 99: ?line case ?MODULE:module_info(native_addresses) of 100: [] -> 101: {comment,"no native functions"}; 102: L -> 103: %% Verify that all functions have unique addresses. 104: ?line S0 = sofs:set(L, [{name,arity,addr}]), 105: ?line S1 = sofs:projection({external,fun ?MODULE:native_proj/1}, S0), 106: ?line S2 = sofs:relation_to_family(S1), 107: ?line S3 = sofs:family_specification(fun ?MODULE:native_filter/1, S2), 108: ?line 0 = sofs:no_elements(S3), 109: ?line S4 = sofs:range(S1), 110: 111: %% Verify that the set of function with native addresses 112: %% is a subset of all functions in the module. 113: ?line AllSet = sofs:set(All, [{name,arity}]), 114: ?line true = sofs:is_subset(S4, AllSet), 115: 116: {comment,integer_to_list(sofs:no_elements(S0))++" native functions"} 117: end. 118: 119: native_proj({Name,Arity,Addr}) -> 120: {Addr,{Name,Arity}}. 121: 122: native_filter(Set) -> 123: sofs:no_elements(Set) =/= 1. 124: 125: %% Helper functions (local). 126: 127: add_arity(L) -> 128: add_arity(L, []). 129: 130: add_arity([H|T], Acc) -> 131: add_arity(T, [{H,1}|Acc]); 132: add_arity([], Acc) -> lists:reverse(Acc).