1: %%
    2: %% %CopyrightBegin%
    3: %%
    4: %% Copyright Ericsson AB 2005-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: %%----------------------------------------------------------------------
   21: %% Purpose: Verify the application specifics of the asn1 application
   22: %%----------------------------------------------------------------------
   23: -module(asn1_app_test).
   24: 
   25: -compile(export_all).
   26: 
   27: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   28: 
   29: all() -> 
   30:     [fields, modules, exportall, app_depend].
   31: 
   32: groups() -> 
   33:     [].
   34: 
   35: init_per_group(_GroupName, Config) ->
   36: 	Config.
   37: 
   38: end_per_group(_GroupName, Config) ->
   39: 	Config.
   40: 
   41: 
   42: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   43: 
   44: init_per_suite(suite) -> [];
   45: init_per_suite(doc) -> [];
   46: init_per_suite(Config) when is_list(Config) ->
   47:     case is_app(asn1) of
   48: 	{ok, AppFile} ->
   49: 	    io:format("AppFile: ~n~p~n", [AppFile]),
   50: 	    [{app_file, AppFile}|Config];
   51: 	{error, Reason} ->
   52: 	    fail(Reason)
   53:     end.
   54: 
   55: is_app(App) ->
   56:     LibDir = code:lib_dir(App),
   57:     File = filename:join([LibDir, "ebin", atom_to_list(App) ++ ".app"]),
   58:     case file:consult(File) of
   59: 	{ok, [{application, App, AppFile}]} ->
   60: 	    {ok, AppFile};
   61: 	Error ->
   62: 	    {error, {invalid_format, Error}}
   63:     end.
   64: 
   65: 
   66: end_per_suite(suite) -> [];
   67: end_per_suite(doc) -> [];
   68: end_per_suite(Config) when is_list(Config) ->
   69:     Config.
   70: 
   71: 
   72: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   73: 
   74: fields(suite) ->
   75:     [];
   76: fields(doc) ->
   77:     [];
   78: fields(Config) when is_list(Config) ->
   79:     AppFile = key1search(app_file, Config),
   80:     Fields = [vsn, description, modules, registered, applications],
   81:     case check_fields(Fields, AppFile, []) of
   82: 	[] ->
   83: 	    ok;
   84: 	Missing ->
   85: 	    fail({missing_fields, Missing})
   86:     end.
   87: 
   88: check_fields([], _AppFile, Missing) ->
   89:     Missing;
   90: check_fields([Field|Fields], AppFile, Missing) ->
   91:     check_fields(Fields, AppFile, check_field(Field, AppFile, Missing)).
   92: 
   93: check_field(Name, AppFile, Missing) ->
   94:     io:format("checking field: ~p~n", [Name]),
   95:     case lists:keymember(Name, 1, AppFile) of
   96: 	true ->
   97: 	    Missing;
   98: 	false ->
   99: 	    [Name|Missing]
  100:     end.
  101: 
  102: 
  103: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  104: 
  105: modules(suite) ->
  106:     [];
  107: modules(doc) ->
  108:     [];
  109: modules(Config) when is_list(Config) ->
  110:     AppFile  = key1search(app_file, Config),
  111:     Mods     = key1search(modules, AppFile),
  112:     EbinList = get_ebin_mods(asn1),
  113:     case missing_modules(Mods, EbinList, []) of
  114: 	[] ->
  115: 	    ok;
  116: 	Missing ->
  117: 	    throw({error, {missing_modules, Missing}})
  118:     end,
  119:     case extra_modules(Mods, EbinList, []) of
  120: 	[] ->
  121: 	    ok;
  122: 	Extra ->
  123: 	    check_asn1ct_modules(Extra)
  124: %	    throw({error, {extra_modules, Extra}})
  125:     end,
  126:     {ok, Mods}.
  127: 	    
  128: get_ebin_mods(App) ->
  129:     LibDir  = code:lib_dir(App),
  130:     EbinDir = filename:join([LibDir,"ebin"]),
  131:     {ok, Files0} = file:list_dir(EbinDir),
  132:     Files1 = [lists:reverse(File) || File <- Files0],
  133:     [list_to_atom(lists:reverse(Name)) || [$m,$a,$e,$b,$.|Name] <- Files1].
  134: 
  135: check_asn1ct_modules(Extra) ->
  136:     ASN1CTMods = [asn1ct,asn1ct_check,asn1_db,asn1ct_pretty_format,
  137: 		  asn1ct_gen,asn1ct_gen_per,asn1ct_gen_per_rt2ct,
  138: 		  asn1ct_name,asn1ct_constructed_per,asn1ct_constructed_ber,
  139: 		  asn1ct_gen_ber,asn1ct_constructed_ber_bin_v2,
  140: 		  asn1ct_gen_ber_bin_v2,asn1ct_value,
  141: 		  asn1ct_tok,asn1ct_parser2,asn1ct_table,
  142: 		  asn1ct_imm,asn1ct_func,asn1ct_rtt,
  143: 		  asn1ct_eval_ext,asn1ct_eval_per,asn1ct_eval_uper],
  144:     case Extra -- ASN1CTMods of
  145: 	[] ->
  146: 	    ok;
  147: 	Extra2 ->
  148: 	    throw({error, {extra_modules, Extra2}})
  149:     end.
  150: 
  151: missing_modules([], _Ebins, Missing) ->
  152:     Missing;
  153: missing_modules([Mod|Mods], Ebins, Missing) ->
  154:     case lists:member(Mod, Ebins) of
  155: 	true ->
  156: 	    missing_modules(Mods, Ebins, Missing);
  157: 	false ->
  158: 	    io:format("missing module: ~p~n", [Mod]),
  159: 	    missing_modules(Mods, Ebins, [Mod|Missing])
  160:     end.
  161: 
  162: 
  163: extra_modules(_Mods, [], Extra) ->
  164:     Extra;
  165: extra_modules(Mods, [Mod|Ebins], Extra) ->
  166:     case lists:member(Mod, Mods) of
  167: 	true ->
  168: 	    extra_modules(Mods, Ebins, Extra);
  169: 	false ->
  170: 	    io:format("supefluous module: ~p~n", [Mod]),
  171: 	    extra_modules(Mods, Ebins, [Mod|Extra])
  172:     end.
  173: 
  174: 
  175: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  176: 
  177: 
  178: exportall(suite) ->
  179:     [];
  180: exportall(doc) ->
  181:     [];
  182: exportall(Config) when is_list(Config) ->
  183:     AppFile = key1search(app_file, Config),
  184:     Mods    = key1search(modules, AppFile),
  185:     check_export_all(Mods).
  186: 
  187: 
  188: check_export_all([]) ->
  189:     ok;
  190: check_export_all([Mod|Mods]) ->
  191:     case (catch apply(Mod, module_info, [compile])) of
  192: 	{'EXIT', {undef, _}} ->
  193: 	    check_export_all(Mods);
  194: 	O ->
  195:             case lists:keysearch(options, 1, O) of
  196:                 false ->
  197:                     check_export_all(Mods);
  198:                 {value, {options, List}} ->
  199:                     case lists:member(export_all, List) of
  200:                         true ->
  201: 			    throw({error, {export_all, Mod}});
  202: 			false ->
  203: 			    check_export_all(Mods)
  204:                     end
  205:             end
  206:     end.
  207: 
  208: 	    
  209: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  210: 
  211: app_depend(suite) ->
  212:     [];
  213: app_depend(doc) ->
  214:     [];
  215: app_depend(Config) when is_list(Config) ->
  216:     AppFile = key1search(app_file, Config),
  217:     Apps    = key1search(applications, AppFile),
  218:     check_apps(Apps).
  219: 
  220: 
  221: check_apps([]) ->
  222:     ok;
  223: check_apps([App|Apps]) ->
  224:     case is_app(App) of
  225: 	{ok, _} ->
  226: 	    check_apps(Apps);
  227: 	Error ->
  228: 	    throw({error, {missing_app, {App, Error}}})
  229:     end.
  230: 
  231: 
  232: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  233: 
  234: 
  235: fail(Reason) ->
  236:     exit({suite_failed, Reason}).
  237: 
  238: key1search(Key, L) ->
  239:     case lists:keysearch(Key, 1, L) of
  240: 	undefined ->
  241: 	    fail({not_found, Key, L});
  242: 	{value, {Key, Value}} ->
  243: 	    Value
  244:     end.