1: %%
    2: %% %CopyrightBegin%
    3: %%
    4: %% Copyright Ericsson AB 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: -module(error_SUITE).
   21: -export([suite/0,all/0,groups/0,
   22: 	 already_defined/1,enumerated/1,objects/1]).
   23: 
   24: -include_lib("test_server/include/test_server.hrl").
   25: 
   26: suite() -> [{ct_hooks, [ts_install_cth]}].
   27: 
   28: all() ->
   29:     [{group,p}].
   30: 
   31: groups() ->
   32:     [{p,parallel(),[already_defined,
   33: 		    enumerated,
   34: 		    objects]}].
   35: 
   36: parallel() ->
   37:     case erlang:system_info(schedulers) > 1 of
   38:         true  -> [parallel];
   39:         false -> []
   40:     end.
   41: 
   42: already_defined(Config) ->
   43:     M = 'Already',
   44:     P = {M,
   45: 	 <<"Already DEFINITIONS ::= BEGIN\n"
   46: 	   "  I ::= INTEGER\n"
   47: 	   "  i I ::= 42\n"
   48: 	   "  I ::= OCTET STRING\n"
   49: 	   "  I ::= CLASS { &Type }\n"
   50: 	   "  MYCLASS ::= CLASS { &Type }\n"
   51: 	   "  i MYCLASS ::= { &Type INTEGER }\n"
   52: 	   "  o MYCLASS ::= { &Type INTEGER }\n"
   53: 	   "  I MYCLASS ::= { o }\n"
   54: 	   "  I{T} ::= SEQUENCE OF T\n"
   55: 	   "  I{INTEGER:x} INTEGER ::= { 1 | 2 | x }\n"
   56: 	   "  i{T} MYCLASS ::= { &Type T }\n"
   57: 	   "END\n">>},
   58:     {error,
   59:      [
   60:       {structured_error,{M,4},asn1ct_check,{already_defined,'I',2}},
   61:       {structured_error,{M,5},asn1ct_check,{already_defined,'I',2}},
   62:       {structured_error,{M,7},asn1ct_check,{already_defined,'i',3}},
   63:       {structured_error,{M,9},asn1ct_check,{already_defined,'I',2}},
   64:       {structured_error,{M,10},asn1ct_check,{already_defined,'I',2}},
   65:       {structured_error,{M,11},asn1ct_check,{already_defined,'I',2}},
   66:       {structured_error,{M,12},asn1ct_check,{already_defined,'i',3}}
   67:      ]
   68:     } = run(P, Config),
   69:     ok.
   70: 
   71: enumerated(Config) ->
   72:     M = 'Enumerated',
   73:     P = {M,
   74: 	 <<"Enumerated DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
   75: 	   "  Enum ::= ENUMERATED { a, b, c }\n"
   76: 	   "  e Enum ::= d\n"
   77: 	   "  EnumExt ::= ENUMERATED { x, ..., y }\n"
   78: 	   "  ext EnumExt ::= z\n"
   79: 	   "  S1 ::= SEQUENCE {\n"
   80:            "    ge1 Enum DEFAULT a,\n"
   81:            "    ge2 EnumExt DEFAULT x,\n"
   82:            "    ge3 EnumExt DEFAULT y,\n"
   83: 	   "    e Enum DEFAULT aa\n"
   84:            "  }\n"
   85: 	   "  S2 ::= SEQUENCE {\n"
   86: 	   "    e2 EnumExt DEFAULT xyz\n"
   87: 	   "  }\n"
   88: 	   "END\n">>},
   89:     {error,
   90:      [
   91:       {structured_error,{'Enumerated',3},asn1ct_check,{undefined,d}},
   92:       {structured_error,{'Enumerated',5},asn1ct_check,{undefined,z}},
   93:       {structured_error,{'Enumerated',10},asn1ct_check,{undefined,aa}},
   94:       {structured_error,{'Enumerated',13},asn1ct_check,{undefined,xyz}}
   95:      ]
   96:     } = run(P, Config),
   97:     ok.
   98: 
   99: objects(Config) ->
  100:     M = 'Objects',
  101:     P = {M,
  102: 	 <<"Objects DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
  103: 	   "  obj1 CL ::= { &wrong 42 }\n"
  104: 	   "  obj2 CL ::= { &wrong 1, &Wrong INTEGER }\n"
  105: 	   "  obj3 CL ::= { &Data OCTET STRING }\n"
  106: 	   "  obj4 SMALL ::= { &code 42 }\n"
  107: 	   "  InvalidSet CL ::= { obj1 }\n"
  108: 
  109: 	   "  CL ::= CLASS {\n"
  110: 	   "    &code INTEGER UNIQUE,\n"
  111: 	   "    &enum ENUMERATED { a, b, c},\n"
  112: 	   "    &Data,\n"
  113: 	   "    &object CL,\n"
  114: 	   "    &Set CL,\n"
  115: 	   "    &vartypevalue &Data,\n"
  116: 	   "    &VarTypeValue &Data\n"
  117: 	   "  }\n"
  118: 
  119: 	   "  SMALL ::= CLASS {\n"
  120: 	   "    &code INTEGER UNIQUE,\n"
  121:            "    &i INTEGER\n"
  122:            "  }\n"
  123: 	   "END\n">>},
  124:     {error,
  125:      [
  126:       {structured_error,{M,2},asn1ct_check,
  127:        {invalid_fields,[wrong],obj1}},
  128:       {structured_error,{M,3},asn1ct_check,
  129:        {invalid_fields,['Wrong',wrong],obj2}},
  130:       {structured_error,{M,4},asn1ct_check,
  131:        {missing_mandatory_fields,['Set','VarTypeValue',code,
  132: 				  enum,object,vartypevalue],obj3}},
  133:       {structured_error,{M,5},asn1ct_check,
  134:        {missing_mandatory_fields,[i],obj4}},
  135:       {structured_error,{M,6},asn1ct_check,
  136:        {invalid_fields,[wrong],'InvalidSet'}}
  137:      ]
  138:     } = run(P, Config),
  139:     ok.
  140: 
  141: 
  142: 
  143: run({Mod,Spec}, Config) ->
  144:     Base = atom_to_list(Mod) ++ ".asn1",
  145:     File = filename:join(?config(priv_dir, Config), Base),
  146:     ok = file:write_file(File, Spec),
  147:     asn1ct:compile(File).