diff options
Diffstat (limited to 'lib')
294 files changed, 76384 insertions, 2832 deletions
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml index 191b3a84df..714902e63f 100644 --- a/lib/asn1/doc/src/notes.xml +++ b/lib/asn1/doc/src/notes.xml @@ -30,6 +30,22 @@ </header> <p>This document describes the changes made to the asn1 application.</p> +<section><title>Asn1 1.6.13.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The encoding of ExtensionAdditionGroup (for PER and UPER) + is corrected.</p> + <p> + Own Id: OTP-8866 Aux Id: OTP-8797, SEQ-11557 </p> + </item> + </list> + </section> + +</section> + <section><title>Asn1 1.6.13.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index 1c9f2c759a..7cd29623c1 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -6408,6 +6408,12 @@ any_component_relation(S,Type,CNames,NamePath,Acc) when is_record(Type,type) -> [] end, InnerAcc ++ CRelPath ++ Acc; +%% Just skip the markers for ExtensionAdditionGroup start and end +%% in this function +any_component_relation(S,[#'ExtensionAdditionGroup'{}|Cs],CNames,NamePath,Acc) -> + any_component_relation(S,Cs,CNames,NamePath,Acc); +any_component_relation(S,['ExtensionAdditionGroupEnd'|Cs],CNames,NamePath,Acc) -> + any_component_relation(S,Cs,CNames,NamePath,Acc); any_component_relation(_,[],_,_,Acc) -> Acc. diff --git a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl index a55ac9db8e..e3be914af4 100644 --- a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl +++ b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. +%% Copyright Ericsson AB 2002-2010. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -75,13 +75,15 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) -> "Val" end, - {SeqOrSet,TableConsInfo,CompList} = + {SeqOrSet,TableConsInfo,CompList0} = case D#type.def of #'SEQUENCE'{tablecinf=TCI,components=CL} -> {'SEQUENCE',TCI,CL}; #'SET'{tablecinf=TCI,components=CL} -> {'SET',TCI,CL} end, + %% filter away extensionAdditiongroup markers + CompList = filter_complist(CompList0), Ext = extensible(CompList), CompList1 = case CompList of {Rl1,El,Rl2} -> Rl1 ++ El ++ Rl2; @@ -183,7 +185,10 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) -> asn1ct_name:start(), asn1ct_name:clear(), asn1ct_name:new(tag), - #'SEQUENCE'{tablecinf=TableConsInfo,components=CList} = D#type.def, + #'SEQUENCE'{tablecinf=TableConsInfo,components=CList0} = D#type.def, + + %% filter away extensionAdditiongroup markers + CList = filter_complist(CList0), Ext = extensible(CList), {CompList,CompList2} = case CList of @@ -345,7 +350,9 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) -> asn1ct_name:clear(), %% asn1ct_name:new(term), asn1ct_name:new(tag), - #'SET'{tablecinf=TableConsInfo,components=TCompList} = D#type.def, + #'SET'{tablecinf=TableConsInfo,components=TCompList0} = D#type.def, + %% filter away extensionAdditiongroup markers + TCompList = filter_complist(TCompList0), Ext = extensible(TCompList), ToOptional = fun(mandatory) -> 'OPTIONAL'; @@ -1426,6 +1433,22 @@ extensible({RootList,ExtList}) -> {ext,length(RootList)+1,length(ExtList)}; extensible({_Rl1,_Ext,_Rl2}) -> extensible. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% filter away ExtensionAdditionGroup start and end marks since these +%% have no significance for the BER encoding +%% +filter_complist(CompList) when is_list(CompList) -> + lists:filter(fun(#'ExtensionAdditionGroup'{}) -> + false; + ('ExtensionAdditionGroupEnd') -> + false; + (_) -> + true + end, CompList); +filter_complist({Root,Ext}) -> + {Root,filter_complist(Ext)}; +filter_complist({Root1,Ext,Root2}) -> + {Root1,filter_complist(Ext),Root2}. print_attribute_comment(InnerType,Pos,Cname,Prop) -> diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl index df430c4f88..cce6eb9831 100644 --- a/lib/asn1/src/asn1ct_constructed_per.erl +++ b/lib/asn1/src/asn1ct_constructed_per.erl @@ -66,9 +66,9 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> end, case Typename of ['EXTERNAL'] -> - emit({{var,asn1ct_name:next(val)}, + emit({{next,val}, " = asn1rt_check:transform_to_EXTERNAL1990(", - {var,asn1ct_name:curr(val)},"),",nl}), + {curr,val},"),",nl}), asn1ct_name:new(val); _ -> ok @@ -77,23 +77,40 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> {[],EmptyCL} when EmptyCL == {[],[],[]};EmptyCL == {[],[]};EmptyCL == [] -> emit(["%%Variable setting just to eliminate ", "compiler warning for unused vars!",nl, - "_Val = ",{var,asn1ct_name:curr(val)},",",nl]); + "_Val = ",{curr,val},",",nl]); {[],_} -> - emit([{var,asn1ct_name:next(val)}," = ?RT_PER:list_to_record("]), + emit([{next,val}," = ?RT_PER:list_to_record("]), emit(["'",asn1ct_gen:list2rname(Typename),"'"]), - emit([", ",{var,asn1ct_name:curr(val)},"),",nl]); + emit([", ",{curr,val},"),",nl]); _ -> Fixoptcall = ",Opt} = ?RT_PER:fixoptionals(", - emit({"{",{var,asn1ct_name:next(val)},Fixoptcall, + emit({"{",{next,val},Fixoptcall, {asis,Optionals},",",length(Optionals), - ",",{var,asn1ct_name:curr(val)},"),",nl}) + ",",{curr,val},"),",nl}) end, asn1ct_name:new(val), Ext = extensible_enc(CompList), case Ext of {ext,_,NumExt} when NumExt > 0 -> - emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext}, - ", ",{curr,val},"),",nl]); + case extgroup_pos_and_length(CompList) of + {extgrouppos,ExtGroupPos,ExtGroupLen} -> + Elements = make_elements(ExtGroupPos+1, + "Val1",lists:seq(1,ExtGroupLen)), + emit([ + {next,val}," = case [X || X <- [",Elements, + "],X =/= asn1_NOVALUE] of",nl, + "[] -> ",{curr,val},";",nl, + "_ -> setelement(",{asis,ExtGroupPos+1},",", + {curr,val},",", + "{extaddgroup,", Elements,"})",nl, + "end,",nl]), + asn1ct_name:new(val); + _ -> % no extensionAdditionGroup + ok + end, + asn1ct_name:new(tmpval), + emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext},",", + {curr,val},"),",nl]); _ -> true end, EncObj = @@ -303,7 +320,7 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) -> mkvlist(textual_order(to_encoding_order(CompList),asn1ct_name:all(term))), emit("},") end, - emit({{var,asn1ct_name:curr(bytes)},"}"}), + emit({{curr,bytes},"}"}), emit({".",nl,nl}). textual_order([#'ComponentType'{textual_order=undefined}|_],TermList) -> @@ -596,6 +613,27 @@ ext_length([#'ComponentType'{}|T],State=normal,Acc) -> ext_length([],_,Acc) -> Acc. +extgroup_pos_and_length(CompList) when is_list(CompList) -> + noextgroup; +extgroup_pos_and_length({RootList,ExtList}) -> + extgrouppos(ExtList,length(RootList)+1); +extgroup_pos_and_length({Rl1,Ext,_Rl2}) -> + extgrouppos(Ext,length(Rl1)+1). + +extgrouppos([{'ExtensionAdditionGroup',_Num}|T],Pos) -> + extgrouppos(T,Pos,0); +extgrouppos([_|T],Pos) -> + extgrouppos(T,Pos+1); +extgrouppos([],_) -> + noextgroup. + +extgrouppos(['ExtensionAdditionGroupEnd'|_T],Pos,Len) -> + {extgrouppos,Pos,Len}; +extgrouppos([_|T],Pos,Len) -> + extgrouppos(T,Pos,Len+1). + + + gen_dec_extension_value(_) -> emit({"{Ext,",{next,bytes},"} = ?RT_PER:getext(",{curr,bytes},")"}), asn1ct_name:new(bytes). @@ -743,7 +781,7 @@ gen_enc_components_call1(_Erule,_TopType,[],Pos,_,_,_) -> Pos. gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal) -> - Element = make_element(Pos+1,"Val1",Cname), + Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname), emit({"case ",Element," of",nl}), % emit({"asn1_DEFAULT -> [];",nl}), emit({"DFLT when DFLT == asn1_DEFAULT; DFLT == ",{asis,DefaultVal}," -> [];",nl}), @@ -760,24 +798,23 @@ gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal gen_enc_component_optional(Erule,TopType,Cname, Type=#type{def=#'SEQUENCE'{ extaddgroup=Number, - components=ExtGroupCompList}}, + components=_ExtGroupCompList}}, Pos,DynamicEnc,Ext) when is_integer(Number) -> - emit({nl,"begin",nl}), + Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname), + emit({"case ",Element," of",nl}), + + emit({"asn1_NOVALUE -> [];",nl}), asn1ct_name:new(tmpval), - ExtAddGroupTypeName = asn1ct_gen:list2name([Cname|TopType]), - emit({{curr,tmpval}," = {'",ExtAddGroupTypeName,"', "}), - ExtNames = [ExtName||#'ComponentType'{name=ExtName}<-ExtGroupCompList], - Elements = make_elements(Pos+1,"Val1",ExtNames), - emit({Elements,"},"}), - InnerType = asn1ct_gen:get_inner(Type#type.def), + emit({{curr,tmpval}," ->",nl}), + InnerType = asn1ct_gen:get_inner(Type#type.def), emit({nl,"%% attribute number ",Pos," with type ", InnerType,nl}), NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)), gen_enc_line(Erule,TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext), emit({nl,"end"}); gen_enc_component_optional(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext) -> - Element = make_element(Pos+1,"Val1",Cname), + Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname), emit({"case ",Element," of",nl}), emit({"asn1_NOVALUE -> [];",nl}), diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index e4cd29bfbd..7a28a16877 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -536,33 +536,18 @@ gen_part_decode_funcs(WhatKind,_TypeName,{_,Directive,_,_}) -> throw({error,{asn1,{"Not implemented yet",WhatKind," partial incomplete directive:",Directive}}}). -extaddgroup2sequence(ExtList) -> - extaddgroup2sequence(ExtList,[]). - -extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) -> - Number = case Number0 of undefined -> 1; _ -> Number0 end, - {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} = - lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T), - extaddgroup2sequence(T2,[#'ComponentType'{ - name='ExtAddGroup', - typespec=#type{def=#'SEQUENCE'{ - extaddgroup=Number, - components=ExtGroupComps}}, - prop='OPTIONAL'}|Acc]); -extaddgroup2sequence([C|T],Acc) -> - extaddgroup2sequence(T,[C|Acc]); -extaddgroup2sequence([],Acc) -> - lists:reverse(Acc). - - gen_types(Erules,Tname,{RootL1,ExtList,RootL2}) when is_list(RootL1), is_list(RootL2) -> gen_types(Erules,Tname,RootL1), - gen_types(Erules,Tname,extaddgroup2sequence(ExtList)), + Rtmod = list_to_atom(lists:concat(["asn1ct_gen_",erule(Erules), + rt2ct_suffix(Erules)])), + gen_types(Erules,Tname,Rtmod:extaddgroup2sequence(ExtList)), gen_types(Erules,Tname,RootL2); gen_types(Erules,Tname,{RootList,ExtList}) when is_list(RootList) -> gen_types(Erules,Tname,RootList), - gen_types(Erules,Tname,extaddgroup2sequence(ExtList)); + Rtmod = list_to_atom(lists:concat(["asn1ct_gen_",erule(Erules), + rt2ct_suffix(Erules)])), + gen_types(Erules,Tname,Rtmod:extaddgroup2sequence(ExtList)); gen_types(Erules,Tname,[{'EXTENSIONMARK',_,_}|Rest]) -> gen_types(Erules,Tname,Rest); gen_types(Erules,Tname,[ComponentType|Rest]) -> diff --git a/lib/asn1/src/asn1ct_gen_ber.erl b/lib/asn1/src/asn1ct_gen_ber.erl index 7c432f29c3..8943541303 100644 --- a/lib/asn1/src/asn1ct_gen_ber.erl +++ b/lib/asn1/src/asn1ct_gen_ber.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -33,6 +33,7 @@ -export([gen_objectset_code/2, gen_obj_code/3]). -export([re_wrap_erule/1]). -export([unused_var/2]). +-export([extaddgroup2sequence/1]). -import(asn1ct_gen, [emit/1,demit/1]). @@ -1734,3 +1735,15 @@ get_object_field(Name,ObjectFields) -> {value,Field} -> Field; false -> false end. + +%% For BER the ExtensionAdditionGroup notation has no impact on the encoding/decoding +%% and therefore we only filter away the ExtensionAdditionGroup start and end markers +%% +extaddgroup2sequence(ExtList) when is_list(ExtList) -> + lists:filter(fun(#'ExtensionAdditionGroup'{}) -> + false; + ('ExtensionAdditionGroupEnd') -> + false; + (_) -> + true + end, ExtList). diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl index b7ac0f407c..ac232ea710 100644 --- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl +++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2002-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -33,6 +33,7 @@ -export([gen_objectset_code/2, gen_obj_code/3]). -export([encode_tag_val/3]). -export([gen_inc_decode/2,gen_decode_selected/3]). +-export([extaddgroup2sequence/1]). -import(asn1ct_gen, [emit/1,demit/1]). @@ -1826,8 +1827,15 @@ mk_object_val(Val, Ack, Len) -> add_func(F={_Func,_Arity}) -> ets:insert(asn1_functab,{F}). - - - +%% For BER the ExtensionAdditionGroup notation has no impact on the encoding/decoding +%% and therefore we only filter away the ExtensionAdditionGroup start and end markers +extaddgroup2sequence(ExtList) when is_list(ExtList) -> + lists:filter(fun(#'ExtensionAdditionGroup'{}) -> + false; + ('ExtensionAdditionGroupEnd') -> + false; + (_) -> + true + end, ExtList). diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl index 06d2489748..a8908db7e4 100644 --- a/lib/asn1/src/asn1ct_gen_per.erl +++ b/lib/asn1/src/asn1ct_gen_per.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -31,6 +31,7 @@ -export([gen_encode/2, gen_encode/3]). -export([is_already_generated/2,more_genfields/1,get_class_fields/1, get_object_field/2]). +-export([extaddgroup2sequence/1]). -import(asn1ct_gen, [emit/1,demit/1]). @@ -1393,3 +1394,25 @@ get_object_field(Name,ObjectFields) -> false -> false end. + +%% For PER the ExtensionAdditionGroup notation has significance for the encoding and decoding +%% the components within the ExtensionAdditionGroup is treated in a similar way as if they +%% have been specified within a SEQUENCE, therefore we construct a fake sequence type here +%% so that we can generate code for it +extaddgroup2sequence(ExtList) -> + extaddgroup2sequence(ExtList,[]). + +extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) -> + Number = case Number0 of undefined -> 1; _ -> Number0 end, + {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} = + lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T), + extaddgroup2sequence(T2,[#'ComponentType'{ + name='ExtAddGroup', + typespec=#type{def=#'SEQUENCE'{ + extaddgroup=Number, + components=ExtGroupComps}}, + prop='OPTIONAL'}|Acc]); +extaddgroup2sequence([C|T],Acc) -> + extaddgroup2sequence(T,[C|Acc]); +extaddgroup2sequence([],Acc) -> + lists:reverse(Acc). diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl index 56f895828a..cd05701965 100644 --- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl +++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2002-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -29,6 +29,7 @@ -export([gen_obj_code/3,gen_objectset_code/2]). -export([gen_decode/2, gen_decode/3]). -export([gen_encode/2, gen_encode/3]). +-export([extaddgroup2sequence/1]). -import(asn1ct_gen, [emit/1,demit/1]). -import(asn1ct_gen_per, [is_already_generated/2,more_genfields/1, @@ -1796,3 +1797,25 @@ dec_enumerated_cases([Name|Rest],Tmpremain,No) -> dec_enumerated_cases(Rest,Tmpremain,No+1); dec_enumerated_cases([],_,_) -> "". + +%% For PER the ExtensionAdditionGroup notation has significance for the encoding and decoding +%% the components within the ExtensionAdditionGroup is treated in a similar way as if they +%% have been specified within a SEQUENCE, therefore we construct a fake sequence type here +%% so that we can generate code for it +extaddgroup2sequence(ExtList) -> + extaddgroup2sequence(ExtList,[]). + +extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) -> + Number = case Number0 of undefined -> 1; _ -> Number0 end, + {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} = + lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T), + extaddgroup2sequence(T2,[#'ComponentType'{ + name='ExtAddGroup', + typespec=#type{def=#'SEQUENCE'{ + extaddgroup=Number, + components=ExtGroupComps}}, + prop='OPTIONAL'}|Acc]); +extaddgroup2sequence([C|T],Acc) -> + extaddgroup2sequence(T,[C|Acc]); +extaddgroup2sequence([],Acc) -> + lists:reverse(Acc). diff --git a/lib/asn1/test/asn1_SUITE.erl.src b/lib/asn1/test/asn1_SUITE.erl.src index 9377d23252..2cb059fa4e 100644 --- a/lib/asn1/test/asn1_SUITE.erl.src +++ b/lib/asn1/test/asn1_SUITE.erl.src @@ -2298,11 +2298,15 @@ testExtensionAdditionGroup(Config) -> ?line Path = code:get_path(), ?line code:add_patha(PrivDir), DoIt = fun(Erule) -> - ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),[Erule,{outdir,PrivDir}]), + ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),Erule ++ [{outdir,PrivDir}]), ?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]), - ?line ok = extensionAdditionGroup:run(Erule) + ?line ok = extensionAdditionGroup:run(Erule), + ?line ok = extensionAdditionGroup:run2(Erule), + ?line ok = asn1ct:compile(filename:join(DataDir,"EUTRA-RRC-Definitions"),Erule ++ [{record_name_prefix,"RRC-"},{outdir,PrivDir}]), + ?line ok = extensionAdditionGroup:run3(Erule) end, - ?line [DoIt(Rule)|| Rule <- [per_bin,uper_bin,ber_bin]], + ?line [DoIt(Rule)|| Rule <- [[per_bin],[per_bin,optimize],[uper_bin]]], + %% FIXME problems with automatic tags [ber_bin],[ber_bin,optimize] ?line code:set_path(Path). diff --git a/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn b/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn index a451874ef0..3b811dafe6 100644 --- a/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn +++ b/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn @@ -1,2640 +1,3155 @@ --- 3GPP TS 36.331 V8.8.0 (2009-12) --- $Id$ --- -EUTRA-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::= - -BEGIN - - -BCCH-BCH-Message ::= SEQUENCE { - message BCCH-BCH-MessageType -} - -BCCH-BCH-MessageType ::= MasterInformationBlock - - -BCCH-DL-SCH-Message ::= SEQUENCE { - message BCCH-DL-SCH-MessageType -} - -BCCH-DL-SCH-MessageType ::= CHOICE { - c1 CHOICE { - systemInformation SystemInformation, - systemInformationBlockType1 SystemInformationBlockType1 - }, - messageClassExtension SEQUENCE {} -} - - -PCCH-Message ::= SEQUENCE { - message PCCH-MessageType -} - -PCCH-MessageType ::= CHOICE { - c1 CHOICE { - paging Paging - }, - messageClassExtension SEQUENCE {} -} - - -DL-CCCH-Message ::= SEQUENCE { - message DL-CCCH-MessageType -} - -DL-CCCH-MessageType ::= CHOICE { - c1 CHOICE { - rrcConnectionReestablishment RRCConnectionReestablishment, - rrcConnectionReestablishmentReject RRCConnectionReestablishmentReject, - rrcConnectionReject RRCConnectionReject, - rrcConnectionSetup RRCConnectionSetup - }, - messageClassExtension SEQUENCE {} -} - - -DL-DCCH-Message ::= SEQUENCE { - message DL-DCCH-MessageType -} - -DL-DCCH-MessageType ::= CHOICE { - c1 CHOICE { - csfbParametersResponseCDMA2000 CSFBParametersResponseCDMA2000, - dlInformationTransfer DLInformationTransfer, - handoverFromEUTRAPreparationRequest HandoverFromEUTRAPreparationRequest, - mobilityFromEUTRACommand MobilityFromEUTRACommand, - rrcConnectionReconfiguration RRCConnectionReconfiguration, - rrcConnectionRelease RRCConnectionRelease, - securityModeCommand SecurityModeCommand, - ueCapabilityEnquiry UECapabilityEnquiry, - counterCheck CounterCheck, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - messageClassExtension SEQUENCE {} -} - - -UL-CCCH-Message ::= SEQUENCE { - message UL-CCCH-MessageType -} - -UL-CCCH-MessageType ::= CHOICE { - c1 CHOICE { - rrcConnectionReestablishmentRequest RRCConnectionReestablishmentRequest, - rrcConnectionRequest RRCConnectionRequest - }, - messageClassExtension SEQUENCE {} -} - - -UL-DCCH-Message ::= SEQUENCE { - message UL-DCCH-MessageType -} - -UL-DCCH-MessageType ::= CHOICE { - c1 CHOICE { - csfbParametersRequestCDMA2000 CSFBParametersRequestCDMA2000, - measurementReport MeasurementReport, - rrcConnectionReconfigurationComplete RRCConnectionReconfigurationComplete, - rrcConnectionReestablishmentComplete RRCConnectionReestablishmentComplete, - rrcConnectionSetupComplete RRCConnectionSetupComplete, - securityModeComplete SecurityModeComplete, - securityModeFailure SecurityModeFailure, - ueCapabilityInformation UECapabilityInformation, - ulHandoverPreparationTransfer ULHandoverPreparationTransfer, - ulInformationTransfer ULInformationTransfer, - counterCheckResponse CounterCheckResponse, - spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - messageClassExtension SEQUENCE {} -} - - -CounterCheck ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - counterCheck-r8 CounterCheck-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -CounterCheck-r8-IEs ::= SEQUENCE { - drb-CountMSB-InfoList DRB-CountMSB-InfoList, - nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP -} - -DRB-CountMSB-InfoList::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-CountMSB-Info - -DRB-CountMSB-Info ::= SEQUENCE { - drb-Identity DRB-Identity, - countMSB-Uplink INTEGER(0..33554431), - countMSB-Downlink INTEGER(0..33554431) -} - - -CounterCheckResponse ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - counterCheckResponse-r8 CounterCheckResponse-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -CounterCheckResponse-r8-IEs ::= SEQUENCE { - drb-CountInfoList DRB-CountInfoList, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - -DRB-CountInfoList ::= SEQUENCE (SIZE (0..maxDRB)) OF DRB-CountInfo - -DRB-CountInfo ::= SEQUENCE { - drb-Identity DRB-Identity, - count-Uplink INTEGER(0..4294967295), - count-Downlink INTEGER(0..4294967295) -} - - -CSFBParametersRequestCDMA2000 ::= SEQUENCE { - criticalExtensions CHOICE { - csfbParametersRequestCDMA2000-r8 CSFBParametersRequestCDMA2000-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -CSFBParametersRequestCDMA2000-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -} - -CSFBParametersResponseCDMA2000 ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - csfbParametersResponseCDMA2000-r8 CSFBParametersResponseCDMA2000-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -CSFBParametersResponseCDMA2000-r8-IEs ::= SEQUENCE { - rand RAND-CDMA2000, - mobilityParameters MobilityParametersCDMA2000, - nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP -} - - -DLInformationTransfer ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - dlInformationTransfer-r8 DLInformationTransfer-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -DLInformationTransfer-r8-IEs ::= SEQUENCE { - dedicatedInfoType CHOICE { - dedicatedInfoNAS DedicatedInfoNAS, - dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000, - dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000 - }, - nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP -} - - -HandoverFromEUTRAPreparationRequest ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - handoverFromEUTRAPreparationRequest-r8 - HandoverFromEUTRAPreparationRequest-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -HandoverFromEUTRAPreparationRequest-r8-IEs ::= SEQUENCE { - cdma2000-Type CDMA2000-Type, - rand RAND-CDMA2000 OPTIONAL, -- Cond cdma2000-Type - mobilityParameters MobilityParametersCDMA2000 OPTIONAL, -- Cond cdma2000-Type - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -MasterInformationBlock ::= SEQUENCE { - dl-Bandwidth ENUMERATED { - n6, n15, n25, n50, n75, n100}, - phich-Config PHICH-Config, - systemFrameNumber BIT STRING (SIZE (8)), - spare BIT STRING (SIZE (10)) -} - - - -MeasurementReport ::= SEQUENCE { - criticalExtensions CHOICE { - c1 CHOICE{ - measurementReport-r8 MeasurementReport-r8-IEs, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -MeasurementReport-r8-IEs ::= SEQUENCE { - measResults MeasResults, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -MobilityFromEUTRACommand ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - mobilityFromEUTRACommand-r8 MobilityFromEUTRACommand-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -MobilityFromEUTRACommand-r8-IEs ::= SEQUENCE { - cs-FallbackIndicator BOOLEAN, - purpose CHOICE{ - handover Handover, - cellChangeOrder CellChangeOrder - }, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -Handover ::= SEQUENCE { - targetRAT-Type ENUMERATED { - utra, geran, cdma2000-1XRTT, cdma2000-HRPD, - spare4, spare3, spare2, spare1, ...}, - targetRAT-MessageContainer OCTET STRING, - nas-SecurityParamFromEUTRA OCTET STRING (SIZE (1)) OPTIONAL, -- Cond UTRAGERAN - systemInformation SI-OrPSI-GERAN OPTIONAL -- Cond PSHO -} - -CellChangeOrder ::= SEQUENCE { - t304 ENUMERATED { - ms100, ms200, ms500, ms1000, - ms2000, ms4000, ms8000, spare1}, - targetRAT-Type CHOICE { - geran SEQUENCE { - physCellId PhysCellIdGERAN, - carrierFreq CarrierFreqGERAN, - networkControlOrder BIT STRING (SIZE (2)) OPTIONAL, -- Need OP - systemInformation SI-OrPSI-GERAN OPTIONAL -- Need OP - }, - ... - } -} - -SI-OrPSI-GERAN ::= CHOICE { - si SystemInfoListGERAN, - psi SystemInfoListGERAN -} - -SystemInfoListGERAN ::= SEQUENCE (SIZE (1..maxGERAN-SI)) OF - OCTET STRING (SIZE (1..23)) - - -Paging ::= SEQUENCE { - pagingRecordList PagingRecordList OPTIONAL, -- Need ON - systemInfoModification ENUMERATED {true} OPTIONAL, -- Need ON - etws-Indication ENUMERATED {true} OPTIONAL, -- Need ON - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -PagingRecordList ::= SEQUENCE (SIZE (1..maxPageRec)) OF PagingRecord - -PagingRecord ::= SEQUENCE { - ue-Identity PagingUE-Identity, - cn-Domain ENUMERATED {ps, cs}, - ... -} - -PagingUE-Identity ::= CHOICE { - s-TMSI S-TMSI, - imsi IMSI, - ... -} - -IMSI ::= SEQUENCE (SIZE (6..21)) OF IMSI-Digit - -IMSI-Digit::= INTEGER (0..9) - - -RRCConnectionReconfiguration ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - rrcConnectionReconfiguration-r8 RRCConnectionReconfiguration-r8-IEs, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReconfiguration-r8-IEs ::= SEQUENCE { - measConfig MeasConfig OPTIONAL, -- Need ON - mobilityControlInfo MobilityControlInfo OPTIONAL, -- Cond HO - dedicatedInfoNASList SEQUENCE (SIZE(1..maxDRB)) OF - DedicatedInfoNAS OPTIONAL, -- Cond nonHO - radioResourceConfigDedicated RadioResourceConfigDedicated OPTIONAL, -- Cond HO-toEUTRA - securityConfigHO SecurityConfigHO OPTIONAL, -- Cond HO - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -SecurityConfigHO ::= SEQUENCE { - handoverType CHOICE { - intraLTE SEQUENCE { - securityAlgorithmConfig SecurityAlgorithmConfig OPTIONAL, -- Need OP - keyChangeIndicator BOOLEAN, - nextHopChainingCount NextHopChainingCount - }, - interRAT SEQUENCE { - securityAlgorithmConfig SecurityAlgorithmConfig, - nas-SecurityParamToEUTRA OCTET STRING (SIZE(6)) - } - }, - ... -} - - -RRCConnectionReconfigurationComplete ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - rrcConnectionReconfigurationComplete-r8 - RRCConnectionReconfigurationComplete-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReconfigurationComplete-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -RRCConnectionReestablishment ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - rrcConnectionReestablishment-r8 RRCConnectionReestablishment-r8-IEs, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReestablishment-r8-IEs ::= SEQUENCE { - radioResourceConfigDedicated RadioResourceConfigDedicated, - nextHopChainingCount NextHopChainingCount, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -RRCConnectionReestablishmentComplete ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - rrcConnectionReestablishmentComplete-r8 - RRCConnectionReestablishmentComplete-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReestablishmentComplete-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -RRCConnectionReestablishmentReject ::= SEQUENCE { - criticalExtensions CHOICE { - rrcConnectionReestablishmentReject-r8 - RRCConnectionReestablishmentReject-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReestablishmentReject-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -RRCConnectionReestablishmentRequest ::= SEQUENCE { - criticalExtensions CHOICE { - rrcConnectionReestablishmentRequest-r8 - RRCConnectionReestablishmentRequest-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReestablishmentRequest-r8-IEs ::= SEQUENCE { - ue-Identity ReestabUE-Identity, - reestablishmentCause ReestablishmentCause, - spare BIT STRING (SIZE (2)) -} - -ReestabUE-Identity ::= SEQUENCE { - c-RNTI C-RNTI, - physCellId PhysCellId, - shortMAC-I ShortMAC-I -} - -ReestablishmentCause ::= ENUMERATED { - reconfigurationFailure, handoverFailure, - otherFailure, spare1} - - -RRCConnectionReject ::= SEQUENCE { - criticalExtensions CHOICE { - c1 CHOICE { - rrcConnectionReject-r8 RRCConnectionReject-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReject-r8-IEs ::= SEQUENCE { - waitTime INTEGER (1..16), - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -RRCConnectionRelease ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - rrcConnectionRelease-r8 RRCConnectionRelease-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionRelease-r8-IEs ::= SEQUENCE { - releaseCause ReleaseCause, - redirectedCarrierInfo RedirectedCarrierInfo OPTIONAL, -- Need ON - idleModeMobilityControlInfo IdleModeMobilityControlInfo OPTIONAL, -- Need OP - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -ReleaseCause ::= ENUMERATED {loadBalancingTAUrequired, - other,spare2, spare1 } - -RedirectedCarrierInfo ::= CHOICE { - eutra ARFCN-ValueEUTRA, - geran CarrierFreqsGERAN, - utra-FDD ARFCN-ValueUTRA, - utra-TDD ARFCN-ValueUTRA, - cdma2000-HRPD CarrierFreqCDMA2000, - cdma2000-1xRTT CarrierFreqCDMA2000, - ... -} - -IdleModeMobilityControlInfo ::= SEQUENCE { - freqPriorityListEUTRA FreqPriorityListEUTRA OPTIONAL, -- Need ON - freqPriorityListGERAN FreqsPriorityListGERAN OPTIONAL, -- Need ON - freqPriorityListUTRA-FDD FreqPriorityListUTRA-FDD OPTIONAL, -- Need ON - freqPriorityListUTRA-TDD FreqPriorityListUTRA-TDD OPTIONAL, -- Need ON - bandClassPriorityListHRPD BandClassPriorityListHRPD OPTIONAL, -- Need ON - bandClassPriorityList1XRTT BandClassPriorityList1XRTT OPTIONAL, -- Need ON - t320 ENUMERATED { - min5, min10, min20, min30, min60, min120, min180, - spare1} OPTIONAL, -- Need OR - ... -} - -FreqPriorityListEUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA - -FreqPriorityEUTRA ::= SEQUENCE { - carrierFreq ARFCN-ValueEUTRA, - cellReselectionPriority CellReselectionPriority -} - -FreqsPriorityListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF FreqsPriorityGERAN - -FreqsPriorityGERAN ::= SEQUENCE { - carrierFreqs CarrierFreqsGERAN, - cellReselectionPriority CellReselectionPriority -} - -FreqPriorityListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF FreqPriorityUTRA-FDD - -FreqPriorityUTRA-FDD ::= SEQUENCE { - carrierFreq ARFCN-ValueUTRA, - cellReselectionPriority CellReselectionPriority -} - -FreqPriorityListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF FreqPriorityUTRA-TDD - -FreqPriorityUTRA-TDD ::= SEQUENCE { - carrierFreq ARFCN-ValueUTRA, - cellReselectionPriority CellReselectionPriority -} - -BandClassPriorityListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriorityHRPD - -BandClassPriorityHRPD ::= SEQUENCE { - bandClass BandclassCDMA2000, - cellReselectionPriority CellReselectionPriority -} - -BandClassPriorityList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriority1XRTT - -BandClassPriority1XRTT ::= SEQUENCE { - bandClass BandclassCDMA2000, - cellReselectionPriority CellReselectionPriority -} - -RRCConnectionRequest ::= SEQUENCE { - criticalExtensions CHOICE { - rrcConnectionRequest-r8 RRCConnectionRequest-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionRequest-r8-IEs ::= SEQUENCE { - ue-Identity InitialUE-Identity, - establishmentCause EstablishmentCause, - spare BIT STRING (SIZE (1)) -} - -InitialUE-Identity ::= CHOICE { - s-TMSI S-TMSI, - randomValue BIT STRING (SIZE (40)) -} - -EstablishmentCause ::= ENUMERATED { - emergency, highPriorityAccess, mt-Access, mo-Signalling, - mo-Data, spare3, spare2, spare1} - - -RRCConnectionSetup ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - rrcConnectionSetup-r8 RRCConnectionSetup-r8-IEs, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionSetup-r8-IEs ::= SEQUENCE { - radioResourceConfigDedicated RadioResourceConfigDedicated, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -RRCConnectionSetupComplete ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - rrcConnectionSetupComplete-r8 RRCConnectionSetupComplete-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionSetupComplete-r8-IEs ::= SEQUENCE { - selectedPLMN-Identity INTEGER (1..6), - registeredMME RegisteredMME OPTIONAL, - dedicatedInfoNAS DedicatedInfoNAS, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - -RegisteredMME ::= SEQUENCE { - plmn-Identity PLMN-Identity OPTIONAL, - mmegi BIT STRING (SIZE (16)), - mmec MMEC -} - - -SecurityModeCommand ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - securityModeCommand-r8 SecurityModeCommand-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -SecurityModeCommand-r8-IEs ::= SEQUENCE { - securityConfigSMC SecurityConfigSMC, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -SecurityConfigSMC ::= SEQUENCE { - securityAlgorithmConfig SecurityAlgorithmConfig, - ... -} - - -SecurityModeComplete ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - securityModeComplete-r8 SecurityModeComplete-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -SecurityModeComplete-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -SecurityModeFailure ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - securityModeFailure-r8 SecurityModeFailure-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -SecurityModeFailure-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -SystemInformation ::= SEQUENCE { - criticalExtensions CHOICE { - systemInformation-r8 SystemInformation-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} -SystemInformation-r8-IEs ::= SEQUENCE { - sib-TypeAndInfo SEQUENCE (SIZE (1..maxSIB)) OF CHOICE { - sib2 SystemInformationBlockType2, - sib3 SystemInformationBlockType3, - sib4 SystemInformationBlockType4, - sib5 SystemInformationBlockType5, - sib6 SystemInformationBlockType6, - sib7 SystemInformationBlockType7, - sib8 SystemInformationBlockType8, - sib9 SystemInformationBlockType9, - sib10 SystemInformationBlockType10, - sib11 SystemInformationBlockType11, - ... - }, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -SystemInformationBlockType1 ::= SEQUENCE { - cellAccessRelatedInfo SEQUENCE { - plmn-IdentityList PLMN-IdentityList, - trackingAreaCode TrackingAreaCode, - cellIdentity CellIdentity, - cellBarred ENUMERATED {barred, notBarred}, - intraFreqReselection ENUMERATED {allowed, notAllowed}, - csg-Indication BOOLEAN, - csg-Identity BIT STRING (SIZE (27)) OPTIONAL -- Need OR - }, - cellSelectionInfo SEQUENCE { - q-RxLevMin Q-RxLevMin, - q-RxLevMinOffset INTEGER (1..8) OPTIONAL -- Need OP - }, - p-Max P-Max OPTIONAL, -- Need OP - freqBandIndicator INTEGER (1..64), - schedulingInfoList SchedulingInfoList, - tdd-Config TDD-Config OPTIONAL, -- Cond TDD - si-WindowLength ENUMERATED { - ms1, ms2, ms5, ms10, ms15, ms20, - ms40}, - systemInfoValueTag INTEGER (0..31), - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -PLMN-IdentityList ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo - -PLMN-IdentityInfo ::= SEQUENCE { - plmn-Identity PLMN-Identity, - cellReservedForOperatorUse ENUMERATED {reserved, notReserved} -} - -SchedulingInfoList ::= SEQUENCE (SIZE (1..maxSI-Message)) OF SchedulingInfo - -SchedulingInfo ::= SEQUENCE { - si-Periodicity ENUMERATED { - rf8, rf16, rf32, rf64, rf128, rf256, rf512}, - sib-MappingInfo SIB-MappingInfo -} - -SIB-MappingInfo ::= SEQUENCE (SIZE (0..maxSIB-1)) OF SIB-Type - -SIB-Type ::= ENUMERATED { - sibType3, sibType4, sibType5, sibType6, - sibType7, sibType8, sibType9, sibType10, - sibType11, spare7, spare6, spare5, - spare4, spare3, spare2, spare1, ...} - - -UECapabilityEnquiry ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - ueCapabilityEnquiry-r8 UECapabilityEnquiry-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -UECapabilityEnquiry-r8-IEs ::= SEQUENCE { - ue-CapabilityRequest UE-CapabilityRequest, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -UE-CapabilityRequest ::= SEQUENCE (SIZE (1..maxRAT-Capabilities)) OF RAT-Type - - -UECapabilityInformation ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - ueCapabilityInformation-r8 UECapabilityInformation-r8-IEs, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -UECapabilityInformation-r8-IEs ::= SEQUENCE { - ue-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -ULHandoverPreparationTransfer ::= SEQUENCE { - criticalExtensions CHOICE { - c1 CHOICE { - ulHandoverPreparationTransfer-r8 ULHandoverPreparationTransfer-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE { - cdma2000-Type CDMA2000-Type, - meid BIT STRING (SIZE (56)) OPTIONAL, - dedicatedInfo DedicatedInfoCDMA2000, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -ULInformationTransfer ::= SEQUENCE { - criticalExtensions CHOICE { - c1 CHOICE { - ulInformationTransfer-r8 ULInformationTransfer-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -ULInformationTransfer-r8-IEs ::= SEQUENCE { - dedicatedInfoType CHOICE { - dedicatedInfoNAS DedicatedInfoNAS, - dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000, - dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000 - }, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -SystemInformationBlockType2 ::= SEQUENCE { - ac-BarringInfo SEQUENCE { - ac-BarringForEmergency BOOLEAN, - ac-BarringForMO-Signalling AC-BarringConfig OPTIONAL, -- Need OP - ac-BarringForMO-Data AC-BarringConfig OPTIONAL -- Need OP - } OPTIONAL, -- Need OP - radioResourceConfigCommon RadioResourceConfigCommonSIB, - ue-TimersAndConstants UE-TimersAndConstants, - freqInfo SEQUENCE { - ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL, -- Need OP - ul-Bandwidth ENUMERATED {n6, n15, n25, n50, n75, n100} - OPTIONAL, -- Need OP - additionalSpectrumEmission AdditionalSpectrumEmission - }, - mbsfn-SubframeConfigList MBSFN-SubframeConfigList OPTIONAL, -- Need OR - timeAlignmentTimerCommon TimeAlignmentTimer, - ... -} - -AC-BarringConfig ::= SEQUENCE { - ac-BarringFactor ENUMERATED { - p00, p05, p10, p15, p20, p25, p30, p40, - p50, p60, p70, p75, p80, p85, p90, p95}, - ac-BarringTime ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512}, - ac-BarringForSpecialAC BIT STRING (SIZE(5)) -} - -MBSFN-SubframeConfigList ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig - -MBSFN-SubframeConfig ::= SEQUENCE { - radioframeAllocationPeriod ENUMERATED {n1, n2, n4, n8, n16, n32}, - radioframeAllocationOffset INTEGER (0..7), - subframeAllocation CHOICE { - oneFrame BIT STRING (SIZE(6)), - fourFrames BIT STRING (SIZE(24)) - } -} - -SystemInformationBlockType3 ::= SEQUENCE { - cellReselectionInfoCommon SEQUENCE { - q-Hyst ENUMERATED { - dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10, - dB12, dB14, dB16, dB18, dB20, dB22, dB24}, - speedStateReselectionPars SEQUENCE { - mobilityStateParameters MobilityStateParameters, - q-HystSF SEQUENCE { - sf-Medium ENUMERATED { - dB-6, dB-4, dB-2, dB0}, - sf-High ENUMERATED { - dB-6, dB-4, dB-2, dB0} - } - } OPTIONAL -- Need OP - }, - cellReselectionServingFreqInfo SEQUENCE { - s-NonIntraSearch ReselectionThreshold OPTIONAL, -- Need OP - threshServingLow ReselectionThreshold, - cellReselectionPriority CellReselectionPriority - }, - intraFreqCellReselectionInfo SEQUENCE { - q-RxLevMin Q-RxLevMin, - p-Max P-Max OPTIONAL, -- Need OP - s-IntraSearch ReselectionThreshold OPTIONAL, -- Need OP - allowedMeasBandwidth AllowedMeasBandwidth OPTIONAL, -- Need OP - presenceAntennaPort1 PresenceAntennaPort1, - neighCellConfig NeighCellConfig, - t-ReselectionEUTRA T-Reselection, - t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL -- Need OP - }, - ... -} - - -SystemInformationBlockType4 ::= SEQUENCE { - intraFreqNeighCellList IntraFreqNeighCellList OPTIONAL, -- Need OR - intraFreqBlackCellList IntraFreqBlackCellList OPTIONAL, -- Need OR - csg-PhysCellIdRange PhysCellIdRange OPTIONAL, -- Cond CSG - ... -} - -IntraFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellIntra)) OF IntraFreqNeighCellInfo - -IntraFreqNeighCellInfo ::= SEQUENCE { - physCellId PhysCellId, - q-OffsetCell Q-OffsetRange, - ... -} - -IntraFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange - - -SystemInformationBlockType5 ::= SEQUENCE { - interFreqCarrierFreqList InterFreqCarrierFreqList, - ... -} - -InterFreqCarrierFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo - -InterFreqCarrierFreqInfo ::= SEQUENCE { - dl-CarrierFreq ARFCN-ValueEUTRA, - q-RxLevMin Q-RxLevMin, - p-Max P-Max OPTIONAL, -- Need OP - t-ReselectionEUTRA T-Reselection, - t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP - threshX-High ReselectionThreshold, - threshX-Low ReselectionThreshold, - allowedMeasBandwidth AllowedMeasBandwidth, - presenceAntennaPort1 PresenceAntennaPort1, - cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP - neighCellConfig NeighCellConfig, - q-OffsetFreq Q-OffsetRange DEFAULT dB0, - interFreqNeighCellList InterFreqNeighCellList OPTIONAL, -- Need OR - interFreqBlackCellList InterFreqBlackCellList OPTIONAL, -- Need OR - ... -} - -InterFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellInter)) OF InterFreqNeighCellInfo - -InterFreqNeighCellInfo ::= SEQUENCE { - physCellId PhysCellId, - q-OffsetCell Q-OffsetRange -} - -InterFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange - - -SystemInformationBlockType6 ::= SEQUENCE { - carrierFreqListUTRA-FDD CarrierFreqListUTRA-FDD OPTIONAL, -- Need OR - carrierFreqListUTRA-TDD CarrierFreqListUTRA-TDD OPTIONAL, -- Need OR - t-ReselectionUTRA T-Reselection, - t-ReselectionUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP - ... -} - -CarrierFreqListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF CarrierFreqUTRA-FDD - -CarrierFreqUTRA-FDD ::= SEQUENCE { - carrierFreq ARFCN-ValueUTRA, - cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP - threshX-High ReselectionThreshold, - threshX-Low ReselectionThreshold, - q-RxLevMin INTEGER (-60..-13), - p-MaxUTRA INTEGER (-50..33), - q-QualMin INTEGER (-24..0), - ... -} - -CarrierFreqListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF CarrierFreqUTRA-TDD - -CarrierFreqUTRA-TDD ::= SEQUENCE { - carrierFreq ARFCN-ValueUTRA, - cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP - threshX-High ReselectionThreshold, - threshX-Low ReselectionThreshold, - q-RxLevMin INTEGER (-60..-13), - p-MaxUTRA INTEGER (-50..33), - ... -} - - -SystemInformationBlockType7 ::= SEQUENCE { - t-ReselectionGERAN T-Reselection, - t-ReselectionGERAN-SF SpeedStateScaleFactors OPTIONAL, -- Need OR - carrierFreqsInfoList CarrierFreqsInfoListGERAN OPTIONAL, -- Need OR - ... -} - -CarrierFreqsInfoListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF CarrierFreqsInfoGERAN - -CarrierFreqsInfoGERAN ::= SEQUENCE { - carrierFreqs CarrierFreqsGERAN, - commonInfo SEQUENCE { - cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP - ncc-Permitted BIT STRING (SIZE (8)), - q-RxLevMin INTEGER (0..45), - p-MaxGERAN INTEGER (0..39) OPTIONAL, -- Need OP - threshX-High ReselectionThreshold, - threshX-Low ReselectionThreshold - }, - ... -} - - -SystemInformationBlockType8 ::= SEQUENCE { - systemTimeInfo SystemTimeInfoCDMA2000 OPTIONAL, -- Need OR - searchWindowSize INTEGER (0..15) OPTIONAL, -- Need OR - parametersHRPD SEQUENCE { - preRegistrationInfoHRPD PreRegistrationInfoHRPD, - cellReselectionParametersHRPD CellReselectionParametersCDMA2000 OPTIONAL -- Need OR - } OPTIONAL, -- Need OR - parameters1XRTT SEQUENCE { - csfb-RegistrationParam1XRTT CSFB-RegistrationParam1XRTT OPTIONAL, -- Need OP - longCodeState1XRTT BIT STRING (SIZE (42)) OPTIONAL, -- Need OR - cellReselectionParameters1XRTT CellReselectionParametersCDMA2000 OPTIONAL -- Need OR - } OPTIONAL, -- Need OR - ... -} - -CellReselectionParametersCDMA2000 ::= SEQUENCE { - bandClassList BandClassListCDMA2000, - neighCellList NeighCellListCDMA2000, - t-ReselectionCDMA2000 T-Reselection, - t-ReselectionCDMA2000-SF SpeedStateScaleFactors OPTIONAL -- Need OP -} -NeighCellListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000 - -NeighCellCDMA2000 ::= SEQUENCE { - bandClass BandclassCDMA2000, - neighCellsPerFreqList NeighCellsPerBandclassListCDMA2000 -} - -NeighCellsPerBandclassListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000 - -NeighCellsPerBandclassCDMA2000 ::= SEQUENCE { - arfcn ARFCN-ValueCDMA2000, - physCellIdList PhysCellIdListCDMA2000 -} - -PhysCellIdListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdCDMA2000 - -BandClassListCDMA2000 ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassInfoCDMA2000 - -BandClassInfoCDMA2000 ::= SEQUENCE { - bandClass BandclassCDMA2000, - cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP - threshX-High INTEGER (0..63), - threshX-Low INTEGER (0..63), - ... -} - - -SystemInformationBlockType9 ::= SEQUENCE { - hnb-Name OCTET STRING (SIZE(1..48)) OPTIONAL, -- Need OR - ... -} - - -SystemInformationBlockType10 ::= SEQUENCE { - messageIdentifier BIT STRING (SIZE (16)), - serialNumber BIT STRING (SIZE (16)), - warningType OCTET STRING (SIZE (2)), - warningSecurityInfo OCTET STRING (SIZE (50)) OPTIONAL, -- Need OP - ... -} - - -SystemInformationBlockType11 ::= SEQUENCE { - messageIdentifier BIT STRING (SIZE (16)), - serialNumber BIT STRING (SIZE (16)), - warningMessageSegmentType ENUMERATED {notLastSegment, lastSegment}, - warningMessageSegmentNumber INTEGER (0..63), - warningMessageSegment OCTET STRING, - dataCodingScheme OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1 - ... -} - - -AntennaInfoCommon ::= SEQUENCE { - antennaPortsCount ENUMERATED {an1, an2, an4, spare1} -} - -AntennaInfoDedicated ::= SEQUENCE { - transmissionMode ENUMERATED { - tm1, tm2, tm3, tm4, tm5, tm6, - tm7, spare1}, - codebookSubsetRestriction CHOICE { - n2TxAntenna-tm3 BIT STRING (SIZE (2)), - n4TxAntenna-tm3 BIT STRING (SIZE (4)), - n2TxAntenna-tm4 BIT STRING (SIZE (6)), - n4TxAntenna-tm4 BIT STRING (SIZE (64)), - n2TxAntenna-tm5 BIT STRING (SIZE (4)), - n4TxAntenna-tm5 BIT STRING (SIZE (16)), - n2TxAntenna-tm6 BIT STRING (SIZE (4)), - n4TxAntenna-tm6 BIT STRING (SIZE (16)) - } OPTIONAL, -- Cond TM - ue-TransmitAntennaSelection CHOICE{ - release NULL, - setup ENUMERATED {closedLoop, openLoop} - } -} - - -CQI-ReportConfig ::= SEQUENCE { - cqi-ReportModeAperiodic ENUMERATED { - rm12, rm20, rm22, rm30, rm31, - spare3, spare2, spare1} OPTIONAL, -- Need OR - nomPDSCH-RS-EPRE-Offset INTEGER (-1..6), - cqi-ReportPeriodic CQI-ReportPeriodic OPTIONAL -- Need ON -} - -CQI-ReportPeriodic ::= CHOICE { - release NULL, - setup SEQUENCE { - cqi-PUCCH-ResourceIndex INTEGER (0.. 1185), - cqi-pmi-ConfigIndex INTEGER (0..1023), - cqi-FormatIndicatorPeriodic CHOICE { - widebandCQI NULL, - subbandCQI SEQUENCE { - k INTEGER (1..4) - } - }, - ri-ConfigIndex INTEGER (0..1023) OPTIONAL, -- Need OR - simultaneousAckNackAndCQI BOOLEAN - } -} - - -DRB-Identity ::= INTEGER (1..32) - - -LogicalChannelConfig ::= SEQUENCE { - ul-SpecificParameters SEQUENCE { - priority INTEGER (1..16), - prioritisedBitRate ENUMERATED { - kBps0, kBps8, kBps16, kBps32, kBps64, kBps128, - kBps256, infinity, spare8, spare7, spare6, - spare5, spare4, spare3, spare2, spare1}, - bucketSizeDuration ENUMERATED { - ms50, ms100, ms150, ms300, ms500, ms1000, spare2, - spare1}, - logicalChannelGroup INTEGER (0..3) OPTIONAL -- Need OR - } OPTIONAL, -- Cond UL - ... -} - - -MAC-MainConfig ::= SEQUENCE { - ul-SCH-Config SEQUENCE { - maxHARQ-Tx ENUMERATED { - n1, n2, n3, n4, n5, n6, n7, n8, - n10, n12, n16, n20, n24, n28, - spare2, spare1} OPTIONAL, -- Need ON - periodicBSR-Timer ENUMERATED { - sf5, sf10, sf16, sf20, sf32, sf40, sf64, sf80, - sf128, sf160, sf320, sf640, sf1280, sf2560, - infinity, spare1} OPTIONAL, -- Need ON - retxBSR-Timer ENUMERATED { - sf320, sf640, sf1280, sf2560, sf5120, - sf10240, spare2, spare1}, - ttiBundling BOOLEAN - } OPTIONAL, -- Need ON - drx-Config DRX-Config OPTIONAL, -- Need ON - timeAlignmentTimerDedicated TimeAlignmentTimer, - phr-Config CHOICE { - release NULL, - setup SEQUENCE { - periodicPHR-Timer ENUMERATED {sf10, sf20, sf50, sf100, sf200, - sf500, sf1000, infinity}, - prohibitPHR-Timer ENUMERATED {sf0, sf10, sf20, sf50, sf100, - sf200, sf500, sf1000}, - dl-PathlossChange ENUMERATED {dB1, dB3, dB6, infinity} - } - } OPTIONAL, -- Need ON - ... -} - -DRX-Config ::= CHOICE { - release NULL, - setup SEQUENCE { - onDurationTimer ENUMERATED { - psf1, psf2, psf3, psf4, psf5, psf6, - psf8, psf10, psf20, psf30, psf40, - psf50, psf60, psf80, psf100, - psf200}, - drx-InactivityTimer ENUMERATED { - psf1, psf2, psf3, psf4, psf5, psf6, - psf8, psf10, psf20, psf30, psf40, - psf50, psf60, psf80, psf100, - psf200, psf300, psf500, psf750, - psf1280, psf1920, psf2560, spare10, - spare9, spare8, spare7, spare6, - spare5, spare4, spare3, spare2, - spare1}, - drx-RetransmissionTimer ENUMERATED { - psf1, psf2, psf4, psf6, psf8, psf16, - psf24, psf33}, - longDRX-CycleStartOffset CHOICE { - sf10 INTEGER(0..9), - sf20 INTEGER(0..19), - sf32 INTEGER(0..31), - sf40 INTEGER(0..39), - sf64 INTEGER(0..63), - sf80 INTEGER(0..79), - sf128 INTEGER(0..127), - sf160 INTEGER(0..159), - sf256 INTEGER(0..255), - sf320 INTEGER(0..319), - sf512 INTEGER(0..511), - sf640 INTEGER(0..639), - sf1024 INTEGER(0..1023), - sf1280 INTEGER(0..1279), - sf2048 INTEGER(0..2047), - sf2560 INTEGER(0..2559) - }, - shortDRX SEQUENCE { - shortDRX-Cycle ENUMERATED { - sf2, sf5, sf8, sf10, sf16, sf20, - sf32, sf40, sf64, sf80, sf128, sf160, - sf256, sf320, sf512, sf640}, - drxShortCycleTimer INTEGER (1..16) - } OPTIONAL -- Need OR - } -} - - -PDCP-Config ::= SEQUENCE { - discardTimer ENUMERATED { - ms50, ms100, ms150, ms300, ms500, - ms750, ms1500, infinity - } OPTIONAL, -- Cond Setup - rlc-AM SEQUENCE { - statusReportRequired BOOLEAN - } OPTIONAL, -- Cond Rlc-AM - rlc-UM SEQUENCE { - pdcp-SN-Size ENUMERATED {len7bits, len12bits} - } OPTIONAL, -- Cond Rlc-UM - headerCompression CHOICE { - notUsed NULL, - rohc SEQUENCE { - maxCID INTEGER (1..16383) DEFAULT 15, - profiles SEQUENCE { - profile0x0001 BOOLEAN, - profile0x0002 BOOLEAN, - profile0x0003 BOOLEAN, - profile0x0004 BOOLEAN, - profile0x0006 BOOLEAN, - profile0x0101 BOOLEAN, - profile0x0102 BOOLEAN, - profile0x0103 BOOLEAN, - profile0x0104 BOOLEAN - }, - ... - } - }, - ... -} - - -PDSCH-ConfigCommon::= SEQUENCE { - referenceSignalPower INTEGER (-60..50), - p-b INTEGER (0..3) -} - -PDSCH-ConfigDedicated::= SEQUENCE { - p-a ENUMERATED { - dB-6, dB-4dot77, dB-3, dB-1dot77, - dB0, dB1, dB2, dB3 } -} - - -PHICH-Config ::= SEQUENCE { - phich-Duration ENUMERATED {normal, extended}, - phich-Resource ENUMERATED {oneSixth, half, one, two} -} - - -PhysicalConfigDedicated ::= SEQUENCE { - pdsch-ConfigDedicated PDSCH-ConfigDedicated OPTIONAL, -- Need ON - pucch-ConfigDedicated PUCCH-ConfigDedicated OPTIONAL, -- Need ON - pusch-ConfigDedicated PUSCH-ConfigDedicated OPTIONAL, -- Need ON - uplinkPowerControlDedicated UplinkPowerControlDedicated OPTIONAL, -- Need ON - tpc-PDCCH-ConfigPUCCH TPC-PDCCH-Config OPTIONAL, -- Need ON - tpc-PDCCH-ConfigPUSCH TPC-PDCCH-Config OPTIONAL, -- Need ON - cqi-ReportConfig CQI-ReportConfig OPTIONAL, -- Need ON - soundingRS-UL-ConfigDedicated SoundingRS-UL-ConfigDedicated OPTIONAL, -- Need ON - antennaInfo CHOICE { - explicitValue AntennaInfoDedicated, - defaultValue NULL - } OPTIONAL, -- Need ON - schedulingRequestConfig SchedulingRequestConfig OPTIONAL, -- Need ON - ... -} - - -P-Max ::= INTEGER (-30..33) - - -PRACH-ConfigSIB ::= SEQUENCE { - rootSequenceIndex INTEGER (0..837), - prach-ConfigInfo PRACH-ConfigInfo -} - -PRACH-Config ::= SEQUENCE { - rootSequenceIndex INTEGER (0..837), - prach-ConfigInfo PRACH-ConfigInfo OPTIONAL -- Need ON -} - -PRACH-ConfigInfo ::= SEQUENCE { - prach-ConfigIndex INTEGER (0..63), - highSpeedFlag BOOLEAN, - zeroCorrelationZoneConfig INTEGER (0..15), - prach-FreqOffset INTEGER (0..94) -} - - -PresenceAntennaPort1 ::= BOOLEAN - - -PUCCH-ConfigCommon ::= SEQUENCE { - deltaPUCCH-Shift ENUMERATED {ds1, ds2, ds3}, - nRB-CQI INTEGER (0..98), - nCS-AN INTEGER (0..7), - n1PUCCH-AN INTEGER (0..2047) -} - -PUCCH-ConfigDedicated ::= SEQUENCE { - ackNackRepetition CHOICE{ - release NULL, - setup SEQUENCE { - repetitionFactor ENUMERATED { n2, n4, n6, spare1}, - n1PUCCH-AN-Rep INTEGER (0..2047) - } - }, - tdd-AckNackFeedbackMode ENUMERATED {bundling, multiplexing} OPTIONAL -- Cond TDD -} - - -PUSCH-ConfigCommon ::= SEQUENCE { - pusch-ConfigBasic SEQUENCE { - n-SB INTEGER (1..4), - hoppingMode ENUMERATED {interSubFrame, intraAndInterSubFrame}, - pusch-HoppingOffset INTEGER (0..98), - enable64QAM BOOLEAN - }, - ul-ReferenceSignalsPUSCH UL-ReferenceSignalsPUSCH -} - -PUSCH-ConfigDedicated ::= SEQUENCE { - betaOffset-ACK-Index INTEGER (0..15), - betaOffset-RI-Index INTEGER (0..15), - betaOffset-CQI-Index INTEGER (0..15) -} - -UL-ReferenceSignalsPUSCH ::= SEQUENCE { - groupHoppingEnabled BOOLEAN, - groupAssignmentPUSCH INTEGER (0..29), - sequenceHoppingEnabled BOOLEAN, - cyclicShift INTEGER (0..7) -} - - -RACH-ConfigCommon ::= SEQUENCE { - preambleInfo SEQUENCE { - numberOfRA-Preambles ENUMERATED { - n4, n8, n12, n16 ,n20, n24, n28, - n32, n36, n40, n44, n48, n52, n56, - n60, n64}, - preamblesGroupAConfig SEQUENCE { - sizeOfRA-PreamblesGroupA ENUMERATED { - n4, n8, n12, n16 ,n20, n24, n28, - n32, n36, n40, n44, n48, n52, n56, - n60}, - messageSizeGroupA ENUMERATED {b56, b144, b208, b256}, - messagePowerOffsetGroupB ENUMERATED { - minusinfinity, dB0, dB5, dB8, dB10, dB12, - dB15, dB18}, - ... - } OPTIONAL -- Need OP - }, - powerRampingParameters SEQUENCE { - powerRampingStep ENUMERATED {dB0, dB2,dB4, dB6}, - preambleInitialReceivedTargetPower ENUMERATED { - dBm-120, dBm-118, dBm-116, dBm-114, dBm-112, - dBm-110, dBm-108, dBm-106, dBm-104, dBm-102, - dBm-100, dBm-98, dBm-96, dBm-94, - dBm-92, dBm-90} - }, - ra-SupervisionInfo SEQUENCE { - preambleTransMax ENUMERATED { - n3, n4, n5, n6, n7, n8, n10, n20, n50, - n100, n200}, - ra-ResponseWindowSize ENUMERATED { - sf2, sf3, sf4, sf5, sf6, sf7, - sf8, sf10}, - mac-ContentionResolutionTimer ENUMERATED { - sf8, sf16, sf24, sf32, sf40, sf48, - sf56, sf64} - }, - maxHARQ-Msg3Tx INTEGER (1..8), - ... -} - - -RACH-ConfigDedicated ::= SEQUENCE { - ra-PreambleIndex INTEGER (0..63), - ra-PRACH-MaskIndex INTEGER (0..15) -} - - -RadioResourceConfigCommonSIB ::= SEQUENCE { - rach-ConfigCommon RACH-ConfigCommon, - bcch-Config BCCH-Config, - pcch-Config PCCH-Config, - prach-Config PRACH-ConfigSIB, - pdsch-ConfigCommon PDSCH-ConfigCommon, - pusch-ConfigCommon PUSCH-ConfigCommon, - pucch-ConfigCommon PUCCH-ConfigCommon, - soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon, - uplinkPowerControlCommon UplinkPowerControlCommon, - ul-CyclicPrefixLength UL-CyclicPrefixLength, - ... -} - -RadioResourceConfigCommon ::= SEQUENCE { - rach-ConfigCommon RACH-ConfigCommon OPTIONAL, -- Need ON - prach-Config PRACH-Config, - pdsch-ConfigCommon PDSCH-ConfigCommon OPTIONAL, -- Need ON - pusch-ConfigCommon PUSCH-ConfigCommon, - phich-Config PHICH-Config OPTIONAL, -- Need ON - pucch-ConfigCommon PUCCH-ConfigCommon OPTIONAL, -- Need ON - soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon OPTIONAL, -- Need ON - uplinkPowerControlCommon UplinkPowerControlCommon OPTIONAL, -- Need ON - antennaInfoCommon AntennaInfoCommon OPTIONAL, -- Need ON - p-Max P-Max OPTIONAL, -- Need OP - tdd-Config TDD-Config OPTIONAL, -- Cond TDD - ul-CyclicPrefixLength UL-CyclicPrefixLength, - ... -} - -BCCH-Config ::= SEQUENCE { - modificationPeriodCoeff ENUMERATED {n2, n4, n8, n16} -} - -PCCH-Config ::= SEQUENCE { - defaultPagingCycle ENUMERATED { - rf32, rf64, rf128, rf256}, - nB ENUMERATED { - fourT, twoT, oneT, halfT, quarterT, oneEighthT, - oneSixteenthT, oneThirtySecondT} -} - -UL-CyclicPrefixLength ::= ENUMERATED {len1, len2} - - -RadioResourceConfigDedicated ::= SEQUENCE { - srb-ToAddModList SRB-ToAddModList OPTIONAL, -- Cond HO-Conn - drb-ToAddModList DRB-ToAddModList OPTIONAL, -- Cond HO-toEUTRA - drb-ToReleaseList DRB-ToReleaseList OPTIONAL, -- Need ON - mac-MainConfig CHOICE { - explicitValue MAC-MainConfig, - defaultValue NULL - } OPTIONAL, -- Cond HO-toEUTRA2 - sps-Config SPS-Config OPTIONAL, -- Need ON - physicalConfigDedicated PhysicalConfigDedicated OPTIONAL, -- Need ON - ... -} - -SRB-ToAddModList ::= SEQUENCE (SIZE (1..2)) OF SRB-ToAddMod - -SRB-ToAddMod ::= SEQUENCE { - srb-Identity INTEGER (1..2), - rlc-Config CHOICE { - explicitValue RLC-Config, - defaultValue NULL - } OPTIONAL, -- Cond Setup - logicalChannelConfig CHOICE { - explicitValue LogicalChannelConfig, - defaultValue NULL - } OPTIONAL, -- Cond Setup - ... -} - -DRB-ToAddModList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddMod - -DRB-ToAddMod ::= SEQUENCE { - eps-BearerIdentity INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup - drb-Identity DRB-Identity, - pdcp-Config PDCP-Config OPTIONAL, -- Cond PDCP - rlc-Config RLC-Config OPTIONAL, -- Cond Setup - logicalChannelIdentity INTEGER (3..10) OPTIONAL, -- Cond DRB-Setup - logicalChannelConfig LogicalChannelConfig OPTIONAL, -- Cond Setup - ... -} - -DRB-ToReleaseList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-Identity - - -RLC-Config ::= CHOICE { - am SEQUENCE { - ul-AM-RLC UL-AM-RLC, - dl-AM-RLC DL-AM-RLC - }, - um-Bi-Directional SEQUENCE { - ul-UM-RLC UL-UM-RLC, - dl-UM-RLC DL-UM-RLC - }, - um-Uni-Directional-UL SEQUENCE { - ul-UM-RLC UL-UM-RLC - }, - um-Uni-Directional-DL SEQUENCE { - dl-UM-RLC DL-UM-RLC - }, - ... -} - -UL-AM-RLC ::= SEQUENCE { - t-PollRetransmit T-PollRetransmit, - pollPDU PollPDU, - pollByte PollByte, - maxRetxThreshold ENUMERATED { - t1, t2, t3, t4, t6, t8, t16, t32} -} - -DL-AM-RLC ::= SEQUENCE { - t-Reordering T-Reordering, - t-StatusProhibit T-StatusProhibit -} - -UL-UM-RLC ::= SEQUENCE { - sn-FieldLength SN-FieldLength -} - -DL-UM-RLC ::= SEQUENCE { - sn-FieldLength SN-FieldLength, - t-Reordering T-Reordering -} - -SN-FieldLength ::= ENUMERATED {size5, size10} - -T-PollRetransmit ::= ENUMERATED { - ms5, ms10, ms15, ms20, ms25, ms30, ms35, - ms40, ms45, ms50, ms55, ms60, ms65, ms70, - ms75, ms80, ms85, ms90, ms95, ms100, ms105, - ms110, ms115, ms120, ms125, ms130, ms135, - ms140, ms145, ms150, ms155, ms160, ms165, - ms170, ms175, ms180, ms185, ms190, ms195, - ms200, ms205, ms210, ms215, ms220, ms225, - ms230, ms235, ms240, ms245, ms250, ms300, - ms350, ms400, ms450, ms500, spare9, spare8, - spare7, spare6, spare5, spare4, spare3, - spare2, spare1} - -PollPDU ::= ENUMERATED { - p4, p8, p16, p32, p64, p128, p256, pInfinity} - -PollByte ::= ENUMERATED { - kB25, kB50, kB75, kB100, kB125, kB250, kB375, - kB500, kB750, kB1000, kB1250, kB1500, kB2000, - kB3000, kBinfinity, spare1} - -T-Reordering ::= ENUMERATED { - ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35, - ms40, ms45, ms50, ms55, ms60, ms65, ms70, - ms75, ms80, ms85, ms90, ms95, ms100, ms110, - ms120, ms130, ms140, ms150, ms160, ms170, - ms180, ms190, ms200, spare1} - -T-StatusProhibit ::= ENUMERATED { - ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35, - ms40, ms45, ms50, ms55, ms60, ms65, ms70, - ms75, ms80, ms85, ms90, ms95, ms100, ms105, - ms110, ms115, ms120, ms125, ms130, ms135, - ms140, ms145, ms150, ms155, ms160, ms165, - ms170, ms175, ms180, ms185, ms190, ms195, - ms200, ms205, ms210, ms215, ms220, ms225, - ms230, ms235, ms240, ms245, ms250, ms300, - ms350, ms400, ms450, ms500, spare8, spare7, - spare6, spare5, spare4, spare3, spare2, - spare1} - - -SchedulingRequestConfig ::= CHOICE { - release NULL, - setup SEQUENCE { - sr-PUCCH-ResourceIndex INTEGER (0..2047), - sr-ConfigIndex INTEGER (0..155), - dsr-TransMax ENUMERATED { - n4, n8, n16, n32, n64, spare3, spare2, spare1} - } -} - - -SoundingRS-UL-ConfigCommon ::= CHOICE { - release NULL, - setup SEQUENCE { - srs-BandwidthConfig ENUMERATED {bw0, bw1, bw2, bw3, bw4, bw5, bw6, bw7}, - srs-SubframeConfig ENUMERATED { - sc0, sc1, sc2, sc3, sc4, sc5, sc6, sc7, - sc8, sc9, sc10, sc11, sc12, sc13, sc14, sc15}, - ackNackSRS-SimultaneousTransmission BOOLEAN, - srs-MaxUpPts ENUMERATED {true} OPTIONAL -- Cond TDD - } -} - -SoundingRS-UL-ConfigDedicated ::= CHOICE{ - release NULL, - setup SEQUENCE { - srs-Bandwidth ENUMERATED {bw0, bw1, bw2, bw3}, - srs-HoppingBandwidth ENUMERATED {hbw0, hbw1, hbw2, hbw3}, - freqDomainPosition INTEGER (0..23), - duration BOOLEAN, - srs-ConfigIndex INTEGER (0..1023), - transmissionComb INTEGER (0..1), - cyclicShift ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7} - } -} - - - -SPS-Config ::= SEQUENCE { - semiPersistSchedC-RNTI C-RNTI OPTIONAL, -- Need OR - sps-ConfigDL SPS-ConfigDL OPTIONAL, -- Need ON - sps-ConfigUL SPS-ConfigUL OPTIONAL -- Need ON -} - -SPS-ConfigDL ::= CHOICE{ - release NULL, - setup SEQUENCE { - semiPersistSchedIntervalDL ENUMERATED { - sf10, sf20, sf32, sf40, sf64, sf80, - sf128, sf160, sf320, sf640, spare6, - spare5, spare4, spare3, spare2, - spare1}, - numberOfConfSPS-Processes INTEGER (1..8), - n1-PUCCH-AN-PersistentList N1-PUCCH-AN-PersistentList, - ... - } -} - -SPS-ConfigUL ::= CHOICE { - release NULL, - setup SEQUENCE { - semiPersistSchedIntervalUL ENUMERATED { - sf10, sf20, sf32, sf40, sf64, sf80, - sf128, sf160, sf320, sf640, spare6, - spare5, spare4, spare3, spare2, - spare1}, - implicitReleaseAfter ENUMERATED {e2, e3, e4, e8}, - p0-Persistent SEQUENCE { - p0-NominalPUSCH-Persistent INTEGER (-126..24), - p0-UE-PUSCH-Persistent INTEGER (-8..7) - } OPTIONAL, -- Need OP - twoIntervalsConfig ENUMERATED {true} OPTIONAL, -- Cond TDD - ... - } -} - -N1-PUCCH-AN-PersistentList ::= SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047) - - -TDD-Config ::= SEQUENCE { - subframeAssignment ENUMERATED { - sa0, sa1, sa2, sa3, sa4, sa5, sa6}, - specialSubframePatterns ENUMERATED { - ssp0, ssp1, ssp2, ssp3, ssp4,ssp5, ssp6, ssp7, - ssp8} -} - - -TimeAlignmentTimer ::= ENUMERATED { - sf500, sf750, sf1280, sf1920, sf2560, sf5120, - sf10240, infinity} - -TPC-PDCCH-Config::= CHOICE { - release NULL, - setup SEQUENCE { - tpc-RNTI BIT STRING (SIZE (16)), - tpc-Index TPC-Index - } -} - -TPC-Index ::= CHOICE { - indexOfFormat3 INTEGER (1..15), - indexOfFormat3A INTEGER (1..31) -} - - -UplinkPowerControlCommon ::= SEQUENCE { - p0-NominalPUSCH INTEGER (-126..24), - alpha ENUMERATED {al0, al04, al05, al06, al07, al08, al09, al1}, - p0-NominalPUCCH INTEGER (-127..-96), - deltaFList-PUCCH DeltaFList-PUCCH, - deltaPreambleMsg3 INTEGER (-1..6) -} - -UplinkPowerControlDedicated ::= SEQUENCE { - p0-UE-PUSCH INTEGER (-8..7), - deltaMCS-Enabled ENUMERATED {en0, en1}, - accumulationEnabled BOOLEAN, - p0-UE-PUCCH INTEGER (-8..7), - pSRS-Offset INTEGER (0..15), - filterCoefficient FilterCoefficient DEFAULT fc4 -} - -DeltaFList-PUCCH ::= SEQUENCE { - deltaF-PUCCH-Format1 ENUMERATED {deltaF-2, deltaF0, deltaF2}, - deltaF-PUCCH-Format1b ENUMERATED {deltaF1, deltaF3, deltaF5}, - deltaF-PUCCH-Format2 ENUMERATED {deltaF-2, deltaF0, deltaF1, deltaF2}, - deltaF-PUCCH-Format2a ENUMERATED {deltaF-2, deltaF0, deltaF2}, - deltaF-PUCCH-Format2b ENUMERATED {deltaF-2, deltaF0, deltaF2} -} - - -NextHopChainingCount ::= INTEGER (0..7) - - -SecurityAlgorithmConfig ::= SEQUENCE { - cipheringAlgorithm ENUMERATED { - eea0, eea1, eea2, spare5, spare4, spare3, - spare2, spare1, ...}, - integrityProtAlgorithm ENUMERATED { - reserved, eia1, eia2, spare5, spare4, spare3, - spare2, spare1, ...} -} - - -ShortMAC-I ::= BIT STRING (SIZE (16)) - - -AdditionalSpectrumEmission ::= INTEGER (1..32) - - -ARFCN-ValueCDMA2000 ::= INTEGER (0..2047) - - -ARFCN-ValueEUTRA ::= INTEGER (0..maxEARFCN) - - -ARFCN-ValueGERAN ::= INTEGER (0..1023) - - -ARFCN-ValueUTRA ::= INTEGER (0..16383) - - -BandclassCDMA2000 ::= ENUMERATED { - bc0, bc1, bc2, bc3, bc4, bc5, bc6, bc7, bc8, - bc9, bc10, bc11, bc12, bc13, bc14, bc15, bc16, - bc17, spare14, spare13, spare12, spare11, spare10, - spare9, spare8, spare7, spare6, spare5, spare4, - spare3, spare2, spare1, ...} - - -BandIndicatorGERAN ::= ENUMERATED {dcs1800, pcs1900} - - -CarrierFreqCDMA2000 ::= SEQUENCE { - bandClass BandclassCDMA2000, - arfcn ARFCN-ValueCDMA2000 -} - - -CarrierFreqGERAN ::= SEQUENCE { - arfcn ARFCN-ValueGERAN, - bandIndicator BandIndicatorGERAN -} - - -CarrierFreqsGERAN ::= SEQUENCE { - startingARFCN ARFCN-ValueGERAN, - bandIndicator BandIndicatorGERAN, - followingARFCNs CHOICE { - explicitListOfARFCNs ExplicitListOfARFCNs, - equallySpacedARFCNs SEQUENCE { - arfcn-Spacing INTEGER (1..8), - numberOfFollowingARFCNs INTEGER (0..31) - }, - variableBitMapOfARFCNs OCTET STRING (SIZE (1..16)) - } -} - -ExplicitListOfARFCNs ::= SEQUENCE (SIZE (0..31)) OF ARFCN-ValueGERAN - - -CDMA2000-Type ::= ENUMERATED {type1XRTT, typeHRPD} - - -CellIdentity ::= BIT STRING (SIZE (28)) - - -CellIndexList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellIndex - -CellIndex ::= INTEGER (1..maxCellMeas) - - -CellReselectionPriority ::= INTEGER (0..7) - - -CSFB-RegistrationParam1XRTT ::= SEQUENCE { - sid BIT STRING (SIZE (15)), - nid BIT STRING (SIZE (16)), - multipleSID BOOLEAN, - multipleNID BOOLEAN, - homeReg BOOLEAN, - foreignSIDReg BOOLEAN, - foreignNIDReg BOOLEAN, - parameterReg BOOLEAN, - powerUpReg BOOLEAN, - registrationPeriod BIT STRING (SIZE (7)), - registrationZone BIT STRING (SIZE (12)), - totalZone BIT STRING (SIZE (3)), - zoneTimer BIT STRING (SIZE (3)) -} - - -CellGlobalIdEUTRA ::= SEQUENCE { - plmn-Identity PLMN-Identity, - cellIdentity CellIdentity -} - - -CellGlobalIdUTRA ::= SEQUENCE { - plmn-Identity PLMN-Identity, - cellIdentity BIT STRING (SIZE (28)) -} - - -CellGlobalIdGERAN ::= SEQUENCE { - plmn-Identity PLMN-Identity, - locationAreaCode BIT STRING (SIZE (16)), - cellIdentity BIT STRING (SIZE (16)) -} - - -CellGlobalIdCDMA2000 ::= CHOICE { - cellGlobalId1XRTT BIT STRING (SIZE (47)), - cellGlobalIdHRPD BIT STRING (SIZE (128)) -} - - -MobilityControlInfo ::= SEQUENCE { - targetPhysCellId PhysCellId, - carrierFreq CarrierFreqEUTRA OPTIONAL, -- Cond HO-toEUTRA - carrierBandwidth CarrierBandwidthEUTRA OPTIONAL, -- Cond HO-toEUTRA - additionalSpectrumEmission AdditionalSpectrumEmission OPTIONAL, -- Cond HO-toEUTRA - t304 ENUMERATED { - ms50, ms100, ms150, ms200, ms500, ms1000, - ms2000, spare1}, - newUE-Identity C-RNTI, - radioResourceConfigCommon RadioResourceConfigCommon, - rach-ConfigDedicated RACH-ConfigDedicated OPTIONAL, -- Need OP - ... -} - -CarrierBandwidthEUTRA ::= SEQUENCE { - dl-Bandwidth ENUMERATED { - n6, n15, n25, n50, n75, n100, spare10, - spare9, spare8, spare7, spare6, spare5, - spare4, spare3, spare2, spare1}, - ul-Bandwidth ENUMERATED { - n6, n15, n25, n50, n75, n100, spare10, - spare9, spare8, spare7, spare6, spare5, - spare4, spare3, spare2, spare1} OPTIONAL -- Need OP -} - -CarrierFreqEUTRA ::= SEQUENCE { - dl-CarrierFreq ARFCN-ValueEUTRA, - ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL -- Cond FDD -} - - -MobilityParametersCDMA2000 ::= OCTET STRING - - -MobilityStateParameters ::= SEQUENCE { - t-Evaluation ENUMERATED { - s30, s60, s120, s180, s240, spare3, spare2, spare1}, - t-HystNormal ENUMERATED { - s30, s60, s120, s180, s240, spare3, spare2, spare1}, - n-CellChangeMedium INTEGER (1..16), - n-CellChangeHigh INTEGER (1..16) -} - - -PhysCellId ::= INTEGER (0..503) - - -PhysCellIdRange ::= SEQUENCE { - start PhysCellId, - range ENUMERATED { - n4, n8, n12, n16, n24, n32, n48, n64, n84, - n96, n128, n168, n252, n504, spare2, - spare1} OPTIONAL -- Need OP -} - - -PhysCellIdCDMA2000 ::= INTEGER (0..maxPNOffset) - - -PhysCellIdGERAN ::= SEQUENCE { - networkColourCode BIT STRING (SIZE (3)), - baseStationColourCode BIT STRING (SIZE (3)) -} - - -PhysCellIdUTRA-FDD ::= INTEGER (0..511) - - -PhysCellIdUTRA-TDD ::= INTEGER (0..127) - - -PLMN-Identity ::= SEQUENCE { - mcc MCC OPTIONAL, -- Cond MCC - mnc MNC -} - -MCC ::= SEQUENCE (SIZE (3)) OF - MCC-MNC-Digit - -MNC ::= SEQUENCE (SIZE (2..3)) OF - MCC-MNC-Digit - -MCC-MNC-Digit ::= INTEGER (0..9) - - - -PreRegistrationInfoHRPD ::= SEQUENCE { - preRegistrationAllowed BOOLEAN, - preRegistrationZoneId PreRegistrationZoneIdHRPD OPTIONAL, -- cond PreRegAllowed - secondaryPreRegistrationZoneIdList SecondaryPreRegistrationZoneIdListHRPD OPTIONAL -- Need OR -} - -SecondaryPreRegistrationZoneIdListHRPD ::= SEQUENCE (SIZE (1..2)) OF PreRegistrationZoneIdHRPD - -PreRegistrationZoneIdHRPD ::= INTEGER (0..255) - - -Q-RxLevMin ::= INTEGER (-70..-22) - - -Q-OffsetRange ::= ENUMERATED { - dB-24, dB-22, dB-20, dB-18, dB-16, dB-14, - dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3, - dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5, - dB6, dB8, dB10, dB12, dB14, dB16, dB18, - dB20, dB22, dB24} - - -Q-OffsetRangeInterRAT ::= INTEGER (-15..15) - - -ReselectionThreshold ::= INTEGER (0..31) - - -SpeedStateScaleFactors ::= SEQUENCE { - sf-Medium ENUMERATED {oDot25, oDot5, oDot75, lDot0}, - sf-High ENUMERATED {oDot25, oDot5, oDot75, lDot0} -} - -SystemTimeInfoCDMA2000 ::= SEQUENCE { - cdma-EUTRA-Synchronisation BOOLEAN, - cdma-SystemTime CHOICE { - synchronousSystemTime BIT STRING (SIZE (39)), - asynchronousSystemTime BIT STRING (SIZE (49)) - } -} - - -TrackingAreaCode ::= BIT STRING (SIZE (16)) - - -T-Reselection ::= INTEGER (0..7) - - -AllowedMeasBandwidth ::= ENUMERATED {mbw6, mbw15, mbw25, mbw50, mbw75, mbw100} - - -Hysteresis ::= INTEGER (0..30) - - -MeasConfig ::= SEQUENCE { - -- Measurement objects - measObjectToRemoveList MeasObjectToRemoveList OPTIONAL, -- Need ON - measObjectToAddModList MeasObjectToAddModList OPTIONAL, -- Need ON - -- Reporting configurations - reportConfigToRemoveList ReportConfigToRemoveList OPTIONAL, -- Need ON - reportConfigToAddModList ReportConfigToAddModList OPTIONAL, -- Need ON - -- Measurement identities - measIdToRemoveList MeasIdToRemoveList OPTIONAL, -- Need ON - measIdToAddModList MeasIdToAddModList OPTIONAL, -- Need ON - -- Other parameters - quantityConfig QuantityConfig OPTIONAL, -- Need ON - measGapConfig MeasGapConfig OPTIONAL, -- Need ON - s-Measure RSRP-Range OPTIONAL, -- Need ON - preRegistrationInfoHRPD PreRegistrationInfoHRPD OPTIONAL, -- Need OP - speedStatePars CHOICE { - release NULL, - setup SEQUENCE { - mobilityStateParameters MobilityStateParameters, - timeToTrigger-SF SpeedStateScaleFactors - } - } OPTIONAL, -- Need ON - ... -} - -MeasIdToRemoveList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasId - -MeasObjectToRemoveList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectId - -ReportConfigToRemoveList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigId - - -MeasGapConfig ::= CHOICE { - release NULL, - setup SEQUENCE { - gapOffset CHOICE { - gp0 INTEGER (0..39), - gp1 INTEGER (0..79), - ... - } - } -} - - -MeasId ::= INTEGER (1..maxMeasId) - - -MeasIdToAddModList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddMod - -MeasIdToAddMod ::= SEQUENCE { - measId MeasId, - measObjectId MeasObjectId, - reportConfigId ReportConfigId -} - - -MeasObjectCDMA2000 ::= SEQUENCE { - cdma2000-Type CDMA2000-Type, - carrierFreq CarrierFreqCDMA2000, - searchWindowSize INTEGER (0..15) OPTIONAL, -- Need ON - offsetFreq Q-OffsetRangeInterRAT DEFAULT 0, - cellsToRemoveList CellIndexList OPTIONAL, -- Need ON - cellsToAddModList CellsToAddModListCDMA2000 OPTIONAL, -- Need ON - cellForWhichToReportCGI PhysCellIdCDMA2000 OPTIONAL, -- Need ON - ... -} - -CellsToAddModListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModCDMA2000 - -CellsToAddModCDMA2000 ::= SEQUENCE { - cellIndex INTEGER (1..maxCellMeas), - physCellId PhysCellIdCDMA2000 -} - - -MeasObjectEUTRA ::= SEQUENCE { - carrierFreq ARFCN-ValueEUTRA, - allowedMeasBandwidth AllowedMeasBandwidth, - presenceAntennaPort1 PresenceAntennaPort1, - neighCellConfig NeighCellConfig, - offsetFreq Q-OffsetRange DEFAULT dB0, - -- Neighbour cell list - cellsToRemoveList CellIndexList OPTIONAL, -- Need ON - cellsToAddModList CellsToAddModList OPTIONAL, -- Need ON - -- Black list - blackCellsToRemoveList CellIndexList OPTIONAL, -- Need ON - blackCellsToAddModList BlackCellsToAddModList OPTIONAL, -- Need ON - cellForWhichToReportCGI PhysCellId OPTIONAL, -- Need ON - ... -} - -CellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddMod - -CellsToAddMod ::= SEQUENCE { - cellIndex INTEGER (1..maxCellMeas), - physCellId PhysCellId, - cellIndividualOffset Q-OffsetRange -} - -BlackCellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF BlackCellsToAddMod - -BlackCellsToAddMod ::= SEQUENCE { - cellIndex INTEGER (1..maxCellMeas), - physCellIdRange PhysCellIdRange -} - - -MeasObjectGERAN ::= SEQUENCE { - carrierFreqs CarrierFreqsGERAN, - offsetFreq Q-OffsetRangeInterRAT DEFAULT 0, - ncc-Permitted BIT STRING(SIZE (8)) DEFAULT '11111111'B, - cellForWhichToReportCGI PhysCellIdGERAN OPTIONAL, -- Need ON - ... -} - - -MeasObjectId ::= INTEGER (1..maxObjectId) - - -MeasObjectToAddModList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectToAddMod - -MeasObjectToAddMod ::= SEQUENCE { - measObjectId MeasObjectId, - measObject CHOICE { - measObjectEUTRA MeasObjectEUTRA, - measObjectUTRA MeasObjectUTRA, - measObjectGERAN MeasObjectGERAN, - measObjectCDMA2000 MeasObjectCDMA2000, - ... - } -} - - -MeasObjectUTRA ::= SEQUENCE { - carrierFreq ARFCN-ValueUTRA, - offsetFreq Q-OffsetRangeInterRAT DEFAULT 0, - cellsToRemoveList CellIndexList OPTIONAL, -- Need ON - cellsToAddModList CHOICE { - cellsToAddModListUTRA-FDD CellsToAddModListUTRA-FDD, - cellsToAddModListUTRA-TDD CellsToAddModListUTRA-TDD - } OPTIONAL, -- Need ON - cellForWhichToReportCGI CHOICE { - utra-FDD PhysCellIdUTRA-FDD, - utra-TDD PhysCellIdUTRA-TDD - } OPTIONAL, -- Need ON - ... -} - -CellsToAddModListUTRA-FDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-FDD - -CellsToAddModUTRA-FDD ::= SEQUENCE { - cellIndex INTEGER (1..maxCellMeas), - physCellId PhysCellIdUTRA-FDD -} - -CellsToAddModListUTRA-TDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-TDD - -CellsToAddModUTRA-TDD ::= SEQUENCE { - cellIndex INTEGER (1..maxCellMeas), - physCellId PhysCellIdUTRA-TDD -} - - -MeasResults ::= SEQUENCE { - measId MeasId, - measResultServCell SEQUENCE { - rsrpResult RSRP-Range, - rsrqResult RSRQ-Range - }, - measResultNeighCells CHOICE { - measResultListEUTRA MeasResultListEUTRA, - measResultListUTRA MeasResultListUTRA, - measResultListGERAN MeasResultListGERAN, - measResultsCDMA2000 MeasResultsCDMA2000, - ... - } OPTIONAL, - ... -} - -MeasResultListEUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultEUTRA - -MeasResultEUTRA ::= SEQUENCE { - physCellId PhysCellId, - cgi-Info SEQUENCE { - cellGlobalId CellGlobalIdEUTRA, - trackingAreaCode TrackingAreaCode, - plmn-IdentityList PLMN-IdentityList2 OPTIONAL - } OPTIONAL, - measResult SEQUENCE { - rsrpResult RSRP-Range OPTIONAL, - rsrqResult RSRQ-Range OPTIONAL, - ... - } -} - -MeasResultListUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultUTRA - -MeasResultUTRA ::= SEQUENCE { - physCellId CHOICE { - fdd PhysCellIdUTRA-FDD, - tdd PhysCellIdUTRA-TDD - }, - cgi-Info SEQUENCE { - cellGlobalId CellGlobalIdUTRA, - locationAreaCode BIT STRING (SIZE (16)) OPTIONAL, - routingAreaCode BIT STRING (SIZE (8)) OPTIONAL, - plmn-IdentityList PLMN-IdentityList2 OPTIONAL - } OPTIONAL, - measResult SEQUENCE { - utra-RSCP INTEGER (-5..91) OPTIONAL, - utra-EcN0 INTEGER (0..49) OPTIONAL, - ... - } -} - -MeasResultListGERAN ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultGERAN - -MeasResultGERAN ::= SEQUENCE { - carrierFreq CarrierFreqGERAN, - physCellId PhysCellIdGERAN, - cgi-Info SEQUENCE { - cellGlobalId CellGlobalIdGERAN, - routingAreaCode BIT STRING (SIZE (8)) OPTIONAL - } OPTIONAL, - measResult SEQUENCE { - rssi INTEGER (0..63), - ... - } -} - -MeasResultsCDMA2000 ::= SEQUENCE { - preRegistrationStatusHRPD BOOLEAN, - measResultListCDMA2000 MeasResultListCDMA2000 -} - -MeasResultListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultCDMA2000 - -MeasResultCDMA2000 ::= SEQUENCE { - physCellId PhysCellIdCDMA2000, - cgi-Info CellGlobalIdCDMA2000 OPTIONAL, - measResult SEQUENCE { - pilotPnPhase INTEGER (0..32767) OPTIONAL, - pilotStrength INTEGER (0..63), - ... - } -} - -PLMN-IdentityList2 ::= SEQUENCE (SIZE (1..5)) OF PLMN-Identity - - -QuantityConfig ::= SEQUENCE { - quantityConfigEUTRA QuantityConfigEUTRA OPTIONAL, -- Need ON - quantityConfigUTRA QuantityConfigUTRA OPTIONAL, -- Need ON - quantityConfigGERAN QuantityConfigGERAN OPTIONAL, -- Need ON - quantityConfigCDMA2000 QuantityConfigCDMA2000 OPTIONAL, -- Need ON - ... -} - -QuantityConfigEUTRA ::= SEQUENCE { - filterCoefficientRSRP FilterCoefficient DEFAULT fc4, - filterCoefficientRSRQ FilterCoefficient DEFAULT fc4 -} - -QuantityConfigUTRA ::= SEQUENCE { - measQuantityUTRA-FDD ENUMERATED {cpich-RSCP, cpich-EcN0}, - measQuantityUTRA-TDD ENUMERATED {pccpch-RSCP}, - filterCoefficient FilterCoefficient DEFAULT fc4 -} - -QuantityConfigGERAN ::= SEQUENCE { - measQuantityGERAN ENUMERATED {rssi}, - filterCoefficient FilterCoefficient DEFAULT fc2 -} - -QuantityConfigCDMA2000 ::= SEQUENCE { - measQuantityCDMA2000 ENUMERATED {pilotStrength, pilotPnPhaseAndPilotStrength} -} - - -ReportConfigEUTRA ::= SEQUENCE { - triggerType CHOICE { - event SEQUENCE { - eventId CHOICE { - eventA1 SEQUENCE { - a1-Threshold ThresholdEUTRA - }, - eventA2 SEQUENCE { - a2-Threshold ThresholdEUTRA - }, - eventA3 SEQUENCE { - a3-Offset INTEGER (-30..30), - reportOnLeave BOOLEAN - }, - eventA4 SEQUENCE { - a4-Threshold ThresholdEUTRA - }, - eventA5 SEQUENCE { - a5-Threshold1 ThresholdEUTRA, - a5-Threshold2 ThresholdEUTRA - }, - ... - }, - hysteresis Hysteresis, - timeToTrigger TimeToTrigger - }, - periodical SEQUENCE { - purpose ENUMERATED { - reportStrongestCells, reportCGI} - } - }, - triggerQuantity ENUMERATED {rsrp, rsrq}, - reportQuantity ENUMERATED {sameAsTriggerQuantity, both}, - maxReportCells INTEGER (1..maxCellReport), - reportInterval ReportInterval, - reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, - ... -} - -ThresholdEUTRA ::= CHOICE{ - threshold-RSRP RSRP-Range, - threshold-RSRQ RSRQ-Range -} - - -ReportConfigId ::= INTEGER (1..maxReportConfigId) - - -ReportConfigInterRAT ::= SEQUENCE { - triggerType CHOICE { - event SEQUENCE { - eventId CHOICE { - eventB1 SEQUENCE { - b1-Threshold CHOICE { - b1-ThresholdUTRA ThresholdUTRA, - b1-ThresholdGERAN ThresholdGERAN, - b1-ThresholdCDMA2000 ThresholdCDMA2000 - } - }, - eventB2 SEQUENCE { - b2-Threshold1 ThresholdEUTRA, - b2-Threshold2 CHOICE { - b2-Threshold2UTRA ThresholdUTRA, - b2-Threshold2GERAN ThresholdGERAN, - b2-Threshold2CDMA2000 ThresholdCDMA2000 - } - }, - ... - }, - hysteresis Hysteresis, - timeToTrigger TimeToTrigger - }, - periodical SEQUENCE { - purpose ENUMERATED { - reportStrongestCells, - reportStrongestCellsForSON, - reportCGI} - } - }, - maxReportCells INTEGER (1..maxCellReport), - reportInterval ReportInterval, - reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, - ... -} - -ThresholdUTRA ::= CHOICE{ - utra-RSCP INTEGER (-5..91), - utra-EcN0 INTEGER (0..49) -} - -ThresholdGERAN ::= INTEGER (0..63) - -ThresholdCDMA2000 ::= INTEGER (0..63) - - -ReportConfigToAddModList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigToAddMod - -ReportConfigToAddMod ::= SEQUENCE { - reportConfigId ReportConfigId, - reportConfig CHOICE { - reportConfigEUTRA ReportConfigEUTRA, - reportConfigInterRAT ReportConfigInterRAT - } -} - - - -ReportInterval ::= ENUMERATED { - ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240, - min1, min6, min12, min30, min60, spare3, spare2, spare1} - - -RSRP-Range ::= INTEGER(0..97) - - -RSRQ-Range ::= INTEGER(0..34) - - -TimeToTrigger ::= ENUMERATED { - ms0, ms40, ms64, ms80, ms100, ms128, ms160, ms256, - ms320, ms480, ms512, ms640, ms1024, ms1280, ms2560, - ms5120} - - -C-RNTI ::= BIT STRING (SIZE (16)) - - -DedicatedInfoCDMA2000 ::= OCTET STRING - - -DedicatedInfoNAS ::= OCTET STRING - - -FilterCoefficient ::= ENUMERATED { - fc0, fc1, fc2, fc3, fc4, fc5, - fc6, fc7, fc8, fc9, fc11, fc13, - fc15, fc17, fc19, spare1, ...} - - -MMEC ::= BIT STRING (SIZE (8)) - - -NeighCellConfig ::= BIT STRING (SIZE (2)) - - -RAND-CDMA2000 ::= BIT STRING (SIZE (32)) - - -RAT-Type ::= ENUMERATED { - eutra, utra, geran-cs, geran-ps, cdma2000-1XRTT, - spare3, spare2, spare1, ...} - - -RRC-TransactionIdentifier ::= INTEGER (0..3) - - -S-TMSI ::= SEQUENCE { - mmec MMEC, - m-TMSI BIT STRING (SIZE (32)) -} - - -UE-CapabilityRAT-ContainerList ::=SEQUENCE (SIZE (0..maxRAT-Capabilities)) OF UE-CapabilityRAT-Container - -UE-CapabilityRAT-Container ::= SEQUENCE { - rat-Type RAT-Type, - ueCapabilityRAT-Container OCTET STRING -} - - -UE-EUTRA-Capability ::= SEQUENCE { - accessStratumRelease AccessStratumRelease, - ue-Category INTEGER (1..5), - pdcp-Parameters PDCP-Parameters, - phyLayerParameters PhyLayerParameters, - rf-Parameters RF-Parameters, - measParameters MeasParameters, - featureGroupIndicators BIT STRING (SIZE (32)) OPTIONAL, - interRAT-Parameters SEQUENCE { - utraFDD IRAT-ParametersUTRA-FDD OPTIONAL, - utraTDD128 IRAT-ParametersUTRA-TDD128 OPTIONAL, - utraTDD384 IRAT-ParametersUTRA-TDD384 OPTIONAL, - utraTDD768 IRAT-ParametersUTRA-TDD768 OPTIONAL, - geran IRAT-ParametersGERAN OPTIONAL, - cdma2000-HRPD IRAT-ParametersCDMA2000-HRPD OPTIONAL, - cdma2000-1xRTT IRAT-ParametersCDMA2000-1XRTT OPTIONAL - }, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - -AccessStratumRelease ::= ENUMERATED { - rel8, spare7, spare6, spare5, spare4, spare3, - spare2, spare1, ...} - -PDCP-Parameters ::= SEQUENCE { - supportedROHC-Profiles SEQUENCE { - profile0x0001 BOOLEAN, - profile0x0002 BOOLEAN, - profile0x0003 BOOLEAN, - profile0x0004 BOOLEAN, - profile0x0006 BOOLEAN, - profile0x0101 BOOLEAN, - profile0x0102 BOOLEAN, - profile0x0103 BOOLEAN, - profile0x0104 BOOLEAN - }, - maxNumberROHC-ContextSessions ENUMERATED { - cs2, cs4, cs8, cs12, cs16, cs24, cs32, - cs48, cs64, cs128, cs256, cs512, cs1024, - cs16384, spare2, spare1} DEFAULT cs16, - ... -} - -PhyLayerParameters ::= SEQUENCE { - ue-TxAntennaSelectionSupported BOOLEAN, - ue-SpecificRefSigsSupported BOOLEAN -} - -RF-Parameters ::= SEQUENCE { - supportedBandListEUTRA SupportedBandListEUTRA -} - -SupportedBandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA - -SupportedBandEUTRA ::= SEQUENCE { - bandEUTRA INTEGER (1..64), - halfDuplex BOOLEAN -} - -MeasParameters ::= SEQUENCE { - bandListEUTRA BandListEUTRA -} - -BandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF BandInfoEUTRA - -BandInfoEUTRA ::= SEQUENCE { - interFreqBandList InterFreqBandList, - interRAT-BandList InterRAT-BandList OPTIONAL -} - -InterFreqBandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterFreqBandInfo - -InterFreqBandInfo ::= SEQUENCE { - interFreqNeedForGaps BOOLEAN -} - -InterRAT-BandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterRAT-BandInfo - -InterRAT-BandInfo ::= SEQUENCE { - interRAT-NeedForGaps BOOLEAN -} - -IRAT-ParametersUTRA-FDD ::= SEQUENCE { - supportedBandListUTRA-FDD SupportedBandListUTRA-FDD -} - -SupportedBandListUTRA-FDD ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-FDD - -SupportedBandUTRA-FDD ::= ENUMERATED { - bandI, bandII, bandIII, bandIV, bandV, bandVI, - bandVII, bandVIII, bandIX, bandX, bandXI, - bandXII, bandXIII, bandXIV, bandXV, bandXVI, ...} - -IRAT-ParametersUTRA-TDD128 ::= SEQUENCE { - supportedBandListUTRA-TDD128 SupportedBandListUTRA-TDD128 -} - -SupportedBandListUTRA-TDD128 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD128 - -SupportedBandUTRA-TDD128 ::= ENUMERATED { - a, b, c, d, e, f, g, h, i, j, k, l, m, n, - o, p, ...} - -IRAT-ParametersUTRA-TDD384 ::= SEQUENCE { - supportedBandListUTRA-TDD384 SupportedBandListUTRA-TDD384 -} - -SupportedBandListUTRA-TDD384 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD384 - -SupportedBandUTRA-TDD384 ::= ENUMERATED { - a, b, c, d, e, f, g, h, i, j, k, l, m, n, - o, p, ...} - -IRAT-ParametersUTRA-TDD768 ::= SEQUENCE { - supportedBandListUTRA-TDD768 SupportedBandListUTRA-TDD768 -} - -SupportedBandListUTRA-TDD768 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD768 - -SupportedBandUTRA-TDD768 ::= ENUMERATED { - a, b, c, d, e, f, g, h, i, j, k, l, m, n, - o, p, ...} - -IRAT-ParametersGERAN ::= SEQUENCE { - supportedBandListGERAN SupportedBandListGERAN, - interRAT-PS-HO-ToGERAN BOOLEAN -} - -SupportedBandListGERAN ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandGERAN - -SupportedBandGERAN ::= ENUMERATED { - gsm450, gsm480, gsm710, gsm750, gsm810, gsm850, - gsm900P, gsm900E, gsm900R, gsm1800, gsm1900, - spare5, spare4, spare3, spare2, spare1, ...} - -IRAT-ParametersCDMA2000-HRPD ::= SEQUENCE { - supportedBandListHRPD SupportedBandListHRPD, - tx-ConfigHRPD ENUMERATED {single, dual}, - rx-ConfigHRPD ENUMERATED {single, dual} -} - -SupportedBandListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000 - -IRAT-ParametersCDMA2000-1XRTT ::= SEQUENCE { - supportedBandList1XRTT SupportedBandList1XRTT, - tx-Config1XRTT ENUMERATED {single, dual}, - rx-Config1XRTT ENUMERATED {single, dual} -} - -SupportedBandList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000 - - -UE-TimersAndConstants ::= SEQUENCE { - t300 ENUMERATED { - ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, - ms2000}, - t301 ENUMERATED { - ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, - ms2000}, - t310 ENUMERATED { - ms0, ms50, ms100, ms200, ms500, ms1000, ms2000}, - n310 ENUMERATED { - n1, n2, n3, n4, n6, n8, n10, n20}, - t311 ENUMERATED { - ms1000, ms3000, ms5000, ms10000, ms15000, - ms20000, ms30000}, - n311 ENUMERATED { - n1, n2, n3, n4, n5, n6, n8, n10}, - ... -} - - -maxBands INTEGER ::= 64 -- Maximum number of bands listed in EUTRA UE caps -maxCDMA-BandClass INTEGER ::= 32 -- Maximum value of the CDMA band classes -maxCellBlack INTEGER ::= 16 -- Maximum number of blacklisted cells - -- listed in SIB type 4 and 5 -maxCellInter INTEGER ::= 16 -- Maximum number of neighbouring inter-frequency - -- cells listed in SIB type 5 -maxCellIntra INTEGER ::= 16 -- Maximum number of neighbouring intra-frequency - -- cells listed in SIB type 4 -maxCellMeas INTEGER ::= 32 -- Maximum number of entries in each of the neighbour - -- cell lists in a measurement object -maxCellReport INTEGER ::= 8 -- Maximum number of reported cells -maxDRB INTEGER ::= 11 -- Maximum number of Data Radio Bearers -maxEARFCN INTEGER ::= 65535 -- Maximum value of EUTRA carrier fequency -maxFreq INTEGER ::= 8 -- Maximum number of EUTRA carrier frequencies -maxGERAN-SI INTEGER ::= 10 -- Maximum number of GERAN SI blocks that can be - -- provided as part of NACC information -maxGNFG INTEGER ::= 16 -- Maximum number of GERAN neighbour freq groups -maxMBSFN-Allocations INTEGER ::= 8 -- Maximum number of MBSFN frame allocations with - -- different offset -maxMCS-1 INTEGER ::= 16 -- Maximum number of PUCCH formats (MCS) -maxMeasId INTEGER ::= 32 -maxObjectId INTEGER ::= 32 -maxPageRec INTEGER ::= 16 -- -maxPNOffset INTEGER ::= 511 -- Maximum number of CDMA2000 PNOffsets -maxRAT-Capabilities INTEGER ::= 8 -- Maximum number of interworking RATs (incl EUTRA) -maxReportConfigId INTEGER ::= 32 -maxSIB INTEGER ::= 32 -- Maximum number of SIBs -maxSIB-1 INTEGER ::= 31 -maxSI-Message INTEGER ::= 32 -- Maximum number of SI messages -maxUTRA-FDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA FDD carrier frequencies -maxUTRA-TDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA TDD carrier frequencies - - -END +-- 3GPP TS 36.331 v9.2.0
+-- http://cdmweb.ericsson.se/TeamCenter/controller/ViewDocs?DocumentName=51%2F15519-10%2FFCP1039669%2F11&Revision=A
+
+EUTRA-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+
+BCCH-BCH-Message ::= SEQUENCE {
+ message BCCH-BCH-MessageType
+}
+
+BCCH-BCH-MessageType ::= MasterInformationBlock
+
+
+BCCH-DL-SCH-Message ::= SEQUENCE {
+ message BCCH-DL-SCH-MessageType
+}
+
+BCCH-DL-SCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ systemInformation SystemInformation,
+ systemInformationBlockType1 SystemInformationBlockType1
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+MCCH-Message ::= SEQUENCE {
+ message MCCH-MessageType
+}
+
+MCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ mbsfnAreaConfiguration-r9 MBSFNAreaConfiguration-r9
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+PCCH-Message ::= SEQUENCE {
+ message PCCH-MessageType
+}
+
+PCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ paging Paging
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+DL-CCCH-Message ::= SEQUENCE {
+ message DL-CCCH-MessageType
+}
+
+DL-CCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ rrcConnectionReestablishment RRCConnectionReestablishment,
+ rrcConnectionReestablishmentReject RRCConnectionReestablishmentReject,
+ rrcConnectionReject RRCConnectionReject,
+ rrcConnectionSetup RRCConnectionSetup
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+DL-DCCH-Message ::= SEQUENCE {
+ message DL-DCCH-MessageType
+}
+
+DL-DCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ csfbParametersResponseCDMA2000 CSFBParametersResponseCDMA2000,
+ dlInformationTransfer DLInformationTransfer,
+ handoverFromEUTRAPreparationRequest HandoverFromEUTRAPreparationRequest,
+ mobilityFromEUTRACommand MobilityFromEUTRACommand,
+ rrcConnectionReconfiguration RRCConnectionReconfiguration,
+ rrcConnectionRelease RRCConnectionRelease,
+ securityModeCommand SecurityModeCommand,
+ ueCapabilityEnquiry UECapabilityEnquiry,
+ counterCheck CounterCheck,
+ ueInformationRequest-r9 UEInformationRequest-r9,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+UL-CCCH-Message ::= SEQUENCE {
+ message UL-CCCH-MessageType
+}
+
+UL-CCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ rrcConnectionReestablishmentRequest RRCConnectionReestablishmentRequest,
+ rrcConnectionRequest RRCConnectionRequest
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+UL-DCCH-Message ::= SEQUENCE {
+ message UL-DCCH-MessageType
+}
+
+UL-DCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ csfbParametersRequestCDMA2000 CSFBParametersRequestCDMA2000,
+ measurementReport MeasurementReport,
+ rrcConnectionReconfigurationComplete RRCConnectionReconfigurationComplete,
+ rrcConnectionReestablishmentComplete RRCConnectionReestablishmentComplete,
+ rrcConnectionSetupComplete RRCConnectionSetupComplete,
+ securityModeComplete SecurityModeComplete,
+ securityModeFailure SecurityModeFailure,
+ ueCapabilityInformation UECapabilityInformation,
+ulHandoverPreparationTransfer ULHandoverPreparationTransfer,
+ ulInformationTransfer ULInformationTransfer,
+ counterCheckResponse CounterCheckResponse,
+ ueInformationResponse-r9 UEInformationResponse-r9,
+ proximityIndication-r9 ProximityIndication-r9,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+CounterCheck ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ counterCheck-r8 CounterCheck-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CounterCheck-r8-IEs ::= SEQUENCE {
+ drb-CountMSB-InfoList DRB-CountMSB-InfoList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+DRB-CountMSB-InfoList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-CountMSB-Info
+
+DRB-CountMSB-Info ::= SEQUENCE {
+ drb-Identity DRB-Identity,
+ countMSB-Uplink INTEGER(0..33554431),
+ countMSB-Downlink INTEGER(0..33554431)
+}
+
+
+CounterCheckResponse ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ counterCheckResponse-r8 CounterCheckResponse-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CounterCheckResponse-r8-IEs ::= SEQUENCE {
+ drb-CountInfoList DRB-CountInfoList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+DRB-CountInfoList ::= SEQUENCE (SIZE (0..maxDRB)) OF DRB-CountInfo
+
+DRB-CountInfo ::= SEQUENCE {
+ drb-Identity DRB-Identity,
+ count-Uplink INTEGER(0..4294967295),
+ count-Downlink INTEGER(0..4294967295)
+}
+
+
+CSFBParametersRequestCDMA2000 ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ csfbParametersRequestCDMA2000-r8 CSFBParametersRequestCDMA2000-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CSFBParametersRequestCDMA2000-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+CSFBParametersResponseCDMA2000 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ csfbParametersResponseCDMA2000-r8 CSFBParametersResponseCDMA2000-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CSFBParametersResponseCDMA2000-r8-IEs ::= SEQUENCE {
+ rand RAND-CDMA2000,
+ mobilityParameters MobilityParametersCDMA2000,
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+
+DLInformationTransfer ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ dlInformationTransfer-r8 DLInformationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+DLInformationTransfer-r8-IEs ::= SEQUENCE {
+ dedicatedInfoType CHOICE {
+ dedicatedInfoNAS DedicatedInfoNAS,
+ dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000,
+ dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+
+HandoverFromEUTRAPreparationRequest ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ handoverFromEUTRAPreparationRequest-r8
+ HandoverFromEUTRAPreparationRequest-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+HandoverFromEUTRAPreparationRequest-r8-IEs ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ rand RAND-CDMA2000 OPTIONAL, -- Cond cdma2000-Type
+ mobilityParameters MobilityParametersCDMA2000 OPTIONAL, -- Cond cdma2000-Type
+ nonCriticalExtension HandoverFromEUTRAPreparationRequest-v890-IEs OPTIONAL
+}
+
+HandoverFromEUTRAPreparationRequest-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension HandoverFromEUTRAPreparationRequest-v920-IEs OPTIONAL
+}
+
+HandoverFromEUTRAPreparationRequest-v920-IEs ::= SEQUENCE {
+ concurrPrepCDMA2000-HRPD-r9 BOOLEAN OPTIONAL, -- Cond PSHO
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+MasterInformationBlock ::= SEQUENCE {
+ dl-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100},
+ phich-Config PHICH-Config,
+ systemFrameNumber BIT STRING (SIZE (8)),
+ spare BIT STRING (SIZE (10))
+}
+
+
+
+MBSFNAreaConfiguration-r9 ::= SEQUENCE {
+ commonSF-Alloc-r9 CommonSF-AllocPatternList-r9,
+ commonSF-AllocPeriod-r9 ENUMERATED {
+ rf4, rf8, rf16, rf32, rf64, rf128, rf256},
+ pmch-InfoList-r9 PMCH-InfoList-r9,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+CommonSF-AllocPatternList-r9 ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig
+
+
+MeasurementReport ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ measurementReport-r8 MeasurementReport-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+MeasurementReport-r8-IEs ::= SEQUENCE {
+ measResults MeasResults,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+MobilityFromEUTRACommand ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ mobilityFromEUTRACommand-r8 MobilityFromEUTRACommand-r8-IEs,
+ mobilityFromEUTRACommand-r9 MobilityFromEUTRACommand-r9-IEs,
+ spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+MobilityFromEUTRACommand-r8-IEs ::= SEQUENCE {
+ cs-FallbackIndicator BOOLEAN,
+ purpose CHOICE{
+ handover Handover,
+ cellChangeOrder CellChangeOrder
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+MobilityFromEUTRACommand-r9-IEs ::= SEQUENCE {
+ cs-FallbackIndicator BOOLEAN,
+ purpose CHOICE{
+ handover Handover,
+ cellChangeOrder CellChangeOrder,
+ e-CSFB-r9 E-CSFB-r9,
+ ...
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+Handover ::= SEQUENCE {
+ targetRAT-Type ENUMERATED {
+ utra, geran, cdma2000-1XRTT, cdma2000-HRPD,
+ spare4, spare3, spare2, spare1, ...},
+ targetRAT-MessageContainer OCTET STRING,
+ nas-SecurityParamFromEUTRA OCTET STRING (SIZE (1)) OPTIONAL, -- Cond UTRAGERAN
+ systemInformation SI-OrPSI-GERAN OPTIONAL -- Cond PSHO
+}
+
+CellChangeOrder ::= SEQUENCE {
+ t304 ENUMERATED {
+ ms100, ms200, ms500, ms1000,
+ ms2000, ms4000, ms8000, spare1},
+ targetRAT-Type CHOICE {
+ geran SEQUENCE {
+ physCellId PhysCellIdGERAN,
+ carrierFreq CarrierFreqGERAN,
+ networkControlOrder BIT STRING (SIZE (2)) OPTIONAL, -- Need OP
+ systemInformation SI-OrPSI-GERAN OPTIONAL -- Need OP
+ },
+ ...
+ }
+}
+
+SI-OrPSI-GERAN ::= CHOICE {
+ si SystemInfoListGERAN,
+ psi SystemInfoListGERAN
+}
+
+E-CSFB-r9 ::= SEQUENCE {
+ messageContCDMA2000-1XRTT-r9 OCTET STRING OPTIONAL, -- Need ON
+ mobilityCDMA2000-HRPD-r9 ENUMERATED {
+ handover, redirection
+ } OPTIONAL, -- Need OP
+ messageContCDMA2000-HRPD-r9 OCTET STRING OPTIONAL, -- Cond concHO
+ redirectCarrierCDMA2000-HRPD-r9 CarrierFreqCDMA2000 OPTIONAL -- Cond concRedir
+}
+
+
+Paging ::= SEQUENCE {
+ pagingRecordList PagingRecordList OPTIONAL, -- Need ON
+ systemInfoModification ENUMERATED {true} OPTIONAL, -- Need ON
+ etws-Indication ENUMERATED {true} OPTIONAL, -- Need ON
+ nonCriticalExtension Paging-v890-IEs OPTIONAL
+}
+
+Paging-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension Paging-v920-IEs OPTIONAL
+}
+
+Paging-v920-IEs ::= SEQUENCE {
+ cmas-Indication-r9 ENUMERATED {true} OPTIONAL, -- Need ON
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+PagingRecordList ::= SEQUENCE (SIZE (1..maxPageRec)) OF PagingRecord
+
+PagingRecord ::= SEQUENCE {
+ ue-Identity PagingUE-Identity,
+ cn-Domain ENUMERATED {ps, cs},
+ ...
+}
+
+PagingUE-Identity ::= CHOICE {
+ s-TMSI S-TMSI,
+ imsi IMSI,
+ ...
+}
+
+IMSI ::= SEQUENCE (SIZE (6..21)) OF IMSI-Digit
+
+IMSI-Digit ::= INTEGER (0..9)
+
+
+ProximityIndication-r9 ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ proximityIndication-r9 ProximityIndication-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ProximityIndication-r9-IEs ::= SEQUENCE {
+ type-r9 ENUMERATED {entering, leaving},
+ carrierFreq-r9 CHOICE {
+ eutra-r9 ARFCN-ValueEUTRA,
+ utra-r9 ARFCN-ValueUTRA,
+ ...
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReconfiguration ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionReconfiguration-r8 RRCConnectionReconfiguration-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReconfiguration-r8-IEs ::= SEQUENCE {
+ measConfig MeasConfig OPTIONAL, -- Need ON
+ mobilityControlInfo MobilityControlInfo OPTIONAL, -- Cond HO
+ dedicatedInfoNASList SEQUENCE (SIZE(1..maxDRB)) OF
+ DedicatedInfoNAS OPTIONAL, -- Cond nonHO
+ radioResourceConfigDedicated RadioResourceConfigDedicated OPTIONAL, -- Cond HO-toEUTRA
+ securityConfigHO SecurityConfigHO OPTIONAL, -- Cond HO
+ nonCriticalExtension RRCConnectionReconfiguration-v890-IEs OPTIONAL
+}
+
+RRCConnectionReconfiguration-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionReconfiguration-v920-IEs OPTIONAL
+}
+
+RRCConnectionReconfiguration-v920-IEs ::= SEQUENCE {
+ otherConfig-r9 OtherConfig-r9 OPTIONAL, -- Need ON
+ fullConfig-r9 ENUMERATED {true} OPTIONAL, -- Cond HO-Reestab
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+SecurityConfigHO ::= SEQUENCE {
+ handoverType CHOICE {
+ intraLTE SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig OPTIONAL, -- Cond fullConfig
+ keyChangeIndicator BOOLEAN,
+ nextHopChainingCount NextHopChainingCount
+ },
+ interRAT SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig,
+ nas-SecurityParamToEUTRA OCTET STRING (SIZE(6))
+ }
+ },
+ ...
+}
+
+
+
+RRCConnectionReconfigurationComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ rrcConnectionReconfigurationComplete-r8
+ RRCConnectionReconfigurationComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReconfigurationComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReestablishment ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionReestablishment-r8 RRCConnectionReestablishment-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishment-r8-IEs ::= SEQUENCE {
+ radioResourceConfigDedicated RadioResourceConfigDedicated,
+ nextHopChainingCount NextHopChainingCount,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionReestablishmentComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentComplete-r8
+ RRCConnectionReestablishmentComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension RRCConnectionReestablishmentComplete-v920-IEs OPTIONAL
+}
+
+RRCConnectionReestablishmentComplete-v920-IEs ::= SEQUENCE {
+ rlf-InfoAvailable-r9 ENUMERATED {true} OPTIONAL,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReestablishmentReject ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentReject-r8
+ RRCConnectionReestablishmentReject-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentReject-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionReestablishmentRequest ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentRequest-r8
+ RRCConnectionReestablishmentRequest-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentRequest-r8-IEs ::= SEQUENCE {
+ ue-Identity ReestabUE-Identity,
+ reestablishmentCause ReestablishmentCause,
+ spare BIT STRING (SIZE (2))
+}
+
+ReestabUE-Identity ::= SEQUENCE {
+ c-RNTI C-RNTI,
+ physCellId PhysCellId,
+ shortMAC-I ShortMAC-I
+}
+
+ReestablishmentCause ::= ENUMERATED {
+ reconfigurationFailure, handoverFailure,
+ otherFailure, spare1}
+
+
+RRCConnectionReject ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionReject-r8 RRCConnectionReject-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReject-r8-IEs ::= SEQUENCE {
+ waitTime INTEGER (1..16),
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionRelease ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionRelease-r8 RRCConnectionRelease-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionRelease-r8-IEs ::= SEQUENCE {
+ releaseCause ReleaseCause,
+ redirectedCarrierInfo RedirectedCarrierInfo OPTIONAL, -- Need ON
+ idleModeMobilityControlInfo IdleModeMobilityControlInfo OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionRelease-v890-IEs OPTIONAL
+}
+
+RRCConnectionRelease-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionRelease-v920-IEs OPTIONAL
+}
+
+RRCConnectionRelease-v920-IEs ::= SEQUENCE {
+ cellInfoList-r9 CHOICE {
+ geran-r9 CellInfoListGERAN-r9,
+ utra-FDD-r9 CellInfoListUTRA-FDD-r9,
+ utra-TDD-r9 CellInfoListUTRA-TDD-r9,
+ ...
+ } OPTIONAL, -- Cond Redirection
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+ReleaseCause ::= ENUMERATED {loadBalancingTAUrequired,
+ other,spare2,spare1}
+
+RedirectedCarrierInfo ::= CHOICE {
+ eutra ARFCN-ValueEUTRA,
+ geran CarrierFreqsGERAN,
+ utra-FDD ARFCN-ValueUTRA,
+ utra-TDD ARFCN-ValueUTRA,
+ cdma2000-HRPD CarrierFreqCDMA2000,
+ cdma2000-1xRTT CarrierFreqCDMA2000,
+ ...
+}
+
+IdleModeMobilityControlInfo ::= SEQUENCE {
+ freqPriorityListEUTRA FreqPriorityListEUTRA OPTIONAL, -- Need ON
+ freqPriorityListGERAN FreqsPriorityListGERAN OPTIONAL, -- Need ON
+ freqPriorityListUTRA-FDD FreqPriorityListUTRA-FDD OPTIONAL, -- Need ON
+ freqPriorityListUTRA-TDD FreqPriorityListUTRA-TDD OPTIONAL, -- Need ON
+ bandClassPriorityListHRPD BandClassPriorityListHRPD OPTIONAL, -- Need ON
+ bandClassPriorityList1XRTT BandClassPriorityList1XRTT OPTIONAL, -- Need ON
+ t320 ENUMERATED {
+ min5, min10, min20, min30, min60, min120, min180,
+ spare1} OPTIONAL, -- Need OR
+ ...
+}
+
+FreqPriorityListEUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA
+
+FreqPriorityEUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqsPriorityListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF FreqsPriorityGERAN
+
+FreqsPriorityGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqPriorityListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF FreqPriorityUTRA-FDD
+
+FreqPriorityUTRA-FDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqPriorityListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF FreqPriorityUTRA-TDD
+
+FreqPriorityUTRA-TDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+BandClassPriorityListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriorityHRPD
+
+BandClassPriorityHRPD ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority
+}
+
+BandClassPriorityList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriority1XRTT
+
+BandClassPriority1XRTT ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority
+}
+
+CellInfoListGERAN-r9 ::= SEQUENCE (SIZE (1..maxCellInfo-GERAN-r9 )) OF CellInfoGERAN-r9
+
+CellInfoGERAN-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdGERAN,
+ carrierFreq-r9 CarrierFreqGERAN,
+ systemInformation-r9 SystemInfoListGERAN
+}
+
+CellInfoListUTRA-FDD-r9 ::= SEQUENCE (SIZE (1..maxUTRA-CellInfo-r9)) OF CellInfoUTRA-FDD-r9
+
+CellInfoUTRA-FDD-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdUTRA-FDD,
+ utra-BCCH-Container-r9 OCTET STRING
+}
+
+CellInfoListUTRA-TDD-r9 ::= SEQUENCE (SIZE (1..maxUTRA-CellInfo-r9)) OF CellInfoUTRA-TDD-r9
+
+CellInfoUTRA-TDD-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdUTRA-TDD,
+ utra-BCCH-Container-r9 OCTET STRING
+}
+
+
+RRCConnectionRequest ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionRequest-r8 RRCConnectionRequest-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionRequest-r8-IEs ::= SEQUENCE {
+ ue-Identity InitialUE-Identity,
+ establishmentCause EstablishmentCause,
+ spare BIT STRING (SIZE (1))
+}
+
+InitialUE-Identity ::= CHOICE {
+ s-TMSI S-TMSI,
+ randomValue BIT STRING (SIZE (40))
+}
+
+EstablishmentCause ::= ENUMERATED {
+ emergency, highPriorityAccess, mt-Access, mo-Signalling,
+ mo-Data, spare3, spare2, spare1}
+
+
+RRCConnectionSetup ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionSetup-r8 RRCConnectionSetup-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionSetup-r8-IEs ::= SEQUENCE {
+ radioResourceConfigDedicated RadioResourceConfigDedicated,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionSetupComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionSetupComplete-r8 RRCConnectionSetupComplete-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionSetupComplete-r8-IEs ::= SEQUENCE {
+ selectedPLMN-Identity INTEGER (1..6),
+ registeredMME RegisteredMME OPTIONAL,
+ dedicatedInfoNAS DedicatedInfoNAS,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+RegisteredMME ::= SEQUENCE {
+ plmn-Identity PLMN-Identity OPTIONAL,
+ mmegi BIT STRING (SIZE (16)),
+ mmec MMEC
+}
+
+
+SecurityModeCommand ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ securityModeCommand-r8 SecurityModeCommand-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeCommand-r8-IEs ::= SEQUENCE {
+ securityConfigSMC SecurityConfigSMC,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+SecurityConfigSMC ::= SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig,
+ ...
+}
+
+
+SecurityModeComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ securityModeComplete-r8 SecurityModeComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SecurityModeFailure ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ securityModeFailure-r8 SecurityModeFailure-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeFailure-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SystemInformation ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ systemInformation-r8 SystemInformation-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+SystemInformation-r8-IEs ::= SEQUENCE {
+ sib-TypeAndInfo SEQUENCE (SIZE (1..maxSIB)) OF CHOICE {
+ sib2 SystemInformationBlockType2,
+ sib3 SystemInformationBlockType3,
+ sib4 SystemInformationBlockType4,
+ sib5 SystemInformationBlockType5,
+ sib6 SystemInformationBlockType6,
+ sib7 SystemInformationBlockType7,
+ sib8 SystemInformationBlockType8,
+ sib9 SystemInformationBlockType9,
+ sib10 SystemInformationBlockType10,
+ sib11 SystemInformationBlockType11,
+ ...,
+ sib12-v920 SystemInformationBlockType12-r9,
+ sib13-v920 SystemInformationBlockType13-r9
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+SystemInformationBlockType1 ::= SEQUENCE {
+ cellAccessRelatedInfo SEQUENCE {
+ plmn-IdentityList PLMN-IdentityList,
+ trackingAreaCode TrackingAreaCode,
+ cellIdentity CellIdentity,
+ cellBarred ENUMERATED {barred, notBarred},
+ intraFreqReselection ENUMERATED {allowed, notAllowed},
+ csg-Indication BOOLEAN,
+ csg-Identity CSG-Identity OPTIONAL -- Need OR
+ },
+ cellSelectionInfo SEQUENCE {
+ q-RxLevMin Q-RxLevMin,
+ q-RxLevMinOffset INTEGER (1..8) OPTIONAL -- Need OP
+ },
+ p-Max P-Max OPTIONAL, -- Need OP
+ freqBandIndicator INTEGER (1..64),
+ schedulingInfoList SchedulingInfoList,
+ tdd-Config TDD-Config OPTIONAL, -- Cond TDD
+ si-WindowLength ENUMERATED {
+ ms1, ms2, ms5, ms10, ms15, ms20,
+ ms40},
+ systemInfoValueTag INTEGER (0..31),
+ nonCriticalExtension SystemInformationBlockType1-v890-IEs OPTIONAL
+}
+
+SystemInformationBlockType1-v890-IEs::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension SystemInformationBlockType1-v920-IEs OPTIONAL
+}
+
+SystemInformationBlockType1-v920-IEs ::= SEQUENCE {
+ ims-EmergencySupport-r9 ENUMERATED {true} OPTIONAL, -- Need OR
+ cellSelectionInfo-v920 CellSelectionInfo-v920 OPTIONAL, -- Need OP
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+PLMN-IdentityList ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo
+
+PLMN-IdentityInfo ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellReservedForOperatorUse ENUMERATED {reserved, notReserved}
+}
+
+SchedulingInfoList ::= SEQUENCE (SIZE (1..maxSI-Message)) OF SchedulingInfo
+
+SchedulingInfo ::= SEQUENCE {
+ si-Periodicity ENUMERATED {
+ rf8, rf16, rf32, rf64, rf128, rf256, rf512},
+ sib-MappingInfo SIB-MappingInfo
+}
+
+SIB-MappingInfo ::= SEQUENCE (SIZE (0..maxSIB-1)) OF SIB-Type
+
+SIB-Type ::= ENUMERATED {
+ sibType3, sibType4, sibType5, sibType6,
+ sibType7, sibType8, sibType9, sibType10,
+ sibType11, sibType12-v920, sibType13-v920, spare5,
+ spare4, spare3, spare2, spare1, ...}
+
+CellSelectionInfo-v920 ::= SEQUENCE {
+ q-QualMin-r9 Q-QualMin-r9,
+ q-QualMinOffset-r9 INTEGER (1..8) OPTIONAL -- Need OP
+}
+
+
+UECapabilityEnquiry ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueCapabilityEnquiry-r8 UECapabilityEnquiry-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UECapabilityEnquiry-r8-IEs ::= SEQUENCE {
+ ue-CapabilityRequest UE-CapabilityRequest,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+UE-CapabilityRequest ::= SEQUENCE (SIZE (1..maxRAT-Capabilities)) OF RAT-Type
+
+
+UECapabilityInformation ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ ueCapabilityInformation-r8 UECapabilityInformation-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UECapabilityInformation-r8-IEs ::= SEQUENCE {
+ ue-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+UEInformationRequest-r9 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueInformationRequest-r9 UEInformationRequest-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UEInformationRequest-r9-IEs ::= SEQUENCE {
+ rach-ReportReq-r9 BOOLEAN,
+ rlf-ReportReq-r9 BOOLEAN,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+UEInformationResponse-r9 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueInformationResponse-r9 UEInformationResponse-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UEInformationResponse-r9-IEs ::= SEQUENCE {
+ rach-Report-r9 SEQUENCE {
+ numberOfPreamblesSent-r9 INTEGER (1..200),
+ contentionDetected-r9 BOOLEAN
+ } OPTIONAL,
+ rlfReport-r9 RLF-Report-r9 OPTIONAL,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+RLF-Report-r9 ::= SEQUENCE {
+ measResultLastServCell SEQUENCE {
+ rsrpResult RSRP-Range,
+ rsrqResult RSRQ-Range OPTIONAL
+ },
+ measResultNeighCells SEQUENCE {
+ measResultListEUTRA MeasResultList2EUTRA OPTIONAL,
+ measResultListUTRA MeasResultList2UTRA OPTIONAL,
+ measResultListGERAN MeasResultListGERAN OPTIONAL,
+ measResultsCDMA2000 MeasResultList2CDMA2000 OPTIONAL
+ } OPTIONAL,
+ ...
+}
+
+MeasResultList2EUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ measResultList MeasResultListEUTRA
+}
+
+MeasResultList2UTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ measResultList MeasResultListUTRA
+}
+
+MeasResultList2CDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF SEQUENCE {
+ carrierFreq CarrierFreqCDMA2000,
+ measResultList MeasResultsCDMA2000
+}
+
+
+ULHandoverPreparationTransfer ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ulHandoverPreparationTransfer-r8 ULHandoverPreparationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ meid BIT STRING (SIZE (56)) OPTIONAL,
+ dedicatedInfo DedicatedInfoCDMA2000,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+ULInformationTransfer ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ulInformationTransfer-r8 ULInformationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ULInformationTransfer-r8-IEs ::= SEQUENCE {
+ dedicatedInfoType CHOICE {
+ dedicatedInfoNAS DedicatedInfoNAS,
+ dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000,
+ dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SystemInformationBlockType2 ::= SEQUENCE {
+ ac-BarringInfo SEQUENCE {
+ ac-BarringForEmergency BOOLEAN,
+ ac-BarringForMO-Signalling AC-BarringConfig OPTIONAL, -- Need OP
+ ac-BarringForMO-Data AC-BarringConfig OPTIONAL -- Need OP
+ } OPTIONAL, -- Need OP
+ radioResourceConfigCommon RadioResourceConfigCommonSIB,
+ ue-TimersAndConstants UE-TimersAndConstants,
+ freqInfo SEQUENCE {
+ ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL, -- Need OP
+ ul-Bandwidth ENUMERATED {n6, n15, n25, n50, n75, n100}
+ OPTIONAL, -- Need OP
+ additionalSpectrumEmission AdditionalSpectrumEmission
+ },
+ mbsfn-SubframeConfigList MBSFN-SubframeConfigList OPTIONAL, -- Need OR
+ timeAlignmentTimerCommon TimeAlignmentTimer,
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ ssac-BarringForMMTEL-Voice-r9 AC-BarringConfig OPTIONAL, -- Need OP
+ ssac-BarringForMMTEL-Video-r9 AC-BarringConfig OPTIONAL -- Need OP
+ ]]
+}
+
+AC-BarringConfig ::= SEQUENCE {
+ ac-BarringFactor ENUMERATED {
+ p00, p05, p10, p15, p20, p25, p30, p40,
+ p50, p60, p70, p75, p80, p85, p90, p95},
+ ac-BarringTime ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512},
+ ac-BarringForSpecialAC BIT STRING (SIZE(5))
+}
+
+MBSFN-SubframeConfigList ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig
+
+
+SystemInformationBlockType3 ::= SEQUENCE {
+ cellReselectionInfoCommon SEQUENCE {
+ q-Hyst ENUMERATED {
+ dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10,
+ dB12, dB14, dB16, dB18, dB20, dB22, dB24},
+ speedStateReselectionPars SEQUENCE {
+ mobilityStateParameters MobilityStateParameters,
+ q-HystSF SEQUENCE {
+ sf-Medium ENUMERATED {
+ dB-6, dB-4, dB-2, dB0},
+ sf-High ENUMERATED {
+ dB-6, dB-4, dB-2, dB0}
+ }
+ } OPTIONAL -- Need OP
+ },
+ cellReselectionServingFreqInfo SEQUENCE {
+ s-NonIntraSearch ReselectionThreshold OPTIONAL, -- Need OP
+ threshServingLow ReselectionThreshold,
+ cellReselectionPriority CellReselectionPriority
+ },
+ intraFreqCellReselectionInfo SEQUENCE {
+ q-RxLevMin Q-RxLevMin,
+ p-Max P-Max OPTIONAL, -- Need OP
+ s-IntraSearch ReselectionThreshold OPTIONAL, -- Need OP
+ allowedMeasBandwidth AllowedMeasBandwidth OPTIONAL, -- Need OP
+ presenceAntennaPort1 PresenceAntennaPort1,
+ neighCellConfig NeighCellConfig,
+ t-ReselectionEUTRA T-Reselection,
+ t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL -- Need OP
+ },
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ s-IntraSearch-v920 SEQUENCE {
+ s-IntraSearchP-r9 ReselectionThreshold,
+ s-IntraSearchQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL, -- Need OP
+ s-NonIntraSearch-v920 SEQUENCE {
+ s-NonIntraSearchP-r9 ReselectionThreshold,
+ s-NonIntraSearchQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL, -- Need OP
+ q-QualMin-r9 Q-QualMin-r9 OPTIONAL, -- Need OP
+ threshServingLowQ-r9 ReselectionThresholdQ-r9 OPTIONAL -- Need OP
+ ]]
+}
+
+
+SystemInformationBlockType4 ::= SEQUENCE {
+ intraFreqNeighCellList IntraFreqNeighCellList OPTIONAL, -- Need OR
+ intraFreqBlackCellList IntraFreqBlackCellList OPTIONAL, -- Need OR
+ csg-PhysCellIdRange PhysCellIdRange OPTIONAL, -- Cond CSG
+ ...
+}
+
+IntraFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellIntra)) OF IntraFreqNeighCellInfo
+
+IntraFreqNeighCellInfo ::= SEQUENCE {
+ physCellId PhysCellId,
+ q-OffsetCell Q-OffsetRange,
+ ...
+}
+
+IntraFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange
+
+
+SystemInformationBlockType5 ::= SEQUENCE {
+ interFreqCarrierFreqList InterFreqCarrierFreqList,
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL -- Need OP
+}
+
+InterFreqCarrierFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo
+
+InterFreqCarrierFreqInfo ::= SEQUENCE {
+ dl-CarrierFreq ARFCN-ValueEUTRA,
+ q-RxLevMin Q-RxLevMin,
+ p-Max P-Max OPTIONAL, -- Need OP
+ t-ReselectionEUTRA T-Reselection,
+ t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ allowedMeasBandwidth AllowedMeasBandwidth,
+ presenceAntennaPort1 PresenceAntennaPort1,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ neighCellConfig NeighCellConfig,
+ q-OffsetFreq Q-OffsetRange DEFAULT dB0,
+ interFreqNeighCellList InterFreqNeighCellList OPTIONAL, -- Need OR
+ interFreqBlackCellList InterFreqBlackCellList OPTIONAL, -- Need OR
+ ...,
+ [[ q-QualMin-r9 Q-QualMin-r9 OPTIONAL, -- Need OP
+ threshX-Q-r9 SEQUENCE {
+ threshX-HighQ-r9 ReselectionThresholdQ-r9,
+ threshX-LowQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL -- Cond RSRQ
+ ]]
+}
+
+InterFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellInter)) OF InterFreqNeighCellInfo
+
+InterFreqNeighCellInfo ::= SEQUENCE {
+ physCellId PhysCellId,
+ q-OffsetCell Q-OffsetRange
+}
+
+InterFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange
+
+
+SystemInformationBlockType6 ::= SEQUENCE {
+ carrierFreqListUTRA-FDD CarrierFreqListUTRA-FDD OPTIONAL, -- Need OR
+ carrierFreqListUTRA-TDD CarrierFreqListUTRA-TDD OPTIONAL, -- Need OR
+ t-ReselectionUTRA T-Reselection,
+ t-ReselectionUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL -- Need OP
+}
+
+CarrierFreqListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF CarrierFreqUTRA-FDD
+
+CarrierFreqUTRA-FDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ q-RxLevMin INTEGER (-60..-13),
+ p-MaxUTRA INTEGER (-50..33),
+ q-QualMin INTEGER (-24..0),
+ ...,
+ [[ threshX-Q-r9 SEQUENCE {
+ threshX-HighQ-r9 ReselectionThresholdQ-r9,
+ threshX-LowQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL -- Cond RSRQ
+ ]]
+}
+
+CarrierFreqListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF CarrierFreqUTRA-TDD
+
+CarrierFreqUTRA-TDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ q-RxLevMin INTEGER (-60..-13),
+ p-MaxUTRA INTEGER (-50..33),
+ ...
+}
+
+
+SystemInformationBlockType7 ::= SEQUENCE {
+ t-ReselectionGERAN T-Reselection,
+ t-ReselectionGERAN-SF SpeedStateScaleFactors OPTIONAL, -- Need OR
+ carrierFreqsInfoList CarrierFreqsInfoListGERAN OPTIONAL, -- Need OR
+ ...
+}
+
+CarrierFreqsInfoListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF CarrierFreqsInfoGERAN
+
+CarrierFreqsInfoGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ commonInfo SEQUENCE {
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ ncc-Permitted BIT STRING (SIZE (8)),
+ q-RxLevMin INTEGER (0..45),
+ p-MaxGERAN INTEGER (0..39) OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold
+ },
+ ...
+}
+
+
+SystemInformationBlockType8 ::= SEQUENCE {
+ systemTimeInfo SystemTimeInfoCDMA2000 OPTIONAL, -- Need OR
+ searchWindowSize INTEGER (0..15) OPTIONAL, -- Need OR
+ parametersHRPD SEQUENCE {
+ preRegistrationInfoHRPD PreRegistrationInfoHRPD,
+ cellReselectionParametersHRPD CellReselectionParametersCDMA2000 OPTIONAL -- Need OR
+ } OPTIONAL, -- Need OR
+ parameters1XRTT SEQUENCE {
+ csfb-RegistrationParam1XRTT CSFB-RegistrationParam1XRTT OPTIONAL, -- Need OP
+ longCodeState1XRTT BIT STRING (SIZE (42)) OPTIONAL, -- Need OR
+ cellReselectionParameters1XRTT CellReselectionParametersCDMA2000 OPTIONAL -- Need OR
+ } OPTIONAL, -- Need OR
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ csfb-SupportForDualRxUEs-r9 BOOLEAN OPTIONAL, -- Need OR
+ cellReselectionParametersHRPD-v920 CellReselectionParametersCDMA2000-v920 OPTIONAL, -- Cond NCL-HRPD
+ cellReselectionParameters1XRTT-v920 CellReselectionParametersCDMA2000-v920 OPTIONAL, -- Cond NCL-1XRTT
+ csfb-RegistrationParam1XRTT-v920 CSFB-RegistrationParam1XRTT-v920 OPTIONAL, -- Cond REG-1XRTT
+ ac-BarringConfig1XRTT-r9 AC-BarringConfig1XRTT-r9 OPTIONAL -- Cond REG-1XRTT
+ ]]
+}
+
+CellReselectionParametersCDMA2000 ::= SEQUENCE {
+ bandClassList BandClassListCDMA2000,
+ neighCellList NeighCellListCDMA2000,
+ t-ReselectionCDMA2000 T-Reselection,
+ t-ReselectionCDMA2000-SF SpeedStateScaleFactors OPTIONAL -- Need OP
+}
+
+CellReselectionParametersCDMA2000-v920 ::= SEQUENCE {
+ neighCellList-v920 NeighCellListCDMA2000-v920
+}
+
+NeighCellListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000
+
+NeighCellCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ neighCellsPerFreqList NeighCellsPerBandclassListCDMA2000
+}
+
+NeighCellsPerBandclassListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000
+
+NeighCellsPerBandclassCDMA2000 ::= SEQUENCE {
+ arfcn ARFCN-ValueCDMA2000,
+ physCellIdList PhysCellIdListCDMA2000
+}
+
+NeighCellListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000-v920
+
+NeighCellCDMA2000-v920 ::= SEQUENCE {
+ neighCellsPerFreqList-v920 NeighCellsPerBandclassListCDMA2000-v920
+}
+
+NeighCellsPerBandclassListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000-v920
+
+NeighCellsPerBandclassCDMA2000-v920 ::= SEQUENCE {
+ physCellIdList-v920 PhysCellIdListCDMA2000-v920
+}
+
+PhysCellIdListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdCDMA2000
+
+PhysCellIdListCDMA2000-v920 ::= SEQUENCE (SIZE (0..24)) OF PhysCellIdCDMA2000
+
+BandClassListCDMA2000 ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassInfoCDMA2000
+
+BandClassInfoCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High INTEGER (0..63),
+ threshX-Low INTEGER (0..63),
+ ...
+}
+
+AC-BarringConfig1XRTT-r9 ::= SEQUENCE {
+ ac-Barring0to9-r9 INTEGER (0..63),
+ ac-Barring10-r9 INTEGER (0..7),
+ ac-Barring11-r9 INTEGER (0..7),
+ ac-Barring12-r9 INTEGER (0..7),
+ ac-Barring13-r9 INTEGER (0..7),
+ ac-Barring14-r9 INTEGER (0..7),
+ ac-Barring15-r9 INTEGER (0..7),
+ ac-BarringMsg-r9 INTEGER (0..7),
+ ac-BarringReg-r9 INTEGER (0..7),
+ ac-BarringEmg-r9 INTEGER (0..7)
+}
+
+
+SystemInformationBlockType9 ::= SEQUENCE {
+ hnb-Name OCTET STRING (SIZE(1..48)) OPTIONAL, -- Need OR
+ ...
+}
+
+
+SystemInformationBlockType10 ::= SEQUENCE {
+ messageIdentifier BIT STRING (SIZE (16)),
+ serialNumber BIT STRING (SIZE (16)),
+ warningType OCTET STRING (SIZE (2)),
+ warningSecurityInfo OCTET STRING (SIZE (50)) OPTIONAL, -- Need OP
+ ...
+}
+
+
+SystemInformationBlockType11 ::= SEQUENCE {
+ messageIdentifier BIT STRING (SIZE (16)),
+ serialNumber BIT STRING (SIZE (16)),
+ warningMessageSegmentType ENUMERATED {notLastSegment, lastSegment},
+ warningMessageSegmentNumber INTEGER (0..63),
+ warningMessageSegment OCTET STRING,
+ dataCodingScheme OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1
+ ...
+}
+
+
+SystemInformationBlockType12-r9 ::= SEQUENCE {
+ messageIdentifier-r9 BIT STRING (SIZE (16)),
+ serialNumber-r9 BIT STRING (SIZE (16)),
+ warningMessageSegmentType-r9 ENUMERATED {notLastSegment, lastSegment},
+ warningMessageSegmentNumber-r9 INTEGER (0..63),
+ warningMessageSegment-r9 OCTET STRING,
+ dataCodingScheme-r9 OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1
+ lateR9NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ ...
+}
+
+
+SystemInformationBlockType13-r9 ::= SEQUENCE {
+ mbsfn-AreaInfoList-r9 MBSFN-AreaInfoList-r9,
+ notificationConfig-r9 MBMS-NotificationConfig-r9,
+ lateR9NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ ...
+}
+
+
+AntennaInfoCommon ::= SEQUENCE {
+ antennaPortsCount ENUMERATED {an1, an2, an4, spare1}
+}
+
+AntennaInfoDedicated ::= SEQUENCE {
+ transmissionMode ENUMERATED {
+ tm1, tm2, tm3, tm4, tm5, tm6,
+ tm7, tm8-v920},
+ codebookSubsetRestriction CHOICE {
+ n2TxAntenna-tm3 BIT STRING (SIZE (2)),
+ n4TxAntenna-tm3 BIT STRING (SIZE (4)),
+ n2TxAntenna-tm4 BIT STRING (SIZE (6)),
+ n4TxAntenna-tm4 BIT STRING (SIZE (64)),
+ n2TxAntenna-tm5 BIT STRING (SIZE (4)),
+ n4TxAntenna-tm5 BIT STRING (SIZE (16)),
+ n2TxAntenna-tm6 BIT STRING (SIZE (4)),
+ n4TxAntenna-tm6 BIT STRING (SIZE (16))
+ } OPTIONAL, -- Cond TM
+ ue-TransmitAntennaSelection CHOICE{
+ release NULL,
+ setup ENUMERATED {closedLoop, openLoop}
+ }
+}
+
+AntennaInfoDedicated-v920 ::= SEQUENCE {
+ codebookSubsetRestriction-v920 CHOICE {
+ n2TxAntenna-tm8-r9 BIT STRING (SIZE (6)),
+ n4TxAntenna-tm8-r9 BIT STRING (SIZE (32))
+ } OPTIONAL -- Cond TM8
+}
+
+
+CQI-ReportConfig ::= SEQUENCE {
+ cqi-ReportModeAperiodic ENUMERATED {
+ rm12, rm20, rm22, rm30, rm31,
+ spare3, spare2, spare1} OPTIONAL, -- Need OR
+ nomPDSCH-RS-EPRE-Offset INTEGER (-1..6),
+ cqi-ReportPeriodic CQI-ReportPeriodic OPTIONAL -- Need ON
+}
+
+CQI-ReportConfig-v920 ::= SEQUENCE {
+ cqi-Mask-r9 ENUMERATED {setup} OPTIONAL, -- Cond cqi-Setup
+ pmi-RI-Report-r9 ENUMERATED {setup} OPTIONAL -- Cond PMIRI
+}
+
+CQI-ReportPeriodic ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ cqi-PUCCH-ResourceIndex INTEGER (0.. 1185),
+ cqi-pmi-ConfigIndex INTEGER (0..1023),
+ cqi-FormatIndicatorPeriodic CHOICE {
+ widebandCQI NULL,
+ subbandCQI SEQUENCE {
+ k INTEGER (1..4)
+ }
+ },
+ ri-ConfigIndex INTEGER (0..1023) OPTIONAL, -- Need OR
+ simultaneousAckNackAndCQI BOOLEAN
+ }
+}
+
+
+DRB-Identity ::= INTEGER (1..32)
+
+
+LogicalChannelConfig ::= SEQUENCE {
+ ul-SpecificParameters SEQUENCE {
+ priority INTEGER (1..16),
+ prioritisedBitRate ENUMERATED {
+ kBps0, kBps8, kBps16, kBps32, kBps64, kBps128,
+ kBps256, infinity, spare8, spare7, spare6,
+ spare5, spare4, spare3, spare2, spare1},
+ bucketSizeDuration ENUMERATED {
+ ms50, ms100, ms150, ms300, ms500, ms1000, spare2,
+ spare1},
+ logicalChannelGroup INTEGER (0..3) OPTIONAL -- Need OR
+ } OPTIONAL, -- Cond UL
+ ...,
+ [[ logicalChannelSR-Mask-r9 ENUMERATED {setup} OPTIONAL -- Cond SRmask
+ ]]
+}
+
+
+MAC-MainConfig ::= SEQUENCE {
+ ul-SCH-Config SEQUENCE {
+ maxHARQ-Tx ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n7, n8,
+ n10, n12, n16, n20, n24, n28,
+ spare2, spare1} OPTIONAL, -- Need ON
+ periodicBSR-Timer ENUMERATED {
+ sf5, sf10, sf16, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, sf1280, sf2560,
+ infinity, spare1} OPTIONAL, -- Need ON
+ retxBSR-Timer ENUMERATED {
+ sf320, sf640, sf1280, sf2560, sf5120,
+ sf10240, spare2, spare1},
+ ttiBundling BOOLEAN
+ } OPTIONAL, -- Need ON
+ drx-Config DRX-Config OPTIONAL, -- Need ON
+ timeAlignmentTimerDedicated TimeAlignmentTimer,
+ phr-Config CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ periodicPHR-Timer ENUMERATED {sf10, sf20, sf50, sf100, sf200,
+ sf500, sf1000, infinity},
+ prohibitPHR-Timer ENUMERATED {sf0, sf10, sf20, sf50, sf100,
+ sf200, sf500, sf1000},
+ dl-PathlossChange ENUMERATED {dB1, dB3, dB6, infinity}
+ }
+ } OPTIONAL, -- Need ON
+ ...,
+ [[ sr-ProhibitTimer-r9 INTEGER (0..7) OPTIONAL -- Need ON
+ ]]
+}
+
+DRX-Config ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ onDurationTimer ENUMERATED {
+ psf1, psf2, psf3, psf4, psf5, psf6,
+ psf8, psf10, psf20, psf30, psf40,
+ psf50, psf60, psf80, psf100,
+ psf200},
+ drx-InactivityTimer ENUMERATED {
+ psf1, psf2, psf3, psf4, psf5, psf6,
+ psf8, psf10, psf20, psf30, psf40,
+ psf50, psf60, psf80, psf100,
+ psf200, psf300, psf500, psf750,
+ psf1280, psf1920, psf2560, spare10,
+ spare9, spare8, spare7, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ drx-RetransmissionTimer ENUMERATED {
+ psf1, psf2, psf4, psf6, psf8, psf16,
+ psf24, psf33},
+ longDRX-CycleStartOffset CHOICE {
+ sf10 INTEGER(0..9),
+ sf20 INTEGER(0..19),
+ sf32 INTEGER(0..31),
+ sf40 INTEGER(0..39),
+ sf64 INTEGER(0..63),
+ sf80 INTEGER(0..79),
+ sf128 INTEGER(0..127),
+ sf160 INTEGER(0..159),
+ sf256 INTEGER(0..255),
+ sf320 INTEGER(0..319),
+ sf512 INTEGER(0..511),
+ sf640 INTEGER(0..639),
+ sf1024 INTEGER(0..1023),
+ sf1280 INTEGER(0..1279),
+ sf2048 INTEGER(0..2047),
+ sf2560 INTEGER(0..2559)
+ },
+ shortDRX SEQUENCE {
+ shortDRX-Cycle ENUMERATED {
+ sf2, sf5, sf8, sf10, sf16, sf20,
+ sf32, sf40, sf64, sf80, sf128, sf160,
+ sf256, sf320, sf512, sf640},
+ drxShortCycleTimer INTEGER (1..16)
+ } OPTIONAL -- Need OR
+ }
+}
+
+
+PDCP-Config ::= SEQUENCE {
+ discardTimer ENUMERATED {
+ ms50, ms100, ms150, ms300, ms500,
+ ms750, ms1500, infinity
+ } OPTIONAL, -- Cond Setup
+ rlc-AM SEQUENCE {
+ statusReportRequired BOOLEAN
+ } OPTIONAL, -- Cond Rlc-AM
+ rlc-UM SEQUENCE {
+ pdcp-SN-Size ENUMERATED {len7bits, len12bits}
+ } OPTIONAL, -- Cond Rlc-UM
+ headerCompression CHOICE {
+ notUsed NULL,
+ rohc SEQUENCE {
+ maxCID INTEGER (1..16383) DEFAULT 15,
+ profiles SEQUENCE {
+ profile0x0001 BOOLEAN,
+ profile0x0002 BOOLEAN,
+ profile0x0003 BOOLEAN,
+ profile0x0004 BOOLEAN,
+ profile0x0006 BOOLEAN,
+ profile0x0101 BOOLEAN,
+ profile0x0102 BOOLEAN,
+ profile0x0103 BOOLEAN,
+ profile0x0104 BOOLEAN
+ },
+ ...
+ }
+ },
+ ...
+}
+
+
+PDSCH-ConfigCommon ::= SEQUENCE {
+ referenceSignalPower INTEGER (-60..50),
+ p-b INTEGER (0..3)
+}
+
+PDSCH-ConfigDedicated::= SEQUENCE {
+ p-a ENUMERATED {
+ dB-6, dB-4dot77, dB-3, dB-1dot77,
+ dB0, dB1, dB2, dB3}
+}
+
+
+PHICH-Config ::= SEQUENCE {
+ phich-Duration ENUMERATED {normal, extended},
+ phich-Resource ENUMERATED {oneSixth, half, one, two}
+}
+
+
+PhysicalConfigDedicated ::= SEQUENCE {
+ pdsch-ConfigDedicated PDSCH-ConfigDedicated OPTIONAL, -- Need ON
+ pucch-ConfigDedicated PUCCH-ConfigDedicated OPTIONAL, -- Need ON
+ pusch-ConfigDedicated PUSCH-ConfigDedicated OPTIONAL, -- Need ON
+ uplinkPowerControlDedicated UplinkPowerControlDedicated OPTIONAL, -- Need ON
+ tpc-PDCCH-ConfigPUCCH TPC-PDCCH-Config OPTIONAL, -- Need ON
+ tpc-PDCCH-ConfigPUSCH TPC-PDCCH-Config OPTIONAL, -- Need ON
+ cqi-ReportConfig CQI-ReportConfig OPTIONAL, -- Need ON
+ soundingRS-UL-ConfigDedicated SoundingRS-UL-ConfigDedicated OPTIONAL, -- Need ON
+ antennaInfo CHOICE {
+ explicitValue AntennaInfoDedicated,
+ defaultValue NULL
+ } OPTIONAL, -- Need ON
+ schedulingRequestConfig SchedulingRequestConfig OPTIONAL, -- Need ON
+ ...,
+ [[ cqi-ReportConfig-v920 CQI-ReportConfig-v920 OPTIONAL, -- Need ON
+ antennaInfo-v920 AntennaInfoDedicated-v920 OPTIONAL -- Need ON
+ ]]
+}
+
+
+P-Max ::= INTEGER (-30..33)
+
+
+PRACH-ConfigSIB ::= SEQUENCE {
+ rootSequenceIndex INTEGER (0..837),
+ prach-ConfigInfo PRACH-ConfigInfo
+}
+
+PRACH-Config ::= SEQUENCE {
+ rootSequenceIndex INTEGER (0..837),
+ prach-ConfigInfo PRACH-ConfigInfo OPTIONAL -- Need ON
+}
+
+PRACH-ConfigInfo ::= SEQUENCE {
+ prach-ConfigIndex INTEGER (0..63),
+ highSpeedFlag BOOLEAN,
+ zeroCorrelationZoneConfig INTEGER (0..15),
+ prach-FreqOffset INTEGER (0..94)
+}
+
+
+PresenceAntennaPort1 ::= BOOLEAN
+
+
+PUCCH-ConfigCommon ::= SEQUENCE {
+ deltaPUCCH-Shift ENUMERATED {ds1, ds2, ds3},
+ nRB-CQI INTEGER (0..98),
+ nCS-AN INTEGER (0..7),
+ n1PUCCH-AN INTEGER (0..2047)
+}
+
+PUCCH-ConfigDedicated ::= SEQUENCE {
+ ackNackRepetition CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ repetitionFactor ENUMERATED {n2, n4, n6, spare1},
+ n1PUCCH-AN-Rep INTEGER (0..2047)
+ }
+ },
+ tdd-AckNackFeedbackMode ENUMERATED {bundling, multiplexing} OPTIONAL -- Cond TDD
+}
+
+
+PUSCH-ConfigCommon ::= SEQUENCE {
+ pusch-ConfigBasic SEQUENCE {
+ n-SB INTEGER (1..4),
+ hoppingMode ENUMERATED {interSubFrame, intraAndInterSubFrame},
+ pusch-HoppingOffset INTEGER (0..98),
+ enable64QAM BOOLEAN
+ },
+ ul-ReferenceSignalsPUSCH UL-ReferenceSignalsPUSCH
+}
+
+PUSCH-ConfigDedicated ::= SEQUENCE {
+ betaOffset-ACK-Index INTEGER (0..15),
+ betaOffset-RI-Index INTEGER (0..15),
+ betaOffset-CQI-Index INTEGER (0..15)
+}
+
+UL-ReferenceSignalsPUSCH ::= SEQUENCE {
+ groupHoppingEnabled BOOLEAN,
+ groupAssignmentPUSCH INTEGER (0..29),
+ sequenceHoppingEnabled BOOLEAN,
+ cyclicShift INTEGER (0..7)
+}
+
+
+RACH-ConfigCommon ::= SEQUENCE {
+ preambleInfo SEQUENCE {
+ numberOfRA-Preambles ENUMERATED {
+ n4, n8, n12, n16 ,n20, n24, n28,
+ n32, n36, n40, n44, n48, n52, n56,
+ n60, n64},
+ preamblesGroupAConfig SEQUENCE {
+ sizeOfRA-PreamblesGroupA ENUMERATED {
+ n4, n8, n12, n16 ,n20, n24, n28,
+ n32, n36, n40, n44, n48, n52, n56,
+ n60},
+ messageSizeGroupA ENUMERATED {b56, b144, b208, b256},
+ messagePowerOffsetGroupB ENUMERATED {
+ minusinfinity, dB0, dB5, dB8, dB10, dB12,
+ dB15, dB18},
+ ...
+ } OPTIONAL -- Need OP
+ },
+ powerRampingParameters SEQUENCE {
+ powerRampingStep ENUMERATED {dB0, dB2,dB4, dB6},
+ preambleInitialReceivedTargetPower ENUMERATED {
+ dBm-120, dBm-118, dBm-116, dBm-114, dBm-112,
+ dBm-110, dBm-108, dBm-106, dBm-104, dBm-102,
+ dBm-100, dBm-98, dBm-96, dBm-94,
+ dBm-92, dBm-90}
+ },
+ ra-SupervisionInfo SEQUENCE {
+ preambleTransMax ENUMERATED {
+ n3, n4, n5, n6, n7, n8, n10, n20, n50,
+ n100, n200},
+ ra-ResponseWindowSize ENUMERATED {
+ sf2, sf3, sf4, sf5, sf6, sf7,
+ sf8, sf10},
+ mac-ContentionResolutionTimer ENUMERATED {
+ sf8, sf16, sf24, sf32, sf40, sf48,
+ sf56, sf64}
+ },
+ maxHARQ-Msg3Tx INTEGER (1..8),
+ ...
+}
+
+
+RACH-ConfigDedicated ::= SEQUENCE {
+ ra-PreambleIndex INTEGER (0..63),
+ ra-PRACH-MaskIndex INTEGER (0..15)
+}
+
+
+RadioResourceConfigCommonSIB ::= SEQUENCE {
+ rach-ConfigCommon RACH-ConfigCommon,
+ bcch-Config BCCH-Config,
+ pcch-Config PCCH-Config,
+ prach-Config PRACH-ConfigSIB,
+ pdsch-ConfigCommon PDSCH-ConfigCommon,
+ pusch-ConfigCommon PUSCH-ConfigCommon,
+ pucch-ConfigCommon PUCCH-ConfigCommon,
+ soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon,
+ uplinkPowerControlCommon UplinkPowerControlCommon,
+ ul-CyclicPrefixLength UL-CyclicPrefixLength,
+ ...
+}
+
+RadioResourceConfigCommon ::= SEQUENCE {
+ rach-ConfigCommon RACH-ConfigCommon OPTIONAL, -- Need ON
+ prach-Config PRACH-Config,
+ pdsch-ConfigCommon PDSCH-ConfigCommon OPTIONAL, -- Need ON
+ pusch-ConfigCommon PUSCH-ConfigCommon,
+ phich-Config PHICH-Config OPTIONAL, -- Need ON
+ pucch-ConfigCommon PUCCH-ConfigCommon OPTIONAL, -- Need ON
+ soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon OPTIONAL, -- Need ON
+ uplinkPowerControlCommon UplinkPowerControlCommon OPTIONAL, -- Need ON
+ antennaInfoCommon AntennaInfoCommon OPTIONAL, -- Need ON
+ p-Max P-Max OPTIONAL, -- Need OP
+ tdd-Config TDD-Config OPTIONAL, -- Cond TDD
+ ul-CyclicPrefixLength UL-CyclicPrefixLength,
+ ...
+}
+
+BCCH-Config ::= SEQUENCE {
+ modificationPeriodCoeff ENUMERATED {n2, n4, n8, n16}
+}
+
+PCCH-Config ::= SEQUENCE {
+ defaultPagingCycle ENUMERATED {
+ rf32, rf64, rf128, rf256},
+ nB ENUMERATED {
+ fourT, twoT, oneT, halfT, quarterT, oneEighthT,
+ oneSixteenthT, oneThirtySecondT}
+}
+
+UL-CyclicPrefixLength ::= ENUMERATED {len1, len2}
+
+
+RadioResourceConfigDedicated ::= SEQUENCE {
+ srb-ToAddModList SRB-ToAddModList OPTIONAL, -- Cond HO-Conn
+ drb-ToAddModList DRB-ToAddModList OPTIONAL, -- Cond HO-toEUTRA
+ drb-ToReleaseList DRB-ToReleaseList OPTIONAL, -- Need ON
+ mac-MainConfig CHOICE {
+ explicitValue MAC-MainConfig,
+ defaultValue NULL
+ } OPTIONAL, -- Cond HO-toEUTRA2
+ sps-Config SPS-Config OPTIONAL, -- Need ON
+ physicalConfigDedicated PhysicalConfigDedicated OPTIONAL, -- Need ON
+ ...,
+ [[ rlf-TimersAndConstants-r9 RLF-TimersAndConstants-r9 OPTIONAL -- Need ON
+ ]]
+}
+
+SRB-ToAddModList ::= SEQUENCE (SIZE (1..2)) OF SRB-ToAddMod
+
+SRB-ToAddMod ::= SEQUENCE {
+ srb-Identity INTEGER (1..2),
+ rlc-Config CHOICE {
+ explicitValue RLC-Config,
+ defaultValue NULL
+ } OPTIONAL, -- Cond Setup
+ logicalChannelConfig CHOICE {
+ explicitValue LogicalChannelConfig,
+ defaultValue NULL
+ } OPTIONAL, -- Cond Setup
+ ...
+}
+
+DRB-ToAddModList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddMod
+
+DRB-ToAddMod ::= SEQUENCE {
+ eps-BearerIdentity INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup
+ drb-Identity DRB-Identity,
+ pdcp-Config PDCP-Config OPTIONAL, -- Cond PDCP
+ rlc-Config RLC-Config OPTIONAL, -- Cond Setup
+ logicalChannelIdentity INTEGER (3..10) OPTIONAL, -- Cond DRB-Setup
+ logicalChannelConfig LogicalChannelConfig OPTIONAL, -- Cond Setup
+ ...
+}
+
+DRB-ToReleaseList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-Identity
+
+
+RLC-Config ::= CHOICE {
+ am SEQUENCE {
+ ul-AM-RLC UL-AM-RLC,
+ dl-AM-RLC DL-AM-RLC
+ },
+ um-Bi-Directional SEQUENCE {
+ ul-UM-RLC UL-UM-RLC,
+ dl-UM-RLC DL-UM-RLC
+ },
+ um-Uni-Directional-UL SEQUENCE {
+ ul-UM-RLC UL-UM-RLC
+ },
+ um-Uni-Directional-DL SEQUENCE {
+ dl-UM-RLC DL-UM-RLC
+ },
+ ...
+}
+
+UL-AM-RLC ::= SEQUENCE {
+ t-PollRetransmit T-PollRetransmit,
+ pollPDU PollPDU,
+ pollByte PollByte,
+ maxRetxThreshold ENUMERATED {
+ t1, t2, t3, t4, t6, t8, t16, t32}
+}
+
+DL-AM-RLC ::= SEQUENCE {
+ t-Reordering T-Reordering,
+ t-StatusProhibit T-StatusProhibit
+}
+
+UL-UM-RLC ::= SEQUENCE {
+ sn-FieldLength SN-FieldLength
+}
+
+DL-UM-RLC ::= SEQUENCE {
+ sn-FieldLength SN-FieldLength,
+ t-Reordering T-Reordering
+}
+
+SN-FieldLength ::= ENUMERATED {size5, size10}
+
+T-PollRetransmit ::= ENUMERATED {
+ ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms105,
+ ms110, ms115, ms120, ms125, ms130, ms135,
+ ms140, ms145, ms150, ms155, ms160, ms165,
+ ms170, ms175, ms180, ms185, ms190, ms195,
+ ms200, ms205, ms210, ms215, ms220, ms225,
+ ms230, ms235, ms240, ms245, ms250, ms300,
+ ms350, ms400, ms450, ms500, spare9, spare8,
+ spare7, spare6, spare5, spare4, spare3,
+ spare2, spare1}
+
+PollPDU ::= ENUMERATED {
+ p4, p8, p16, p32, p64, p128, p256, pInfinity}
+
+PollByte ::= ENUMERATED {
+ kB25, kB50, kB75, kB100, kB125, kB250, kB375,
+ kB500, kB750, kB1000, kB1250, kB1500, kB2000,
+ kB3000, kBinfinity, spare1}
+
+T-Reordering ::= ENUMERATED {
+ ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms110,
+ ms120, ms130, ms140, ms150, ms160, ms170,
+ ms180, ms190, ms200, spare1}
+
+T-StatusProhibit ::= ENUMERATED {
+ ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms105,
+ ms110, ms115, ms120, ms125, ms130, ms135,
+ ms140, ms145, ms150, ms155, ms160, ms165,
+ ms170, ms175, ms180, ms185, ms190, ms195,
+ ms200, ms205, ms210, ms215, ms220, ms225,
+ ms230, ms235, ms240, ms245, ms250, ms300,
+ ms350, ms400, ms450, ms500, spare8, spare7,
+ spare6, spare5, spare4, spare3, spare2,
+ spare1}
+
+
+RLF-TimersAndConstants-r9 ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ t301-r9 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t310-r9 ENUMERATED {
+ ms0, ms50, ms100, ms200, ms500, ms1000, ms2000},
+ n310-r9 ENUMERATED {
+ n1, n2, n3, n4, n6, n8, n10, n20},
+ t311-r9 ENUMERATED {
+ ms1000, ms3000, ms5000, ms10000, ms15000,
+ ms20000, ms30000},
+ n311-r9 ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n8, n10},
+ ...
+ }
+}
+
+
+SchedulingRequestConfig ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ sr-PUCCH-ResourceIndex INTEGER (0..2047),
+ sr-ConfigIndex INTEGER (0..157),
+ dsr-TransMax ENUMERATED {
+ n4, n8, n16, n32, n64, spare3, spare2, spare1}
+ }
+}
+
+
+SoundingRS-UL-ConfigCommon ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ srs-BandwidthConfig ENUMERATED {bw0, bw1, bw2, bw3, bw4, bw5, bw6, bw7},
+ srs-SubframeConfig ENUMERATED {
+ sc0, sc1, sc2, sc3, sc4, sc5, sc6, sc7,
+ sc8, sc9, sc10, sc11, sc12, sc13, sc14, sc15},
+ ackNackSRS-SimultaneousTransmission BOOLEAN,
+ srs-MaxUpPts ENUMERATED {true} OPTIONAL -- Cond TDD
+ }
+}
+
+SoundingRS-UL-ConfigDedicated ::= CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ srs-Bandwidth ENUMERATED {bw0, bw1, bw2, bw3},
+ srs-HoppingBandwidth ENUMERATED {hbw0, hbw1, hbw2, hbw3},
+ freqDomainPosition INTEGER (0..23),
+ duration BOOLEAN,
+ srs-ConfigIndex INTEGER (0..1023),
+ transmissionComb INTEGER (0..1),
+ cyclicShift ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7}
+ }
+}
+
+
+
+SPS-Config ::= SEQUENCE {
+ semiPersistSchedC-RNTI C-RNTI OPTIONAL, -- Need OR
+ sps-ConfigDL SPS-ConfigDL OPTIONAL, -- Need ON
+ sps-ConfigUL SPS-ConfigUL OPTIONAL -- Need ON
+}
+
+SPS-ConfigDL ::= CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ semiPersistSchedIntervalDL ENUMERATED {
+ sf10, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ numberOfConfSPS-Processes INTEGER (1..8),
+ n1-PUCCH-AN-PersistentList N1-PUCCH-AN-PersistentList,
+ ...
+ }
+}
+
+SPS-ConfigUL ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ semiPersistSchedIntervalUL ENUMERATED {
+ sf10, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ implicitReleaseAfter ENUMERATED {e2, e3, e4, e8},
+ p0-Persistent SEQUENCE {
+ p0-NominalPUSCH-Persistent INTEGER (-126..24),
+ p0-UE-PUSCH-Persistent INTEGER (-8..7)
+ } OPTIONAL, -- Need OP
+ twoIntervalsConfig ENUMERATED {true} OPTIONAL, -- Cond TDD
+ ...
+ }
+}
+
+N1-PUCCH-AN-PersistentList ::= SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047)
+
+
+TDD-Config ::= SEQUENCE {
+ subframeAssignment ENUMERATED {
+ sa0, sa1, sa2, sa3, sa4, sa5, sa6},
+ specialSubframePatterns ENUMERATED {
+ ssp0, ssp1, ssp2, ssp3, ssp4,ssp5, ssp6, ssp7,
+ ssp8}
+}
+
+
+TimeAlignmentTimer ::= ENUMERATED {
+ sf500, sf750, sf1280, sf1920, sf2560, sf5120,
+ sf10240, infinity}
+
+TPC-PDCCH-Config ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ tpc-RNTI BIT STRING (SIZE (16)),
+ tpc-Index TPC-Index
+ }
+}
+
+TPC-Index ::= CHOICE {
+ indexOfFormat3 INTEGER (1..15),
+ indexOfFormat3A INTEGER (1..31)
+}
+
+
+UplinkPowerControlCommon ::= SEQUENCE {
+ p0-NominalPUSCH INTEGER (-126..24),
+ alpha ENUMERATED {al0, al04, al05, al06, al07, al08, al09, al1},
+ p0-NominalPUCCH INTEGER (-127..-96),
+ deltaFList-PUCCH DeltaFList-PUCCH,
+ deltaPreambleMsg3 INTEGER (-1..6)
+}
+
+UplinkPowerControlDedicated ::= SEQUENCE {
+ p0-UE-PUSCH INTEGER (-8..7),
+ deltaMCS-Enabled ENUMERATED {en0, en1},
+ accumulationEnabled BOOLEAN,
+ p0-UE-PUCCH INTEGER (-8..7),
+ pSRS-Offset INTEGER (0..15),
+ filterCoefficient FilterCoefficient DEFAULT fc4
+}
+
+DeltaFList-PUCCH ::= SEQUENCE {
+ deltaF-PUCCH-Format1 ENUMERATED {deltaF-2, deltaF0, deltaF2},
+ deltaF-PUCCH-Format1b ENUMERATED {deltaF1, deltaF3, deltaF5},
+ deltaF-PUCCH-Format2 ENUMERATED {deltaF-2, deltaF0, deltaF1, deltaF2},
+ deltaF-PUCCH-Format2a ENUMERATED {deltaF-2, deltaF0, deltaF2},
+ deltaF-PUCCH-Format2b ENUMERATED {deltaF-2, deltaF0, deltaF2}
+}
+
+
+NextHopChainingCount ::= INTEGER (0..7)
+
+
+SecurityAlgorithmConfig ::= SEQUENCE {
+ cipheringAlgorithm ENUMERATED {
+ eea0, eea1, eea2, spare5, spare4, spare3,
+ spare2, spare1, ...},
+ integrityProtAlgorithm ENUMERATED {
+ eia0-v920, eia1, eia2, spare5, spare4, spare3,
+ spare2, spare1, ...}
+}
+
+
+ShortMAC-I ::= BIT STRING (SIZE (16))
+
+
+AdditionalSpectrumEmission ::= INTEGER (1..32)
+
+
+ARFCN-ValueCDMA2000 ::= INTEGER (0..2047)
+
+
+ARFCN-ValueEUTRA ::= INTEGER (0..maxEARFCN)
+
+
+ARFCN-ValueGERAN ::= INTEGER (0..1023)
+
+
+ARFCN-ValueUTRA ::= INTEGER (0..16383)
+
+
+BandclassCDMA2000 ::= ENUMERATED {
+ bc0, bc1, bc2, bc3, bc4, bc5, bc6, bc7, bc8,
+ bc9, bc10, bc11, bc12, bc13, bc14, bc15, bc16,
+ bc17, spare14, spare13, spare12, spare11, spare10,
+ spare9, spare8, spare7, spare6, spare5, spare4,
+ spare3, spare2, spare1, ...}
+
+
+BandIndicatorGERAN ::= ENUMERATED {dcs1800, pcs1900}
+
+
+CarrierFreqCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ arfcn ARFCN-ValueCDMA2000
+}
+
+
+CarrierFreqGERAN ::= SEQUENCE {
+ arfcn ARFCN-ValueGERAN,
+ bandIndicator BandIndicatorGERAN
+}
+
+
+CarrierFreqsGERAN ::= SEQUENCE {
+ startingARFCN ARFCN-ValueGERAN,
+ bandIndicator BandIndicatorGERAN,
+ followingARFCNs CHOICE {
+ explicitListOfARFCNs ExplicitListOfARFCNs,
+ equallySpacedARFCNs SEQUENCE {
+ arfcn-Spacing INTEGER (1..8),
+ numberOfFollowingARFCNs INTEGER (0..31)
+ },
+ variableBitMapOfARFCNs OCTET STRING (SIZE (1..16))
+ }
+}
+
+ExplicitListOfARFCNs ::= SEQUENCE (SIZE (0..31)) OF ARFCN-ValueGERAN
+
+
+CDMA2000-Type ::= ENUMERATED {type1XRTT, typeHRPD}
+
+
+CellIdentity ::= BIT STRING (SIZE (28))
+
+
+CellIndexList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellIndex
+
+CellIndex ::= INTEGER (1..maxCellMeas)
+
+
+CellReselectionPriority ::= INTEGER (0..7)
+
+
+CSFB-RegistrationParam1XRTT ::= SEQUENCE {
+ sid BIT STRING (SIZE (15)),
+ nid BIT STRING (SIZE (16)),
+ multipleSID BOOLEAN,
+ multipleNID BOOLEAN,
+ homeReg BOOLEAN,
+ foreignSIDReg BOOLEAN,
+ foreignNIDReg BOOLEAN,
+ parameterReg BOOLEAN,
+ powerUpReg BOOLEAN,
+ registrationPeriod BIT STRING (SIZE (7)),
+ registrationZone BIT STRING (SIZE (12)),
+ totalZone BIT STRING (SIZE (3)),
+ zoneTimer BIT STRING (SIZE (3))
+}
+
+CSFB-RegistrationParam1XRTT-v920 ::= SEQUENCE {
+ powerDownReg-r9 ENUMERATED {true}
+}
+
+
+CellGlobalIdEUTRA ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellIdentity CellIdentity
+}
+
+
+CellGlobalIdUTRA ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellIdentity BIT STRING (SIZE (28))
+}
+
+
+CellGlobalIdGERAN ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ locationAreaCode BIT STRING (SIZE (16)),
+ cellIdentity BIT STRING (SIZE (16))
+}
+
+
+CellGlobalIdCDMA2000 ::= CHOICE {
+ cellGlobalId1XRTT BIT STRING (SIZE (47)),
+ cellGlobalIdHRPD BIT STRING (SIZE (128))
+}
+
+
+CSG-Identity ::= BIT STRING (SIZE (27))
+
+
+MobilityControlInfo ::= SEQUENCE {
+ targetPhysCellId PhysCellId,
+ carrierFreq CarrierFreqEUTRA OPTIONAL, -- Cond HO-toEUTRA
+ carrierBandwidth CarrierBandwidthEUTRA OPTIONAL, -- Cond HO-toEUTRA
+ additionalSpectrumEmission AdditionalSpectrumEmission OPTIONAL, -- Cond HO-toEUTRA
+ t304 ENUMERATED {
+ ms50, ms100, ms150, ms200, ms500, ms1000,
+ ms2000, spare1},
+ newUE-Identity C-RNTI,
+ radioResourceConfigCommon RadioResourceConfigCommon,
+ rach-ConfigDedicated RACH-ConfigDedicated OPTIONAL, -- Need OP
+ ...
+}
+
+CarrierBandwidthEUTRA ::= SEQUENCE {
+ dl-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100, spare10,
+ spare9, spare8, spare7, spare6, spare5,
+ spare4, spare3, spare2, spare1},
+ ul-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100, spare10,
+ spare9, spare8, spare7, spare6, spare5,
+ spare4, spare3, spare2, spare1} OPTIONAL -- Need OP
+}
+
+CarrierFreqEUTRA ::= SEQUENCE {
+ dl-CarrierFreq ARFCN-ValueEUTRA,
+ ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL -- Cond FDD
+}
+
+
+MobilityParametersCDMA2000 ::= OCTET STRING
+
+
+MobilityStateParameters ::= SEQUENCE {
+ t-Evaluation ENUMERATED {
+ s30, s60, s120, s180, s240, spare3, spare2, spare1},
+ t-HystNormal ENUMERATED {
+ s30, s60, s120, s180, s240, spare3, spare2, spare1},
+ n-CellChangeMedium INTEGER (1..16),
+ n-CellChangeHigh INTEGER (1..16)
+}
+
+
+PhysCellId ::= INTEGER (0..503)
+
+
+PhysCellIdRange ::= SEQUENCE {
+ start PhysCellId,
+ range ENUMERATED {
+ n4, n8, n12, n16, n24, n32, n48, n64, n84,
+ n96, n128, n168, n252, n504, spare2,
+ spare1} OPTIONAL -- Need OP
+}
+
+
+PhysCellIdCDMA2000 ::= INTEGER (0..maxPNOffset)
+
+
+PhysCellIdGERAN ::= SEQUENCE {
+ networkColourCode BIT STRING (SIZE (3)),
+ baseStationColourCode BIT STRING (SIZE (3))
+}
+
+
+PhysCellIdUTRA-FDD ::= INTEGER (0..511)
+
+
+PhysCellIdUTRA-TDD ::= INTEGER (0..127)
+
+
+PLMN-Identity ::= SEQUENCE {
+ mcc MCC OPTIONAL, -- Cond MCC
+ mnc MNC
+}
+
+MCC ::= SEQUENCE (SIZE (3)) OF
+ MCC-MNC-Digit
+
+MNC ::= SEQUENCE (SIZE (2..3)) OF
+ MCC-MNC-Digit
+
+MCC-MNC-Digit ::= INTEGER (0..9)
+
+
+
+PreRegistrationInfoHRPD ::= SEQUENCE {
+ preRegistrationAllowed BOOLEAN,
+ preRegistrationZoneId PreRegistrationZoneIdHRPD OPTIONAL, -- cond PreRegAllowed
+ secondaryPreRegistrationZoneIdList SecondaryPreRegistrationZoneIdListHRPD OPTIONAL -- Need OR
+}
+
+SecondaryPreRegistrationZoneIdListHRPD ::= SEQUENCE (SIZE (1..2)) OF PreRegistrationZoneIdHRPD
+
+PreRegistrationZoneIdHRPD ::= INTEGER (0..255)
+
+
+Q-QualMin-r9 ::= INTEGER (-34..-3)
+
+
+Q-RxLevMin ::= INTEGER (-70..-22)
+
+
+Q-OffsetRange ::= ENUMERATED {
+ dB-24, dB-22, dB-20, dB-18, dB-16, dB-14,
+ dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3,
+ dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5,
+ dB6, dB8, dB10, dB12, dB14, dB16, dB18,
+ dB20, dB22, dB24}
+
+
+Q-OffsetRangeInterRAT ::= INTEGER (-15..15)
+
+
+ReselectionThreshold ::= INTEGER (0..31)
+
+
+ReselectionThresholdQ-r9 ::= INTEGER (0..31)
+
+
+SpeedStateScaleFactors ::= SEQUENCE {
+ sf-Medium ENUMERATED {oDot25, oDot5, oDot75, lDot0},
+ sf-High ENUMERATED {oDot25, oDot5, oDot75, lDot0}
+}
+
+SystemInfoListGERAN ::= SEQUENCE (SIZE (1..maxGERAN-SI)) OF
+ OCTET STRING (SIZE (1..23))
+
+
+SystemTimeInfoCDMA2000 ::= SEQUENCE {
+ cdma-EUTRA-Synchronisation BOOLEAN,
+ cdma-SystemTime CHOICE {
+ synchronousSystemTime BIT STRING (SIZE (39)),
+ asynchronousSystemTime BIT STRING (SIZE (49))
+ }
+}
+
+
+TrackingAreaCode ::= BIT STRING (SIZE (16))
+
+
+T-Reselection ::= INTEGER (0..7)
+
+
+AllowedMeasBandwidth ::= ENUMERATED {mbw6, mbw15, mbw25, mbw50, mbw75, mbw100}
+
+
+Hysteresis ::= INTEGER (0..30)
+
+
+MeasConfig ::= SEQUENCE {
+ -- Measurement objects
+ measObjectToRemoveList MeasObjectToRemoveList OPTIONAL, -- Need ON
+ measObjectToAddModList MeasObjectToAddModList OPTIONAL, -- Need ON
+ -- Reporting configurations
+ reportConfigToRemoveList ReportConfigToRemoveList OPTIONAL, -- Need ON
+ reportConfigToAddModList ReportConfigToAddModList OPTIONAL, -- Need ON
+ -- Measurement identities
+ measIdToRemoveList MeasIdToRemoveList OPTIONAL, -- Need ON
+ measIdToAddModList MeasIdToAddModList OPTIONAL, -- Need ON
+ -- Other parameters
+ quantityConfig QuantityConfig OPTIONAL, -- Need ON
+ measGapConfig MeasGapConfig OPTIONAL, -- Need ON
+ s-Measure RSRP-Range OPTIONAL, -- Need ON
+ preRegistrationInfoHRPD PreRegistrationInfoHRPD OPTIONAL, -- Need OP
+ speedStatePars CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ mobilityStateParameters MobilityStateParameters,
+ timeToTrigger-SF SpeedStateScaleFactors
+ }
+ } OPTIONAL, -- Need ON
+ ...
+}
+
+MeasIdToRemoveList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasId
+
+MeasObjectToRemoveList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectId
+
+ReportConfigToRemoveList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigId
+
+
+MeasGapConfig ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ gapOffset CHOICE {
+ gp0 INTEGER (0..39),
+ gp1 INTEGER (0..79),
+ ...
+ }
+ }
+}
+
+
+MeasId ::= INTEGER (1..maxMeasId)
+
+
+MeasIdToAddModList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddMod
+
+MeasIdToAddMod ::= SEQUENCE {
+ measId MeasId,
+ measObjectId MeasObjectId,
+ reportConfigId ReportConfigId
+}
+
+
+MeasObjectCDMA2000 ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ carrierFreq CarrierFreqCDMA2000,
+ searchWindowSize INTEGER (0..15) OPTIONAL, -- Need ON
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CellsToAddModListCDMA2000 OPTIONAL, -- Need ON
+ cellForWhichToReportCGI PhysCellIdCDMA2000 OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModCDMA2000
+
+CellsToAddModCDMA2000 ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdCDMA2000
+}
+
+
+MeasObjectEUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ allowedMeasBandwidth AllowedMeasBandwidth,
+ presenceAntennaPort1 PresenceAntennaPort1,
+ neighCellConfig NeighCellConfig,
+ offsetFreq Q-OffsetRange DEFAULT dB0,
+ -- Neighbour cell list
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CellsToAddModList OPTIONAL, -- Need ON
+ -- Black list
+ blackCellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ blackCellsToAddModList BlackCellsToAddModList OPTIONAL, -- Need ON
+ cellForWhichToReportCGI PhysCellId OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddMod
+
+CellsToAddMod ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellId,
+ cellIndividualOffset Q-OffsetRange
+}
+
+BlackCellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF BlackCellsToAddMod
+
+BlackCellsToAddMod ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellIdRange PhysCellIdRange
+}
+
+
+MeasObjectGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ ncc-Permitted BIT STRING(SIZE (8)) DEFAULT '11111111'B,
+ cellForWhichToReportCGI PhysCellIdGERAN OPTIONAL, -- Need ON
+ ...
+}
+
+
+MeasObjectId ::= INTEGER (1..maxObjectId)
+
+
+MeasObjectToAddModList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectToAddMod
+
+MeasObjectToAddMod ::= SEQUENCE {
+ measObjectId MeasObjectId,
+ measObject CHOICE {
+ measObjectEUTRA MeasObjectEUTRA,
+ measObjectUTRA MeasObjectUTRA,
+ measObjectGERAN MeasObjectGERAN,
+ measObjectCDMA2000 MeasObjectCDMA2000,
+ ...
+ }
+}
+
+
+MeasObjectUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CHOICE {
+ cellsToAddModListUTRA-FDD CellsToAddModListUTRA-FDD,
+ cellsToAddModListUTRA-TDD CellsToAddModListUTRA-TDD
+ } OPTIONAL, -- Need ON
+ cellForWhichToReportCGI CHOICE {
+ utra-FDD PhysCellIdUTRA-FDD,
+ utra-TDD PhysCellIdUTRA-TDD
+ } OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModListUTRA-FDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-FDD
+
+CellsToAddModUTRA-FDD ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdUTRA-FDD
+}
+
+CellsToAddModListUTRA-TDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-TDD
+
+CellsToAddModUTRA-TDD ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdUTRA-TDD
+}
+
+
+MeasResults ::= SEQUENCE {
+ measId MeasId,
+ measResultServCell SEQUENCE {
+ rsrpResult RSRP-Range,
+ rsrqResult RSRQ-Range
+ },
+ measResultNeighCells CHOICE {
+ measResultListEUTRA MeasResultListEUTRA,
+ measResultListUTRA MeasResultListUTRA,
+ measResultListGERAN MeasResultListGERAN,
+ measResultsCDMA2000 MeasResultsCDMA2000,
+ ...
+ } OPTIONAL,
+ ...,
+ [[ measResultForECID-r9 MeasResultForECID-r9 OPTIONAL
+ ]]
+}
+
+MeasResultListEUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultEUTRA
+
+MeasResultEUTRA ::= SEQUENCE {
+ physCellId PhysCellId,
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdEUTRA,
+ trackingAreaCode TrackingAreaCode,
+ plmn-IdentityList PLMN-IdentityList2 OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ rsrpResult RSRP-Range OPTIONAL,
+ rsrqResult RSRQ-Range OPTIONAL,
+ ...,
+ [[ additionalSI-Info-r9 AdditionalSI-Info-r9 OPTIONAL
+ ]]
+ }
+}
+
+MeasResultListUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultUTRA
+
+MeasResultUTRA ::= SEQUENCE {
+ physCellId CHOICE {
+ fdd PhysCellIdUTRA-FDD,
+ tdd PhysCellIdUTRA-TDD
+ },
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdUTRA,
+ locationAreaCode BIT STRING (SIZE (16)) OPTIONAL,
+ routingAreaCode BIT STRING (SIZE (8)) OPTIONAL,
+ plmn-IdentityList PLMN-IdentityList2 OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ utra-RSCP INTEGER (-5..91) OPTIONAL,
+ utra-EcN0 INTEGER (0..49) OPTIONAL,
+ ...,
+ [[ additionalSI-Info-r9 AdditionalSI-Info-r9 OPTIONAL
+ ]]
+ }
+}
+
+MeasResultListGERAN ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultGERAN
+
+MeasResultGERAN ::= SEQUENCE {
+ carrierFreq CarrierFreqGERAN,
+ physCellId PhysCellIdGERAN,
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdGERAN,
+ routingAreaCode BIT STRING (SIZE (8)) OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ rssi INTEGER (0..63),
+ ...
+ }
+}
+
+MeasResultsCDMA2000 ::= SEQUENCE {
+ preRegistrationStatusHRPD BOOLEAN,
+ measResultListCDMA2000 MeasResultListCDMA2000
+}
+
+MeasResultListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultCDMA2000
+
+MeasResultCDMA2000 ::= SEQUENCE {
+ physCellId PhysCellIdCDMA2000,
+ cgi-Info CellGlobalIdCDMA2000 OPTIONAL,
+ measResult SEQUENCE {
+ pilotPnPhase INTEGER (0..32767) OPTIONAL,
+ pilotStrength INTEGER (0..63),
+ ...
+ }
+}
+
+MeasResultForECID-r9 ::= SEQUENCE {
+ ue-RxTxTimeDiffResult-r9 INTEGER (0..4095),
+ currentSFN-r9 BIT STRING (SIZE (10))
+}
+
+PLMN-IdentityList2 ::= SEQUENCE (SIZE (1..5)) OF PLMN-Identity
+
+AdditionalSI-Info-r9 ::= SEQUENCE {
+ csg-MemberStatus-r9 ENUMERATED {member} OPTIONAL,
+ csg-Identity-r9 CSG-Identity OPTIONAL
+}
+
+
+QuantityConfig ::= SEQUENCE {
+ quantityConfigEUTRA QuantityConfigEUTRA OPTIONAL, -- Need ON
+ quantityConfigUTRA QuantityConfigUTRA OPTIONAL, -- Need ON
+ quantityConfigGERAN QuantityConfigGERAN OPTIONAL, -- Need ON
+ quantityConfigCDMA2000 QuantityConfigCDMA2000 OPTIONAL, -- Need ON
+ ...
+}
+
+QuantityConfigEUTRA ::= SEQUENCE {
+ filterCoefficientRSRP FilterCoefficient DEFAULT fc4,
+ filterCoefficientRSRQ FilterCoefficient DEFAULT fc4
+}
+
+QuantityConfigUTRA ::= SEQUENCE {
+ measQuantityUTRA-FDD ENUMERATED {cpich-RSCP, cpich-EcN0},
+ measQuantityUTRA-TDD ENUMERATED {pccpch-RSCP},
+ filterCoefficient FilterCoefficient DEFAULT fc4
+}
+
+QuantityConfigGERAN ::= SEQUENCE {
+ measQuantityGERAN ENUMERATED {rssi},
+ filterCoefficient FilterCoefficient DEFAULT fc2
+}
+
+QuantityConfigCDMA2000 ::= SEQUENCE {
+ measQuantityCDMA2000 ENUMERATED {pilotStrength, pilotPnPhaseAndPilotStrength}
+}
+
+
+ReportConfigEUTRA ::= SEQUENCE {
+ triggerType CHOICE {
+ event SEQUENCE {
+ eventId CHOICE {
+ eventA1 SEQUENCE {
+ a1-Threshold ThresholdEUTRA
+ },
+ eventA2 SEQUENCE {
+ a2-Threshold ThresholdEUTRA
+ },
+ eventA3 SEQUENCE {
+ a3-Offset INTEGER (-30..30),
+ reportOnLeave BOOLEAN
+ },
+ eventA4 SEQUENCE {
+ a4-Threshold ThresholdEUTRA
+ },
+ eventA5 SEQUENCE {
+ a5-Threshold1 ThresholdEUTRA,
+ a5-Threshold2 ThresholdEUTRA
+ },
+ ...
+ },
+ hysteresis Hysteresis,
+ timeToTrigger TimeToTrigger
+ },
+ periodical SEQUENCE {
+ purpose ENUMERATED {
+ reportStrongestCells, reportCGI}
+ }
+ },
+ triggerQuantity ENUMERATED {rsrp, rsrq},
+ reportQuantity ENUMERATED {sameAsTriggerQuantity, both},
+ maxReportCells INTEGER (1..maxCellReport),
+ reportInterval ReportInterval,
+ reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity},
+ ...,
+ [[ si-RequestForHO-r9 ENUMERATED {setup} OPTIONAL, -- Cond reportCGI
+ ue-RxTxTimeDiffPeriodical-r9 ENUMERATED {setup} OPTIONAL -- Need OR
+ ]]
+}
+
+ThresholdEUTRA ::= CHOICE{
+ threshold-RSRP RSRP-Range,
+ threshold-RSRQ RSRQ-Range
+}
+
+
+ReportConfigId ::= INTEGER (1..maxReportConfigId)
+
+
+ReportConfigInterRAT ::= SEQUENCE {
+ triggerType CHOICE {
+ event SEQUENCE {
+ eventId CHOICE {
+ eventB1 SEQUENCE {
+ b1-Threshold CHOICE {
+ b1-ThresholdUTRA ThresholdUTRA,
+ b1-ThresholdGERAN ThresholdGERAN,
+ b1-ThresholdCDMA2000 ThresholdCDMA2000
+ }
+ },
+ eventB2 SEQUENCE {
+ b2-Threshold1 ThresholdEUTRA,
+ b2-Threshold2 CHOICE {
+ b2-Threshold2UTRA ThresholdUTRA,
+ b2-Threshold2GERAN ThresholdGERAN,
+ b2-Threshold2CDMA2000 ThresholdCDMA2000
+ }
+ },
+ ...
+ },
+ hysteresis Hysteresis,
+ timeToTrigger TimeToTrigger
+ },
+ periodical SEQUENCE {
+ purpose ENUMERATED {
+ reportStrongestCells,
+ reportStrongestCellsForSON,
+ reportCGI}
+ }
+ },
+ maxReportCells INTEGER (1..maxCellReport),
+ reportInterval ReportInterval,
+ reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity},
+ ...,
+ [[ si-RequestForHO-r9 ENUMERATED {setup} OPTIONAL -- Cond reportCGI
+ ]]
+}
+
+ThresholdUTRA ::= CHOICE{
+ utra-RSCP INTEGER (-5..91),
+ utra-EcN0 INTEGER (0..49)
+}
+
+ThresholdGERAN ::= INTEGER (0..63)
+
+ThresholdCDMA2000 ::= INTEGER (0..63)
+
+
+ReportConfigToAddModList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigToAddMod
+
+ReportConfigToAddMod ::= SEQUENCE {
+ reportConfigId ReportConfigId,
+ reportConfig CHOICE {
+ reportConfigEUTRA ReportConfigEUTRA,
+ reportConfigInterRAT ReportConfigInterRAT
+ }
+}
+
+
+
+ReportInterval ::= ENUMERATED {
+ ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240,
+ min1, min6, min12, min30, min60, spare3, spare2, spare1}
+
+
+RSRP-Range ::= INTEGER(0..97)
+
+
+RSRQ-Range ::= INTEGER(0..34)
+
+
+TimeToTrigger ::= ENUMERATED {
+ ms0, ms40, ms64, ms80, ms100, ms128, ms160, ms256,
+ ms320, ms480, ms512, ms640, ms1024, ms1280, ms2560,
+ ms5120}
+
+
+C-RNTI ::= BIT STRING (SIZE (16))
+
+
+DedicatedInfoCDMA2000 ::= OCTET STRING
+
+
+DedicatedInfoNAS ::= OCTET STRING
+
+
+FilterCoefficient ::= ENUMERATED {
+ fc0, fc1, fc2, fc3, fc4, fc5,
+ fc6, fc7, fc8, fc9, fc11, fc13,
+ fc15, fc17, fc19, spare1, ...}
+
+
+MMEC ::= BIT STRING (SIZE (8))
+
+
+NeighCellConfig ::= BIT STRING (SIZE (2))
+
+
+OtherConfig-r9 ::= SEQUENCE {
+ reportProximityConfig-r9 ReportProximityConfig-r9 OPTIONAL, -- Need ON
+ ...
+}
+
+ReportProximityConfig-r9 ::= SEQUENCE {
+ proximityIndicationEUTRA-r9 ENUMERATED {enabled} OPTIONAL, -- Need OR
+ proximityIndicationUTRA-r9 ENUMERATED {enabled} OPTIONAL -- Need OR
+}
+
+
+RAND-CDMA2000 ::= BIT STRING (SIZE (32))
+
+
+RAT-Type ::= ENUMERATED {
+ eutra, utra, geran-cs, geran-ps, cdma2000-1XRTT,
+ spare3, spare2, spare1, ...}
+
+
+RRC-TransactionIdentifier ::= INTEGER (0..3)
+
+
+S-TMSI ::= SEQUENCE {
+ mmec MMEC,
+ m-TMSI BIT STRING (SIZE (32))
+}
+
+
+UE-CapabilityRAT-ContainerList ::=SEQUENCE (SIZE (0..maxRAT-Capabilities)) OF UE-CapabilityRAT-Container
+
+UE-CapabilityRAT-Container ::= SEQUENCE {
+ rat-Type RAT-Type,
+ ueCapabilityRAT-Container OCTET STRING
+}
+
+
+UE-EUTRA-Capability ::= SEQUENCE {
+ accessStratumRelease AccessStratumRelease,
+ ue-Category INTEGER (1..5),
+ pdcp-Parameters PDCP-Parameters,
+ phyLayerParameters PhyLayerParameters,
+ rf-Parameters RF-Parameters,
+ measParameters MeasParameters,
+ featureGroupIndicators BIT STRING (SIZE (32)) OPTIONAL,
+ interRAT-Parameters SEQUENCE {
+ utraFDD IRAT-ParametersUTRA-FDD OPTIONAL,
+ utraTDD128 IRAT-ParametersUTRA-TDD128 OPTIONAL,
+ utraTDD384 IRAT-ParametersUTRA-TDD384 OPTIONAL,
+ utraTDD768 IRAT-ParametersUTRA-TDD768 OPTIONAL,
+ geran IRAT-ParametersGERAN OPTIONAL,
+ cdma2000-HRPD IRAT-ParametersCDMA2000-HRPD OPTIONAL,
+ cdma2000-1xRTT IRAT-ParametersCDMA2000-1XRTT OPTIONAL
+ },
+ nonCriticalExtension UE-EUTRA-Capability-v920-IEs OPTIONAL
+}
+
+UE-EUTRA-Capability-v920-IEs ::= SEQUENCE {
+ phyLayerParameters-v920 PhyLayerParameters-v920,
+ interRAT-ParametersGERAN-v920 IRAT-ParametersGERAN-v920,
+ interRAT-ParametersUTRA-v920 IRAT-ParametersUTRA-v920 OPTIONAL,
+ interRAT-Parameters-v920 IRAT-ParametersCDMA2000-1XRTT-v920 OPTIONAL,
+ deviceType-r9 ENUMERATED {noBenFromBatConsumpOpt} OPTIONAL,
+ csg-ProximityIndicationParameters-r9 CSG-ProximityIndicationParameters-r9,
+ neighCellSI-AcquisitionParameters-r9 NeighCellSI-AcquisitionParameters-r9,
+ son-Parameters-r9 SON-Parameters-r9,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+AccessStratumRelease ::= ENUMERATED {
+ rel8, rel9, spare6, spare5, spare4, spare3,
+ spare2, spare1, ...}
+
+PDCP-Parameters ::= SEQUENCE {
+ supportedROHC-Profiles SEQUENCE {
+ profile0x0001 BOOLEAN,
+ profile0x0002 BOOLEAN,
+ profile0x0003 BOOLEAN,
+ profile0x0004 BOOLEAN,
+ profile0x0006 BOOLEAN,
+ profile0x0101 BOOLEAN,
+ profile0x0102 BOOLEAN,
+ profile0x0103 BOOLEAN,
+ profile0x0104 BOOLEAN
+ },
+ maxNumberROHC-ContextSessions ENUMERATED {
+ cs2, cs4, cs8, cs12, cs16, cs24, cs32,
+ cs48, cs64, cs128, cs256, cs512, cs1024,
+ cs16384, spare2, spare1} DEFAULT cs16,
+ ...
+}
+
+PhyLayerParameters ::= SEQUENCE {
+ ue-TxAntennaSelectionSupported BOOLEAN,
+ ue-SpecificRefSigsSupported BOOLEAN
+}
+
+PhyLayerParameters-v920 ::= SEQUENCE {
+ enhancedDualLayerFDD-Supported-r9 BOOLEAN,
+ enhancedDualLayerTDD-Supported-r9 BOOLEAN
+}
+
+RF-Parameters ::= SEQUENCE {
+ supportedBandListEUTRA SupportedBandListEUTRA
+}
+
+SupportedBandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA
+
+SupportedBandEUTRA ::= SEQUENCE {
+ bandEUTRA INTEGER (1..64),
+ halfDuplex BOOLEAN
+}
+
+MeasParameters ::= SEQUENCE {
+ bandListEUTRA BandListEUTRA
+}
+
+BandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF BandInfoEUTRA
+
+BandInfoEUTRA ::= SEQUENCE {
+ interFreqBandList InterFreqBandList,
+ interRAT-BandList InterRAT-BandList OPTIONAL
+}
+
+InterFreqBandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterFreqBandInfo
+
+InterFreqBandInfo ::= SEQUENCE {
+ interFreqNeedForGaps BOOLEAN
+}
+
+InterRAT-BandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterRAT-BandInfo
+
+InterRAT-BandInfo ::= SEQUENCE {
+ interRAT-NeedForGaps BOOLEAN
+}
+
+IRAT-ParametersUTRA-FDD ::= SEQUENCE {
+ supportedBandListUTRA-FDD SupportedBandListUTRA-FDD
+}
+
+IRAT-ParametersUTRA-v920 ::= SEQUENCE {
+ e-Redirection-r9 ENUMERATED {supported}
+}
+
+SupportedBandListUTRA-FDD ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-FDD
+
+SupportedBandUTRA-FDD ::= ENUMERATED {
+ bandI, bandII, bandIII, bandIV, bandV, bandVI,
+ bandVII, bandVIII, bandIX, bandX, bandXI,
+ bandXII, bandXIII, bandXIV, bandXV, bandXVI, ...}
+
+IRAT-ParametersUTRA-TDD128 ::= SEQUENCE {
+ supportedBandListUTRA-TDD128 SupportedBandListUTRA-TDD128
+}
+
+SupportedBandListUTRA-TDD128 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD128
+
+SupportedBandUTRA-TDD128 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersUTRA-TDD384 ::= SEQUENCE {
+ supportedBandListUTRA-TDD384 SupportedBandListUTRA-TDD384
+}
+
+SupportedBandListUTRA-TDD384 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD384
+
+SupportedBandUTRA-TDD384 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersUTRA-TDD768 ::= SEQUENCE {
+ supportedBandListUTRA-TDD768 SupportedBandListUTRA-TDD768
+}
+
+SupportedBandListUTRA-TDD768 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD768
+
+SupportedBandUTRA-TDD768 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersGERAN ::= SEQUENCE {
+ supportedBandListGERAN SupportedBandListGERAN,
+ interRAT-PS-HO-ToGERAN BOOLEAN
+}
+
+IRAT-ParametersGERAN-v920 ::= SEQUENCE {
+ dtm-r9 ENUMERATED {supported} OPTIONAL,
+ e-RedirectionGERAN-r9 ENUMERATED {supported} OPTIONAL
+}
+
+SupportedBandListGERAN ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandGERAN
+
+SupportedBandGERAN ::= ENUMERATED {
+ gsm450, gsm480, gsm710, gsm750, gsm810, gsm850,
+ gsm900P, gsm900E, gsm900R, gsm1800, gsm1900,
+ spare5, spare4, spare3, spare2, spare1, ...}
+
+IRAT-ParametersCDMA2000-HRPD ::= SEQUENCE {
+ supportedBandListHRPD SupportedBandListHRPD,
+ tx-ConfigHRPD ENUMERATED {single, dual},
+ rx-ConfigHRPD ENUMERATED {single, dual}
+}
+
+SupportedBandListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000
+
+IRAT-ParametersCDMA2000-1XRTT ::= SEQUENCE {
+ supportedBandList1XRTT SupportedBandList1XRTT,
+ tx-Config1XRTT ENUMERATED {single, dual},
+ rx-Config1XRTT ENUMERATED {single, dual}
+}
+
+IRAT-ParametersCDMA2000-1XRTT-v920 ::= SEQUENCE {
+ e-CSFB-r9 ENUMERATED {supported},
+ e-CSFB-ConcPS-Mob-r9 ENUMERATED {notSupported, supported}
+}
+
+SupportedBandList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000
+
+CSG-ProximityIndicationParameters-r9 ::= SEQUENCE {
+ intraFreqProximityIndicationSupported-r9 BOOLEAN,
+ interFreqProximityIndicationSupported-r9 BOOLEAN,
+ utran-ProximityIndicationSupported-r9 BOOLEAN
+}
+
+NeighCellSI-AcquisitionParameters-r9 ::= SEQUENCE {
+ intraFreqSI-AcquisitionForHO-Supported-r9 BOOLEAN,
+ interFreqSI-AcquisitionForHO-Supported-r9 BOOLEAN,
+ utran-SI-AcquisitionForHO-Supported-r9 BOOLEAN
+}
+
+SON-Parameters-r9 ::= SEQUENCE {
+ rach-ReportSupported-r9 BOOLEAN
+}
+
+
+UE-TimersAndConstants ::= SEQUENCE {
+ t300 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t301 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t310 ENUMERATED {
+ ms0, ms50, ms100, ms200, ms500, ms1000, ms2000},
+ n310 ENUMERATED {
+ n1, n2, n3, n4, n6, n8, n10, n20},
+ t311 ENUMERATED {
+ ms1000, ms3000, ms5000, ms10000, ms15000,
+ ms20000, ms30000},
+ n311 ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n8, n10},
+ ...
+}
+
+
+MBMS-NotificationConfig-r9 ::= SEQUENCE {
+ notificationRepetitionCoeff-r9 ENUMERATED {n2, n4},
+ notificationOffset-r9 INTEGER (0..10),
+ notificationSF-Index-r9 INTEGER (1..6)
+}
+
+
+MBSFN-AreaInfoList-r9 ::= SEQUENCE (SIZE(1..maxMBSFN-Area)) OF MBSFN-AreaInfo-r9
+
+MBSFN-AreaInfo-r9 ::= SEQUENCE {
+ mbsfn-AreaId-r9 INTEGER (0..255),
+ non-MBSFNregionLength ENUMERATED {s1, s2},
+ notificationIndicator-r9 INTEGER (0..7),
+ mcch-Config-r9 SEQUENCE {
+ mcch-RepetitionPeriod-r9 ENUMERATED {rf32, rf64, rf128, rf256},
+ mcch-Offset-r9 INTEGER (0..10),
+ mcch-ModificationPeriod-r9 ENUMERATED {rf512, rf1024},
+ sf-AllocInfo-r9 BIT STRING (SIZE(6)),
+ signallingMCS-r9 ENUMERATED {n2, n7, n13, n19}
+ },
+ ...
+}
+
+
+MBSFN-SubframeConfig ::= SEQUENCE {
+ radioframeAllocationPeriod ENUMERATED {n1, n2, n4, n8, n16, n32},
+ radioframeAllocationOffset INTEGER (0..7),
+ subframeAllocation CHOICE {
+ oneFrame BIT STRING (SIZE(6)),
+ fourFrames BIT STRING (SIZE(24))
+ }
+}
+
+PMCH-InfoList-r9 ::= SEQUENCE (SIZE (0..maxPMCH-PerMBSFN)) OF PMCH-Info-r9
+
+PMCH-Info-r9 ::= SEQUENCE {
+ pmch-Config-r9 PMCH-Config-r9,
+ mbms-SessionInfoList-r9 MBMS-SessionInfoList-r9,
+ ...
+}
+
+MBMS-SessionInfoList-r9 ::= SEQUENCE (SIZE (0..maxSessionPerPMCH)) OF MBMS-SessionInfo-r9
+
+MBMS-SessionInfo-r9 ::= SEQUENCE {
+ tmgi-r9 TMGI-r9,
+ sessionId-r9 OCTET STRING (SIZE (1)) OPTIONAL, -- Need OR
+ logicalChannelIdentity-r9 INTEGER (0..maxSessionPerPMCH-1),
+ ...
+}
+
+PMCH-Config-r9 ::= SEQUENCE {
+ sf-AllocEnd-r9 INTEGER (0..1535),
+ dataMCS-r9 INTEGER (0..28),
+ mch-SchedulingPeriod-r9 ENUMERATED {
+ rf8, rf16, rf32, rf64, rf128, rf256, rf512, rf1024},
+ ...
+}
+
+TMGI-r9 ::= SEQUENCE {
+ plmn-Id-r9 CHOICE {
+ plmn-Index-r9 INTEGER (1..6),
+ explicitValue-r9 PLMN-Identity
+ },
+ serviceId-r9 OCTET STRING (SIZE (3))
+}
+
+
+maxBands INTEGER ::= 64 -- Maximum number of bands listed in EUTRA UE caps
+maxCDMA-BandClass INTEGER ::= 32 -- Maximum value of the CDMA band classes
+maxCellBlack INTEGER ::= 16 -- Maximum number of blacklisted cells
+ -- listed in SIB type 4 and 5
+maxCellInter INTEGER ::= 16 -- Maximum number of neighbouring inter-frequency
+ -- cells listed in SIB type 5
+maxCellIntra INTEGER ::= 16 -- Maximum number of neighbouring intra-frequency
+ -- cells listed in SIB type 4
+maxCellMeas INTEGER ::= 32 -- Maximum number of entries in each of the neighbour
+ -- cell lists in a measurement object
+maxCellReport INTEGER ::= 8 -- Maximum number of reported cells
+maxDRB INTEGER ::= 11 -- Maximum number of Data Radio Bearers
+maxEARFCN INTEGER ::= 65535 -- Maximum value of EUTRA carrier fequency
+maxFreq INTEGER ::= 8 -- Maximum number of EUTRA carrier frequencies
+maxCellInfo-GERAN-r9 INTEGER ::= 32 -- Maximum number of GERAN cells for which system in-
+ -- formation can be provided as redirection assistance
+maxGERAN-SI INTEGER ::= 10 -- Maximum number of GERAN SI blocks that can be
+ -- provided as part of NACC information
+maxGNFG INTEGER ::= 16 -- Maximum number of GERAN neighbour freq groups
+maxMBSFN-Allocations INTEGER ::= 8 -- Maximum number of MBSFN frame allocations with
+ -- different offset
+maxMBSFN-Area INTEGER ::= 8
+maxSessionPerPMCH INTEGER ::= 29
+maxSessionPerPMCH-1 INTEGER ::= 28
+maxPMCH-PerMBSFN INTEGER ::= 15
+maxMeasId INTEGER ::= 32
+maxObjectId INTEGER ::= 32
+maxPageRec INTEGER ::= 16 --
+maxPNOffset INTEGER ::= 511 -- Maximum number of CDMA2000 PNOffsets
+maxRAT-Capabilities INTEGER ::= 8 -- Maximum number of interworking RATs (incl EUTRA)
+maxReportConfigId INTEGER ::= 32
+maxSIB INTEGER ::= 32 -- Maximum number of SIBs
+maxSIB-1 INTEGER ::= 31
+maxSI-Message INTEGER ::= 32 -- Maximum number of SI messages
+maxUTRA-FDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA FDD carrier frequencies
+maxUTRA-TDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA TDD carrier frequencies
+maxUTRA-CellInfo-r9 INTEGER ::= 16 -- Maximum number of cells for which system information
+ -- can be provided as redirection assistance
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn index b985c970ac..fc244c30a2 100644 --- a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn +++ b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn @@ -48,6 +48,7 @@ Ax ::= SEQUENCE { } -- valAx Ax ::= { a 253, b TRUE, c e: TRUE, g "123", h TRUE } + Ax2 ::= SEQUENCE { a INTEGER (250..253), b BOOLEAN, @@ -55,7 +56,6 @@ Ax2 ::= SEQUENCE { ug NumericString } -END -- The value { a 253, b TRUE, c e: TRUE, g "123", h TRUE } -- is encoded in PER as @@ -64,3 +64,19 @@ END -- is encoded in Unaligned PER as -- 9E000600 040A4690 + +Ax3 ::= SEQUENCE { + a INTEGER (250..253), + b BOOLEAN, + s SEQUENCE { + sa INTEGER, + sb BOOLEAN, + ..., + [[ + sextaddgroup INTEGER OPTIONAL + ]] + } +} + +-- { a 253, b TRUE, s {sa 17, sb TRUE, sextaddgroup 11}} +END diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl index 79e200f561..1cf2eb4088 100644 --- a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl +++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl @@ -41,3 +41,91 @@ run(Erule) -> Val -> ok; _ -> exit({expected,Val, got, Val2}) end. + +run2(Erule) -> + Val = #'Ax3'{a=253, b = true, s = #'Ax3_s'{sa = 11, sb = true, sextaddgroup = 17}}, + io:format("~p:~p~n",[Erule,Val]), + {ok,List}= asn1rt:encode('Extension-Addition-Group','Ax3',Val), + Enc = iolist_to_binary(List), + io:format("~p~n",[Enc]), + {ok,Val2} = asn1rt:decode('Extension-Addition-Group','Ax3',Enc), + io:format("~p~n",[Val2]), + case Val2 of + Val -> ok; + _ -> exit({expected,Val, got, Val2}) + end. + +run3(Erule) -> + Val = +{'RRC-DL-DCCH-Message', + {c1, + {rrcConnectionReconfiguration, + {'RRC-RRCConnectionReconfiguration',0, + {c1, + {'rrcConnectionReconfiguration-r8', + {'RRC-RRCConnectionReconfiguration-r8-IEs', + {'RRC-MeasConfig',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE, + asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE, + asn1_NOVALUE,asn1_NOVALUE}, + asn1_NOVALUE, + [[80,66,0,5,10,0,5,0,24,11,7,84,54,33,0,1,1,0,0,0,1,39,5,66,127,0,0,1], + []], + {'RRC-RadioResourceConfigDedicated', + [{'RRC-SRB-ToAddMod',1, + {explicitValue, + {am, + {'RRC-RLC-Config_am', + {'RRC-UL-AM-RLC',ms45,pInfinity,kBinfinity,t4}, + {'RRC-DL-AM-RLC',ms35,ms0}}}}, + {explicitValue, + {'RRC-LogicalChannelConfig', + {'RRC-LogicalChannelConfig_ul-SpecificParameters',3,infinity, + ms50,0}, + asn1_NOVALUE}}}], + [{'RRC-DRB-ToAddMod',3,3, + {'RRC-PDCP-Config',infinity, + {'RRC-PDCP-Config_rlc-AM',false}, + asn1_NOVALUE, + {notUsed,'NULL'}}, + {am, + {'RRC-RLC-Config_am', + {'RRC-UL-AM-RLC',ms70,p256,kBinfinity,t4}, + {'RRC-DL-AM-RLC',ms35,ms40}}}, + 3, + {'RRC-LogicalChannelConfig', + {'RRC-LogicalChannelConfig_ul-SpecificParameters',5,infinity,ms50, + 1}, + asn1_NOVALUE}}, + {'RRC-DRB-ToAddMod',4,4, + {'RRC-PDCP-Config',infinity, + {'RRC-PDCP-Config_rlc-AM',false}, + asn1_NOVALUE, + {notUsed,'NULL'}}, + {am, + {'RRC-RLC-Config_am', + {'RRC-UL-AM-RLC',ms70,p256,kBinfinity,t4}, + {'RRC-DL-AM-RLC',ms35,ms40}}}, + 4, + {'RRC-LogicalChannelConfig', + {'RRC-LogicalChannelConfig_ul-SpecificParameters',5,infinity,ms50, + 1}, + asn1_NOVALUE}}], + asn1_NOVALUE, + {explicitValue, + {'RRC-MAC-MainConfig', + {'RRC-MAC-MainConfig_ul-SCH-Config',n4,sf10,sf10240,false}, + asn1_NOVALUE,sf500, + {setup,{'RRC-MAC-MainConfig_phr-Config_setup',sf200,sf200,dB3}}, + asn1_NOVALUE}}, + asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}, + asn1_NOVALUE,asn1_NOVALUE}}}}}}}, + io:format("~p:~p~n",[Erule,Val]), + {ok,List}= asn1rt:encode('EUTRA-RRC-Definitions','DL-DCCH-Message',Val), + Enc = iolist_to_binary(List), + io:format("Result from encode:~n~p~n",[Enc]), + {ok,Val2} = asn1rt:decode('EUTRA-RRC-Definitions','DL-DCCH-Message',Enc), + io:format("Result from decode:~n~p~n",[Val2]), + case Val2 of + Val -> ok; + _ -> exit({expected,Val, got, Val2}) + end. diff --git a/lib/asn1/test/asn1_app_test.erl b/lib/asn1/test/asn1_app_test.erl index 8ee42d3ec3..1ea76426f1 100644 --- a/lib/asn1/test/asn1_app_test.erl +++ b/lib/asn1/test/asn1_app_test.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2005-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -54,7 +54,7 @@ all(suite) -> app_init(suite) -> []; app_init(doc) -> []; -app_init(Config) when list(Config) -> +app_init(Config) when is_list(Config) -> case is_app(asn1) of {ok, AppFile} -> io:format("AppFile: ~n~p~n", [AppFile]), @@ -76,7 +76,7 @@ is_app(App) -> app_fin(suite) -> []; app_fin(doc) -> []; -app_fin(Config) when list(Config) -> +app_fin(Config) when is_list(Config) -> Config. @@ -86,7 +86,7 @@ fields(suite) -> []; fields(doc) -> []; -fields(Config) when list(Config) -> +fields(Config) when is_list(Config) -> AppFile = key1search(app_file, Config), Fields = [vsn, description, modules, registered, applications], case check_fields(Fields, AppFile, []) of @@ -117,7 +117,7 @@ modules(suite) -> []; modules(doc) -> []; -modules(Config) when list(Config) -> +modules(Config) when is_list(Config) -> AppFile = key1search(app_file, Config), Mods = key1search(modules, AppFile), EbinList = get_ebin_mods(asn1), @@ -188,7 +188,7 @@ exportall(suite) -> []; exportall(doc) -> []; -exportall(Config) when list(Config) -> +exportall(Config) when is_list(Config) -> AppFile = key1search(app_file, Config), Mods = key1search(modules, AppFile), check_export_all(Mods). @@ -221,7 +221,7 @@ app_depend(suite) -> []; app_depend(doc) -> []; -app_depend(Config) when list(Config) -> +app_depend(Config) when is_list(Config) -> AppFile = key1search(app_file, Config), Apps = key1search(applications, AppFile), check_apps(Apps). diff --git a/lib/asn1/test/asn1_appup_test.erl b/lib/asn1/test/asn1_appup_test.erl index 644c0f7d03..96197ed963 100644 --- a/lib/asn1/test/asn1_appup_test.erl +++ b/lib/asn1/test/asn1_appup_test.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2005-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -51,7 +51,7 @@ all(suite) -> appup_init(suite) -> []; appup_init(doc) -> []; -appup_init(Config) when list(Config) -> +appup_init(Config) when is_list(Config) -> AppFile = file_name(asn1, ".app"), AppupFile = file_name(asn1, ".appup"), [{app_file, AppFile}, {appup_file, AppupFile}|Config]. @@ -64,7 +64,7 @@ file_name(App, Ext) -> appup_fin(suite) -> []; appup_fin(doc) -> []; -appup_fin(Config) when list(Config) -> +appup_fin(Config) when is_list(Config) -> Config. @@ -74,7 +74,7 @@ appup(suite) -> []; appup(doc) -> "perform a simple check of the appup file"; -appup(Config) when list(Config) -> +appup(Config) when is_list(Config) -> AppupFile = key1search(appup_file, Config), AppFile = key1search(app_file, Config), Modules = modules(AppFile), @@ -161,14 +161,14 @@ check_instructions(UpDown, [Instr|Instrs], AllInstr, Good, Bad, Modules) -> %% A new module is added check_instruction(up, {add_module, Module}, _, Modules) - when atom(Module) -> + when is_atom(Module) -> d("check_instruction -> entry when up-add_module instruction with" "~n Module: ~p", [Module]), check_module(Module, Modules); %% An old module is re-added check_instruction(down, {add_module, Module}, _, Modules) - when atom(Module) -> + when is_atom(Module) -> d("check_instruction -> entry when down-add_module instruction with" "~n Module: ~p", [Module]), case (catch check_module(Module, Modules)) of @@ -182,7 +182,7 @@ check_instruction(down, {add_module, Module}, _, Modules) %% - the module has been removed from the app-file. %% - check that no module depends on this (removed) module check_instruction(up, {remove, {Module, Pre, Post}}, _, Modules) - when atom(Module), atom(Pre), atom(Post) -> + when is_atom(Module), is_atom(Pre), is_atom(Post) -> d("check_instruction -> entry when up-remove instruction with" "~n Module: ~p" "~n Pre: ~p" @@ -198,7 +198,7 @@ check_instruction(up, {remove, {Module, Pre, Post}}, _, Modules) %% Removing a module on downgrade: the module exist %% in the app-file. check_instruction(down, {remove, {Module, Pre, Post}}, AllInstr, Modules) - when atom(Module), atom(Pre), atom(Post) -> + when is_atom(Module), is_atom(Pre), is_atom(Post) -> d("check_instruction -> entry when down-remove instruction with" "~n Module: ~p" "~n Pre: ~p" @@ -214,7 +214,7 @@ check_instruction(down, {remove, {Module, Pre, Post}}, AllInstr, Modules) check_instruction(_, {load_module, Module, Pre, Post, Depend}, AllInstr, Modules) - when atom(Module), atom(Pre), atom(Post), list(Depend) -> + when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) -> d("check_instruction -> entry when load_module instruction with" "~n Module: ~p" "~n Pre: ~p" @@ -228,7 +228,7 @@ check_instruction(_, {load_module, Module, Pre, Post, Depend}, check_instruction(_, {update, Module, Change, Pre, Post, Depend}, AllInstr, Modules) - when atom(Module), atom(Pre), atom(Post), list(Depend) -> + when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) -> d("check_instruction -> entry when update instruction with" "~n Module: ~p" "~n Change: ~p" @@ -244,7 +244,7 @@ check_instruction(_, {update, Module, Change, Pre, Post, Depend}, check_instruction(_, {apply, {Module, Function, Args}}, _AllInstr, Modules) - when atom(Module), atom(Function), list(Args) -> + when is_atom(Module), is_atom(Function), is_list(Args) -> d("check_instruction -> entry when apply instruction with" "~n Module: ~p" "~n Function: ~p" @@ -289,13 +289,13 @@ instruction_module(Instr) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -check_version(V) when list(V) -> +check_version(V) when is_list(V) -> ok; check_version(V) -> error({bad_version, V}). -check_module(M, Modules) when atom(M) -> +check_module(M, Modules) when is_atom(M) -> case lists:member(M,Modules) of true -> ok; @@ -307,7 +307,7 @@ check_module(M, _) -> check_apply(Module,Function,Args) -> case (catch Module:module_info()) of - Info when list(Info) -> + Info when is_list(Info) -> check_exported(Function,Args,Info); {'EXIT',{undef,_}} -> error({not_existing_module,Module}) @@ -326,11 +326,11 @@ check_exported(Function,Args,Info) -> error({bad_export,Info}) end. -check_module_depend(M, [], _) when atom(M) -> +check_module_depend(M, [], _) when is_atom(M) -> d("check_module_depend -> entry with" "~n M: ~p", [M]), ok; -check_module_depend(M, Deps, Modules) when atom(M), list(Deps) -> +check_module_depend(M, Deps, Modules) when is_atom(M), is_list(Deps) -> d("check_module_depend -> entry with" "~n M: ~p" "~n Deps: ~p" diff --git a/lib/asn1/test/asn1_wrapper.erl b/lib/asn1/test/asn1_wrapper.erl index 553f0b062c..d515b99ac2 100644 --- a/lib/asn1/test/asn1_wrapper.erl +++ b/lib/asn1/test/asn1_wrapper.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2001-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -26,7 +26,7 @@ encode(Module,Type,Value) -> case asn1rt:encode(Module,Type,Value) of - {ok,X} when binary(X) -> + {ok,X} when is_binary(X) -> {ok, binary_to_list(X)}; {ok,X} -> {ok, binary_to_list(list_to_binary(X))}; @@ -38,21 +38,21 @@ decode(Module,Type,Bytes) -> case Module:encoding_rule() of ber -> asn1rt:decode(Module,Type,Bytes); - ber_bin when binary(Bytes) -> + ber_bin when is_binary(Bytes) -> asn1rt:decode(Module,Type,Bytes); ber_bin -> asn1rt:decode(Module,Type,list_to_binary(Bytes)); - ber_bin_v2 when binary(Bytes) -> + ber_bin_v2 when is_binary(Bytes) -> asn1rt:decode(Module,Type,Bytes); ber_bin_v2 -> asn1rt:decode(Module,Type,list_to_binary(Bytes)); per -> asn1rt:decode(Module,Type,Bytes); - per_bin when binary(Bytes) -> + per_bin when is_binary(Bytes) -> asn1rt:decode(Module,Type,Bytes); per_bin -> asn1rt:decode(Module,Type,list_to_binary(Bytes)); - uper_bin when binary(Bytes) -> + uper_bin when is_binary(Bytes) -> asn1rt:decode(Module,Type,Bytes); uper_bin -> asn1rt:decode(Module,Type,list_to_binary(Bytes)) diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl index ef14397d1e..399c9ecaf7 100644 --- a/lib/asn1/test/testContextSwitchingTypes.erl +++ b/lib/asn1/test/testContextSwitchingTypes.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2001-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -71,13 +71,13 @@ check_EXTERNAL_Idef({Alt,_}) when Alt=='context-negotiation'; ok; check_EXTERNAL_Idef(I) -> {error,"failed on identification alternative",I}. -check_EXTERNAL_DVD(DVD) when list(DVD) -> +check_EXTERNAL_DVD(DVD) when is_list(DVD) -> ok; check_EXTERNAL_DVD(asn1_NOVALUE) -> ok; check_EXTERNAL_DVD(DVD) -> {error,"failed on data-value-descriptor alternative",DVD}. -check_EXTERNAL_DV(DV) when list(DV) -> +check_EXTERNAL_DV(DV) when is_list(DV) -> ok; check_EXTERNAL_DV(DV) -> {error,"failed on data-value alternative",DV}. diff --git a/lib/asn1/test/testINSTANCE_OF.erl b/lib/asn1/test/testINSTANCE_OF.erl index 2a3a5c333b..7f5b634e06 100644 --- a/lib/asn1/test/testINSTANCE_OF.erl +++ b/lib/asn1/test/testINSTANCE_OF.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2003-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2003-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -73,17 +73,17 @@ test_encdec(_Erule,{lastName,{'GeneralName_lastName',{2,3,4}, test_encdec(Erule,Res) -> {error,{Erule,Res}}. -wrap(ber,Int) when list(Int) -> +wrap(ber,Int) when is_list(Int) -> binary_to_list(list_to_binary(Int)); -wrap(per,Int) when list(Int) -> +wrap(per,Int) when is_list(Int) -> binary_to_list(list_to_binary(Int)); -wrap(ber_bin,Int) when list(Int) -> +wrap(ber_bin,Int) when is_list(Int) -> list_to_binary(Int); -wrap(ber_bin_v2,Int) when list(Int) -> +wrap(ber_bin_v2,Int) when is_list(Int) -> list_to_binary(Int); -wrap(per_bin,Int) when list(Int) -> +wrap(per_bin,Int) when is_list(Int) -> list_to_binary(Int); -wrap(uper_bin,Int) when list(Int) -> +wrap(uper_bin,Int) when is_list(Int) -> list_to_binary(Int); wrap(_,Int) -> Int. diff --git a/lib/asn1/test/testMegaco.erl b/lib/asn1/test/testMegaco.erl index 8c0565eec7..50bc6e7dee 100644 --- a/lib/asn1/test/testMegaco.erl +++ b/lib/asn1/test/testMegaco.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2001-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -163,7 +163,7 @@ read_msg(File) -> end. -request(Mid, TransId, ContextId, CmdReq) when list(CmdReq) -> +request(Mid, TransId, ContextId, CmdReq) when is_list(CmdReq) -> Actions = [#'ActionRequest'{contextId = ContextId, commandRequests = CmdReq}], Req = {transactions, diff --git a/lib/asn1/test/testNBAPsystem.erl b/lib/asn1/test/testNBAPsystem.erl index 402f16ab5d..79e553a596 100644 --- a/lib/asn1/test/testNBAPsystem.erl +++ b/lib/asn1/test/testNBAPsystem.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2005-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -299,7 +299,7 @@ protocolIEs_051107() -> compare(V,V) -> ok; -compare(V,L) when list(L) -> +compare(V,L) when is_list(L) -> compare(V,list_to_binary(L)); compare(_,_) -> false. diff --git a/lib/asn1/test/testPrimStrings.erl b/lib/asn1/test/testPrimStrings.erl index 707ee375c1..a2252ba99b 100644 --- a/lib/asn1/test/testPrimStrings.erl +++ b/lib/asn1/test/testPrimStrings.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -930,7 +930,7 @@ utf8_string(_Rules) -> ?line {ok,Bin13} = asn1_wrapper:decode('PrimStrings','UTF',Bytes13), ?line {ok,LongVal} = wrapper_utf8_binary_to_list(Bin13). -wrapper_utf8_binary_to_list(L) when list(L) -> +wrapper_utf8_binary_to_list(L) when is_list(L) -> asn1rt:utf8_binary_to_list(list_to_binary(L)); wrapper_utf8_binary_to_list(B) -> asn1rt:utf8_binary_to_list(B). diff --git a/lib/asn1/test/testTimer.erl b/lib/asn1/test/testTimer.erl index 0fade7ebca..34b9cf1740 100644 --- a/lib/asn1/test/testTimer.erl +++ b/lib/asn1/test/testTimer.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2001-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -146,7 +146,7 @@ go(Config,Enc) -> Bytes = case Enc of ber_bin -> list_to_binary(B); - per_bin when list(B) -> + per_bin when is_list(B) -> list_to_binary(B); per_bin -> B; @@ -179,7 +179,7 @@ encode(0, _Module,_Type,_Value) -> encode(N, Module,Type,Value) -> ?line {ok,B} = asn1rt:encode(Module,Type,Value), _B2 = if - list(B) -> list_to_binary(B); + is_list(B) -> list_to_binary(B); true -> B end, encode(N-1, Module,Type,Value). diff --git a/lib/asn1/test/testX420.erl b/lib/asn1/test/testX420.erl index 0fa3e6fb13..314c5c837a 100644 --- a/lib/asn1/test/testX420.erl +++ b/lib/asn1/test/testX420.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -50,7 +50,7 @@ compile_loop(Erule,[Spec|Specs],Options,Config) Error -> Error end; -compile_loop(Erule,_Specs,_Options,_Config) -> +compile_loop(_Erule,_Specs,_Options,_Config) -> ok.%%{skip,io_lib:format("Not tested for ~p",[Erule])}. diff --git a/lib/asn1/test/test_undecoded_rest.erl b/lib/asn1/test/test_undecoded_rest.erl index c7762d28f7..d2c98e130d 100644 --- a/lib/asn1/test/test_undecoded_rest.erl +++ b/lib/asn1/test/test_undecoded_rest.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -39,10 +39,10 @@ test(Opt) -> ?line {ok,Msg} = asn1ct:value('P-Record','PersonnelRecord'), ?line {ok,Bytes} = asn1_wrapper:encode('P-Record','PersonnelRecord',Msg), Bytes2 = - fun(B) when list(B) -> + fun(B) when is_list(B) -> B ++ [55,55,55]; - (B) when binary(B) -> - concat_binary([B,<<55,55,55>>]) + (B) when is_binary(B) -> + erlang:list_to_binary([B,<<55,55,55>>]) end (Bytes), case Opt of diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk index dc89027de4..20ee8ac6ff 100644 --- a/lib/asn1/vsn.mk +++ b/lib/asn1/vsn.mk @@ -1,5 +1,5 @@ #next version number to use is 1.6.14 | 1.7 | 2.0 -ASN1_VSN = 1.6.13.1 +ASN1_VSN = 1.6.13.2 TICKETS = OTP-8463 diff --git a/lib/cosEvent/test/Makefile b/lib/cosEvent/test/Makefile new file mode 100644 index 0000000000..3d95075ee1 --- /dev/null +++ b/lib/cosEvent/test/Makefile @@ -0,0 +1,154 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1999-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSEVENT_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/cosEvent_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = cosEvent.spec + + +IDL_FILES = \ + event_test_server.idl \ + +IDLOUTDIR = idl_output + +MODULES = \ + event_test_PushC_impl \ + event_test_PullC_impl \ + event_test_PushS_impl \ + event_test_PullS_impl \ + event_channel_SUITE \ + generated_SUITE + +GEN_MOD_COS = \ + event_test_PullC \ + event_test_PushS \ + event_test_PullS \ + oe_event_test_server \ + event_test_PushC + +GEN_HRL_COS = \ + event_test.hrl \ + event_test_PushC.hrl \ + event_test_PullC.hrl \ + event_test_PushS.hrl \ + event_test_PullS.hrl \ + oe_event_test_server.hrl + + +GEN_MODULES = $(GEN_MOD_COS) + +ERL_FILES = $(MODULES:%=%.erl) + +HRL_FILES = + +GEN_HRL_FILES = $(GEN_HRL_COS) + +GEN_FILES = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl) + +GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR)) + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(GEN_TARGET_FILES) \ + $(SUITE_TARGET_FILES) + +# ---------------------------------------------------- +# PROGRAMS +# ---------------------------------------------------- +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/orber/ebin -pa $(ERL_TOP)/lib/ic/ebin + +ERL_COMPILE_FLAGS += $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/test_server/ebin \ + -pa $(ERL_TOP)/lib/cosEvent/ebin \ + -pa $(ERL_TOP)/lib/cosEvent/test/idl_output \ + -I$(ERL_TOP)/lib/cosEvent \ + -I$(ERL_TOP)/lib/cosEvent/test/$(IDLOUTDIR) \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +tests debug opt: $(TARGET_FILES) + +clean: + rm -f idl_output/* + rm -rf java_initial_reference_idl java_cos_naming_idl + rm -rf java_iiop_module_idl java_output/* + rm -f $(TARGET_FILES) + rm -f errs core *~ + + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + +# +# Each IDL file produces many target files so no pattern +# rule can be used. +# +TGT_COS = \ + $(GEN_HRL_COS:%=$(IDLOUTDIR)/%) \ + $(GEN_MOD_COS:%=$(IDLOUTDIR)/%.erl) + + +$(TGT_COS): event_test_server.idl + erlc $(ERL_IDL_FLAGS) -o$(IDLOUTDIR) event_test_server.idl + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +# We don't copy generated intermediate erlang and hrl files + +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ + $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) + $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ + $(RELSYSDIR)/$(IDLOUTDIR) + diff --git a/lib/cosEvent/test/cosEvent.spec b/lib/cosEvent/test/cosEvent.spec new file mode 100644 index 0000000000..910f7a7c28 --- /dev/null +++ b/lib/cosEvent/test/cosEvent.spec @@ -0,0 +1,19 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +{topcase, {dir, "../cosEvent_test"}}. diff --git a/lib/cosEvent/test/event_channel_SUITE.erl b/lib/cosEvent/test/event_channel_SUITE.erl new file mode 100644 index 0000000000..2b0cf1fe30 --- /dev/null +++ b/lib/cosEvent/test/event_channel_SUITE.erl @@ -0,0 +1,316 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- + +-module(event_channel_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +%%----------------------------------------------------------------- +%% Macros +%%----------------------------------------------------------------- + +-define(default_timeout, ?t:minutes(5)). + + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, event_objects_api/1, events_api/1, events_sync_api/1, + cases/0, init_all/1, finish_all/1, + init_per_testcase/2, fin_per_testcase/2, app_test/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- + +all(doc) -> ["API tests for the cosEvent interfaces", ""]; +all(suite) -> {req, + [mnesia, orber], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [events_api, events_sync_api, event_objects_api, app_test]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + orber:install([node()]), + application:start(mnesia), + application:start(orber), + cosEventApp:install(), + cosEventApp:start(), + oe_event_test_server:oe_register(), + Config. + +finish_all(Config) when is_list(Config) -> + oe_event_test_server:oe_unregister(), + cosEventApp:stop(), + cosEventApp:uninstall(), + application:stop(orber), + application:stop(mnesia), + mnesia:delete_schema([node()]), + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Config. + +%%----------------------------------------------------------------- +%% Tests app file +%%----------------------------------------------------------------- +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ok=test_server:app_test(cosEvent), + ok. + + + +event_objects_api(doc) -> ["Testing the CosEvent API to setup a complete service", ""]; +event_objects_api(suite) -> []; +event_objects_api(_Config) -> + + Ch = ?match({_,key,_,_,_,_}, cosEventApp:start_channel([{typecheck, true}, + {pull_interval, 300}])), + + AC=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_EventChannel':for_consumers(Ch)), + AS=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_EventChannel':for_suppliers(Ch)), + + PPushS=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_ConsumerAdmin':obtain_push_supplier(AC)), + PPullS=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_ConsumerAdmin':obtain_pull_supplier(AC)), + + PPushC=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_SupplierAdmin':obtain_push_consumer(AS)), + PPullC=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_SupplierAdmin':obtain_pull_consumer(AS)), + + PushC=?match({_,key,_,_,_,_}, + 'event_test_PushC':oe_create([])), + PullC=?match({_,key,_,_,_,_}, + 'event_test_PullC':oe_create(PPullC)), + + PushS=?match({_,key,_,_,_,_}, + 'event_test_PushS':oe_create(PPushC)), + + PullS=?match({_,key,_,_,_,_}, + 'event_test_PullS':oe_create([])), + + NIL = corba:create_nil_objref(), + + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, + 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPushS, NIL)), + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, + 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPushS, PullS)), + ?match(ok, 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPushS, PushC)), + ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}}, + 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPushS, PushC)), + + ?match(ok, 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PPullS, NIL)), + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, + 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PPullS, PullS)), + ?match(ok, 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PPullS, PullC)), + ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}}, + 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PPullS, PullC)), + + ?match(ok, 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPushC, NIL)), + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, + 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPushC, PullS)), + ?match(ok, 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPushC, PushS)), + ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}}, + 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPushC, PushS)), + + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, + 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PPullC, NIL)), + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, + 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PPullC, PushS)), + ?match(ok, 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PPullC, PullS)), + ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}}, + 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PPullC, PullS)), + + + catch corba:dispose(AC), + %% Wait a couple of seconds to be sure all data removed from DB. + timer:sleep(2000), + + %% Since we terminated ConsumerAdmin only the Supplier Proxies should be terminated. + ?match(true, corba_object:non_existent(AC)), + ?match(true, corba_object:non_existent(PPushS)), + ?match(true, corba_object:non_existent(PPullS)), + + ?match(false, corba_object:non_existent(Ch)), + ?match(false, corba_object:non_existent(AS)), + ?match(false, corba_object:non_existent(PPullC)), + ?match(false, corba_object:non_existent(PPushC)), + + %% Terminate a proxy and check that its admin is unaffected. + catch corba:dispose(PPullC), + timer:sleep(2000), + ?match(false, corba_object:non_existent(AS)), + ?match(true, corba_object:non_existent(PPullC)), + + catch corba:dispose(Ch), + timer:sleep(2000), + + ?match(true, corba_object:non_existent(Ch)), + ?match(true, corba_object:non_existent(AS)), + ?match(true, corba_object:non_existent(PPullC)), + ?match(true, corba_object:non_existent(PPushC)), + + %% The client should be notified; wait for a couple of seconds and check it. + timer:sleep(2000), + ?match(true, corba_object:non_existent(PushC)), + ?match(true, corba_object:non_existent(PullC)), + ?match(true, corba_object:non_existent(PushS)), + ?match(true, corba_object:non_existent(PullS)), + + ok. + +events_api(doc) -> ["Testing the CosEvent API for sending events asynchronous", ""]; +events_api(suite) -> []; +events_api(_Config) -> + + Ch = ?match({_,key,_,_,_,_}, cosEventApp:start_channel([{typecheck, true}, + {pull_interval, 2}, + {blocking, false}])), + event_sender(Ch). + + +events_sync_api(doc) -> ["Testing the CosEvent API for sending events synchronous", ""]; +events_sync_api(suite) -> []; +events_sync_api(_Config) -> + + Ch = ?match({_,key,_,_,_,_}, cosEventApp:start_channel([{typecheck, true}, + {pull_interval, 2}, + {blocking, true}])), + event_sender(Ch). + +event_sender(Ch) -> + Event1 = #any{typecode=tk_long, value = 1}, + Event2 = #any{typecode=tk_long, value = 2}, + Event3 = #any{typecode=tk_long, value = 3}, + Event4 = #any{typecode=tk_long, value = 4}, + Event5 = #any{typecode=tk_long, value = 5}, + Event6 = #any{typecode=tk_long, value = 6}, + + AC=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_EventChannel':for_consumers(Ch)), + AS=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_EventChannel':for_suppliers(Ch)), + + PPushS=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_ConsumerAdmin':obtain_push_supplier(AC)), + PPullS=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_ConsumerAdmin':obtain_pull_supplier(AC)), + + PPushC=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_SupplierAdmin':obtain_push_consumer(AS)), + PPullC=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_SupplierAdmin':obtain_pull_consumer(AS)), + + PushC=?match({_,key,_,_,_,_}, 'event_test_PushC':oe_create([])), + PullC=?match({_,key,_,_,_,_}, 'event_test_PullC':oe_create(PPullS)), + + PushS=?match({_,key,_,_,_,_}, 'event_test_PushS':oe_create(PPushC)), + + PullS=?match({_,key,_,_,_,_}, 'event_test_PullS':oe_create([])), + + ?match(ok, 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPushS, PushC)), + ?match(ok, 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PPullS, PullC)), + ?match(ok, 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPushC, PushS)), + ?match(ok, 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PPullC, PullS)), + + %% No events should be available at the consumer side at this point. + ?match({_, false}, event_test_PullC:do_try_pull(PullC)), + ?match([], event_test_PushC:get_data(PushC)), + + %% Push an event and wait to be sure it have reached the destination. + ?match(ok, event_test_PushS:do_push(PushS, Event1)), + ?match(ok, event_test_PushS:do_push(PushS, Event2)), + ?match(ok, event_test_PushS:do_push(PushS, Event3)), + timer:sleep(2000), + ?match({Event1, true}, event_test_PullC:do_try_pull(PullC)), + ?match({Event2, true}, event_test_PullC:do_try_pull(PullC)), + ?match({Event3, true}, event_test_PullC:do_try_pull(PullC)), + ?match({_, false}, event_test_PullC:do_try_pull(PullC)), + ?match([Event1, Event2, Event3], event_test_PushC:get_data(PushC)), + + ?match(ok, event_test_PullS:add_event(PullS, Event4)), + ?match(ok, event_test_PullS:add_event(PullS, Event5)), + ?match(ok, event_test_PullS:add_event(PullS, Event6)), + + %% Since the pull operation is blocking we do not need to "sleep". + %% The ProxyPullConsumer will pull for events according to the pull_interval + %% parameter given when started the channel. + ?match(Event4, event_test_PullC:do_pull(PullC)), + ?match(Event5, event_test_PullC:do_pull(PullC)), + ?match(Event6, event_test_PullC:do_pull(PullC)), + + timer:sleep(2000), + ?match([Event4, Event5, Event6], event_test_PushC:get_data(PushC)), + + + catch corba:dispose(Ch), + %% The client should be notified; wait for a couple of seconds and check it. + timer:sleep(2000), + ?match(true, corba_object:non_existent(PushC)), + ?match(true, corba_object:non_existent(PullC)), + ?match(true, corba_object:non_existent(PushS)), + ?match(true, corba_object:non_existent(PullS)), + + ok. diff --git a/lib/cosEvent/test/event_test_PullC_impl.erl b/lib/cosEvent/test/event_test_PullC_impl.erl new file mode 100644 index 0000000000..186d1cbd51 --- /dev/null +++ b/lib/cosEvent/test/event_test_PullC_impl.erl @@ -0,0 +1,43 @@ +%%------------------------------------------------------------------------ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%------------------------------------------------------------------------ +%% Description: a very simple implementation of PullConsumer interface +%%------------------------------------------------------------------------ +-module(event_test_PullC_impl). + +-export([init/1, terminate/2, disconnect_pull_consumer/1, do_pull/1, do_try_pull/1]). + +init(Proxy) -> + {ok, Proxy}. + +terminate(_From, _Reason) -> + ok. + +disconnect_pull_consumer(Proxy) -> + io:format("event_test_PullC terminates~n",[]), + {stop, normal, ok, Proxy}. + +do_pull(Proxy) -> + {reply, 'CosEventComm_PullSupplier':pull(Proxy), Proxy}. + +do_try_pull(Proxy) -> + {reply, 'CosEventComm_PullSupplier':try_pull(Proxy), Proxy}. + diff --git a/lib/cosEvent/test/event_test_PullS_impl.erl b/lib/cosEvent/test/event_test_PullS_impl.erl new file mode 100644 index 0000000000..b7fa0c34f0 --- /dev/null +++ b/lib/cosEvent/test/event_test_PullS_impl.erl @@ -0,0 +1,57 @@ +%%------------------------------------------------------------------------ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%------------------------------------------------------------------------ +%% Description: a very simple implementation of Pull Supplier interface +%%------------------------------------------------------------------------ +-module(event_test_PullS_impl). + +-include_lib("orber/include/corba.hrl"). + +-export([init/1, terminate/2, pull/1, try_pull/1, disconnect_pull_supplier/1, + add_event/2]). + +init(_) -> + {ok, []}. + +terminate(_From, _Reason) -> + ok. + +pull([]) -> + corba:raise(#'INTERNAL'{completion_status = ?COMPLETED_NO}); +pull([Event|Events]) -> + {reply, Event, Events}. + +try_pull([]) -> + {reply, {#any{typecode=tk_null, value = null}, false}, []}; +try_pull([Event|Events]) -> + {reply, {Event, true}, Events}. + +disconnect_pull_supplier(Events) -> + io:format("event_test_PullS terminates ~p~n", [Events]), + {stop, normal, ok, Events}. + + +add_event(Events, Event) -> + %% Store in FIFO order; don't really care if we use '++' since + %% this operation is used in tests only. + {reply, ok, Events ++ [Event]}. + + diff --git a/lib/cosEvent/test/event_test_PushC_impl.erl b/lib/cosEvent/test/event_test_PushC_impl.erl new file mode 100644 index 0000000000..6eadf74a31 --- /dev/null +++ b/lib/cosEvent/test/event_test_PushC_impl.erl @@ -0,0 +1,46 @@ +%%------------------------------------------------------------------------ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%------------------------------------------------------------------------ +%% Description: a very simple implementation of Push Consumer interface +%%------------------------------------------------------------------------ + +-module(event_test_PushC_impl). + +-export([init/1, terminate/2, push/2, disconnect_push_consumer/1, get_data/1]). + +init(_) -> + {ok, []}. + +terminate(_From, _Reason) -> + ok. + +push(Events, Event) -> + {reply, ok, [Event|Events]}. + +disconnect_push_consumer(Events) -> + io:format("event_test_PushC terminates: ~p~n", [Events]), + {stop, normal, ok, Events}. + + +get_data(Events) -> + %% Returns Events in FIFO order and reset state. + {reply, lists:reverse(Events), []}. + diff --git a/lib/cosEvent/test/event_test_PushS_impl.erl b/lib/cosEvent/test/event_test_PushS_impl.erl new file mode 100644 index 0000000000..da82e97211 --- /dev/null +++ b/lib/cosEvent/test/event_test_PushS_impl.erl @@ -0,0 +1,41 @@ +%%------------------------------------------------------------------------ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%------------------------------------------------------------------------ +%% Description: a very simple implementation of Push Supplier interface +%%------------------------------------------------------------------------ + +-module(event_test_PushS_impl). + +-export([init/1, terminate/2, disconnect_push_supplier/1, do_push/2]). + +init(Proxy) -> + {ok, Proxy}. + +terminate(_From, _Reason) -> + ok. + +disconnect_push_supplier(Proxy) -> + io:format("event_test_PullC terminates~n",[]), + {stop, normal, ok, Proxy}. + +do_push(Proxy, Event) -> + {reply, 'CosEventComm_PushConsumer':push(Proxy, Event), Proxy}. + diff --git a/lib/cosEvent/test/event_test_server.idl b/lib/cosEvent/test/event_test_server.idl new file mode 100644 index 0000000000..1719401ccd --- /dev/null +++ b/lib/cosEvent/test/event_test_server.idl @@ -0,0 +1,47 @@ +// +// %CopyrightBegin% +// +// Copyright Ericsson AB 2001-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// + +#ifndef _EVENT_TEST_SERVER_IDL +#define _EVENT_TEST_SERVER_IDL + +#include <../src/CosEventComm.idl> + +module event_test { + + interface PushC : CosEventComm::PushConsumer { + typedef sequence<any> AnySeq; + AnySeq get_data(); + }; + interface PullC : CosEventComm::PullConsumer { + any do_pull(); + any do_try_pull(out boolean has_event); + }; + + interface PushS : CosEventComm::PushSupplier { + void do_push(in any Event); + }; + interface PullS : CosEventComm::PullSupplier { + void add_event(in any Event); + }; + +}; + +#endif + + diff --git a/lib/cosEvent/test/generated_SUITE.erl b/lib/cosEvent/test/generated_SUITE.erl new file mode 100644 index 0000000000..2d75b18451 --- /dev/null +++ b/lib/cosEvent/test/generated_SUITE.erl @@ -0,0 +1,487 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : generated_SUITE.erl +%% Purpose : +%%----------------------------------------------------------------- + +-module(generated_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(nomatch(Not, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + Not -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS); + _ -> + AcTuAlReS + end + end()). + + +-define(checktc(_Op), + fun(TC) -> + case orber_tc:check_tc(TC) of + false -> + io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]), + ?line exit(TC); + true -> + true + end + end). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["This suite is for testing IC generated files"]; +all(suite) -> + ['CosEventChannelAdmin_AlreadyConnected', 'CosEventChannelAdmin_TypeError', + 'CosEventComm_Disconnected', + 'CosEventChannelAdmin_ConsumerAdmin', 'CosEventChannelAdmin_EventChannel', + 'CosEventChannelAdmin_ProxyPullConsumer', 'CosEventChannelAdmin_ProxyPullSupplier', + 'CosEventChannelAdmin_ProxyPushConsumer', 'CosEventChannelAdmin_ProxyPushSupplier', + 'CosEventChannelAdmin_SupplierAdmin', oe_CosEventComm_CAdmin, + oe_CosEventComm_Channel, oe_CosEventComm_Event, oe_CosEventComm_PullerS, + oe_CosEventComm_PusherS, 'CosEventComm_PullConsumer', + 'CosEventComm_PullSupplier', 'CosEventComm_PushConsumer', + 'CosEventComm_PushSupplier']. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventChannelAdmin_AlreadyConnected' +%% Description: +%%----------------------------------------------------------------- +'CosEventChannelAdmin_AlreadyConnected'(doc) -> [""]; +'CosEventChannelAdmin_AlreadyConnected'(suite) -> []; +'CosEventChannelAdmin_AlreadyConnected'(_) -> + ?match(true, orber_tc:check_tc('CosEventChannelAdmin_AlreadyConnected':tc())), + ?match("IDL:omg.org/CosEventChannelAdmin/AlreadyConnected:1.0", + 'CosEventChannelAdmin_AlreadyConnected':id()), + ?match("CosEventChannelAdmin_AlreadyConnected", + 'CosEventChannelAdmin_AlreadyConnected':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventChannelAdmin_TypeError' +%% Description: +%%----------------------------------------------------------------- +'CosEventChannelAdmin_TypeError'(doc) -> [""]; +'CosEventChannelAdmin_TypeError'(suite) -> []; +'CosEventChannelAdmin_TypeError'(_) -> + ?match(true, orber_tc:check_tc('CosEventChannelAdmin_TypeError':tc())), + ?match("IDL:omg.org/CosEventChannelAdmin/TypeError:1.0", + 'CosEventChannelAdmin_TypeError':id()), + ?match("CosEventChannelAdmin_TypeError", + 'CosEventChannelAdmin_TypeError':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventComm_Disconnected' +%% Description: +%%----------------------------------------------------------------- +'CosEventComm_Disconnected'(doc) -> [""]; +'CosEventComm_Disconnected'(suite) -> []; +'CosEventComm_Disconnected'(_) -> + ?match(true, orber_tc:check_tc('CosEventComm_Disconnected':tc())), + ?match("IDL:omg.org/CosEventComm/Disconnected:1.0", + 'CosEventComm_Disconnected':id()), + ?match("CosEventComm_Disconnected", 'CosEventComm_Disconnected':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventChannelAdmin_ConsumerAdmin' +%% Description: +%%----------------------------------------------------------------- +'CosEventChannelAdmin_ConsumerAdmin'(doc) -> [""]; +'CosEventChannelAdmin_ConsumerAdmin'(suite) -> []; +'CosEventChannelAdmin_ConsumerAdmin'(_) -> + ?nomatch(undefined, 'CosEventChannelAdmin_ConsumerAdmin':oe_tc(obtain_push_supplier)), + ?nomatch(undefined, 'CosEventChannelAdmin_ConsumerAdmin':oe_tc(obtain_pull_supplier)), + ?match(undefined, 'CosEventChannelAdmin_ConsumerAdmin':oe_tc(undefined)), + ?match([_|_], 'CosEventChannelAdmin_ConsumerAdmin':oe_get_interface()), + ?match("IDL:omg.org/CosEventChannelAdmin/ConsumerAdmin:1.0", + 'CosEventChannelAdmin_ConsumerAdmin':typeID()), + check_tc('CosEventChannelAdmin_ConsumerAdmin':oe_get_interface()), + ?match(true, 'CosEventChannelAdmin_ConsumerAdmin':oe_is_a('CosEventChannelAdmin_ConsumerAdmin':typeID())), + ?match(false, 'CosEventChannelAdmin_ConsumerAdmin':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventChannelAdmin_EventChannel' +%% Description: +%%----------------------------------------------------------------- +'CosEventChannelAdmin_EventChannel'(doc) -> [""]; +'CosEventChannelAdmin_EventChannel'(suite) -> []; +'CosEventChannelAdmin_EventChannel'(_) -> + ?nomatch(undefined, 'CosEventChannelAdmin_EventChannel':oe_tc(for_consumers)), + ?nomatch(undefined, 'CosEventChannelAdmin_EventChannel':oe_tc(for_suppliers)), + ?nomatch(undefined, 'CosEventChannelAdmin_EventChannel':oe_tc(destroy)), + ?match(undefined, 'CosEventChannelAdmin_EventChannel':oe_tc(undefined)), + ?match([_|_], 'CosEventChannelAdmin_EventChannel':oe_get_interface()), + ?match("IDL:omg.org/CosEventChannelAdmin/EventChannel:1.0", + 'CosEventChannelAdmin_EventChannel':typeID()), + check_tc('CosEventChannelAdmin_EventChannel':oe_get_interface()), + ?match(true, 'CosEventChannelAdmin_EventChannel':oe_is_a('CosEventChannelAdmin_EventChannel':typeID())), + ?match(false, 'CosEventChannelAdmin_EventChannel':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventChannelAdmin_ProxyPullConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosEventChannelAdmin_ProxyPullConsumer'(doc) -> [""]; +'CosEventChannelAdmin_ProxyPullConsumer'(suite) -> []; +'CosEventChannelAdmin_ProxyPullConsumer'(_) -> + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullConsumer':oe_tc(connect_pull_supplier)), + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullConsumer':oe_tc(disconnect_pull_consumer)), + ?match(undefined, 'CosEventChannelAdmin_ProxyPullConsumer':oe_tc(undefined)), + ?match([_|_], 'CosEventChannelAdmin_ProxyPullConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosEventChannelAdmin/ProxyPullConsumer:1.0", + 'CosEventChannelAdmin_ProxyPullConsumer':typeID()), + check_tc('CosEventChannelAdmin_ProxyPullConsumer':oe_get_interface()), + ?match(true, 'CosEventChannelAdmin_ProxyPullConsumer':oe_is_a('CosEventChannelAdmin_ProxyPullConsumer':typeID())), + ?match(true, 'CosEventChannelAdmin_ProxyPullConsumer':oe_is_a('CosEventComm_PullConsumer':typeID())), + ?match(false, 'CosEventChannelAdmin_ProxyPullConsumer':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventChannelAdmin_ProxyPullSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosEventChannelAdmin_ProxyPullSupplier'(doc) -> [""]; +'CosEventChannelAdmin_ProxyPullSupplier'(suite) -> []; +'CosEventChannelAdmin_ProxyPullSupplier'(_) -> + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullSupplier':oe_tc(connect_pull_consumer)), + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullSupplier':oe_tc(pull)), + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullSupplier':oe_tc(try_pull)), + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPullSupplier':oe_tc(disconnect_pull_supplier)), + ?match(undefined, 'CosEventChannelAdmin_ProxyPullSupplier':oe_tc(undefined)), + ?match([_|_], 'CosEventChannelAdmin_ProxyPullSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosEventChannelAdmin/ProxyPullSupplier:1.0", + 'CosEventChannelAdmin_ProxyPullSupplier':typeID()), + check_tc('CosEventChannelAdmin_ProxyPullSupplier':oe_get_interface()), + ?match(true, 'CosEventChannelAdmin_ProxyPullSupplier':oe_is_a('CosEventChannelAdmin_ProxyPullSupplier':typeID())), + ?match(true, 'CosEventChannelAdmin_ProxyPullSupplier':oe_is_a('CosEventComm_PullSupplier':typeID())), + ?match(false, 'CosEventChannelAdmin_ProxyPullSupplier':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventChannelAdmin_ProxyPushConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosEventChannelAdmin_ProxyPushConsumer'(doc) -> [""]; +'CosEventChannelAdmin_ProxyPushConsumer'(suite) -> []; +'CosEventChannelAdmin_ProxyPushConsumer'(_) -> + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPushConsumer':oe_tc(connect_push_supplier)), + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPushConsumer':oe_tc(push)), + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPushConsumer':oe_tc(disconnect_push_consumer)), + ?match(undefined, 'CosEventChannelAdmin_ProxyPushConsumer':oe_tc(undefined)), + ?match([_|_], 'CosEventChannelAdmin_ProxyPushConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosEventChannelAdmin/ProxyPushConsumer:1.0", + 'CosEventChannelAdmin_ProxyPushConsumer':typeID()), + check_tc('CosEventChannelAdmin_ProxyPushConsumer':oe_get_interface()), + ?match(true, 'CosEventChannelAdmin_ProxyPushConsumer':oe_is_a('CosEventChannelAdmin_ProxyPushConsumer':typeID())), + ?match(true, 'CosEventChannelAdmin_ProxyPushConsumer':oe_is_a('CosEventComm_PushConsumer':typeID())), + ?match(false, 'CosEventChannelAdmin_ProxyPushConsumer':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventChannelAdmin_ProxyPushSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosEventChannelAdmin_ProxyPushSupplier'(doc) -> [""]; +'CosEventChannelAdmin_ProxyPushSupplier'(suite) -> []; +'CosEventChannelAdmin_ProxyPushSupplier'(_) -> + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPushSupplier':oe_tc(connect_push_consumer)), + ?nomatch(undefined, 'CosEventChannelAdmin_ProxyPushSupplier':oe_tc(disconnect_push_supplier)), + ?match(undefined, 'CosEventChannelAdmin_ProxyPushSupplier':oe_tc(undefined)), + ?match([_|_], 'CosEventChannelAdmin_ProxyPushSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosEventChannelAdmin/ProxyPushSupplier:1.0", + 'CosEventChannelAdmin_ProxyPushSupplier':typeID()), + check_tc('CosEventChannelAdmin_ProxyPushSupplier':oe_get_interface()), + ?match(true, 'CosEventChannelAdmin_ProxyPushSupplier':oe_is_a('CosEventChannelAdmin_ProxyPushSupplier':typeID())), + ?match(true, 'CosEventChannelAdmin_ProxyPushSupplier':oe_is_a('CosEventComm_PushSupplier':typeID())), + ?match(false, 'CosEventChannelAdmin_ProxyPushSupplier':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventChannelAdmin_SupplierAdmin' +%% Description: +%%----------------------------------------------------------------- +'CosEventChannelAdmin_SupplierAdmin'(doc) -> [""]; +'CosEventChannelAdmin_SupplierAdmin'(suite) -> []; +'CosEventChannelAdmin_SupplierAdmin'(_) -> + ?nomatch(undefined, 'CosEventChannelAdmin_SupplierAdmin':oe_tc(obtain_push_consumer)), + ?nomatch(undefined, 'CosEventChannelAdmin_SupplierAdmin':oe_tc(obtain_pull_consumer)), + ?match(undefined, 'CosEventChannelAdmin_SupplierAdmin':oe_tc(undefined)), + ?match([_|_], 'CosEventChannelAdmin_SupplierAdmin':oe_get_interface()), + ?match("IDL:omg.org/CosEventChannelAdmin/SupplierAdmin:1.0", + 'CosEventChannelAdmin_SupplierAdmin':typeID()), + check_tc('CosEventChannelAdmin_SupplierAdmin':oe_get_interface()), + ?match(true, 'CosEventChannelAdmin_SupplierAdmin':oe_is_a('CosEventChannelAdmin_SupplierAdmin':typeID())), + ?match(false, 'CosEventChannelAdmin_SupplierAdmin':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'oe_CosEventComm_CAdmin' +%% Description: +%%----------------------------------------------------------------- +'oe_CosEventComm_CAdmin'(doc) -> [""]; +'oe_CosEventComm_CAdmin'(suite) -> []; +'oe_CosEventComm_CAdmin'(_) -> + ?nomatch(undefined, 'oe_CosEventComm_CAdmin':oe_tc(obtain_push_supplier)), + ?nomatch(undefined, 'oe_CosEventComm_CAdmin':oe_tc(obtain_pull_supplier)), + ?nomatch(undefined, 'oe_CosEventComm_CAdmin':oe_tc(send)), + ?nomatch(undefined, 'oe_CosEventComm_CAdmin':oe_tc(send_sync)), + ?match(undefined, 'oe_CosEventComm_CAdmin':oe_tc(undefined)), + ?match([_|_], 'oe_CosEventComm_CAdmin':oe_get_interface()), + ?match("IDL:oe_CosEventComm/CAdmin:1.0", + 'oe_CosEventComm_CAdmin':typeID()), + check_tc('oe_CosEventComm_CAdmin':oe_get_interface()), + ?match(true, 'oe_CosEventComm_CAdmin':oe_is_a('oe_CosEventComm_CAdmin':typeID())), + ?match(true, 'oe_CosEventComm_CAdmin':oe_is_a('CosEventChannelAdmin_ConsumerAdmin':typeID())), + ?match(true, 'oe_CosEventComm_CAdmin':oe_is_a('oe_CosEventComm_Event':typeID())), + ?match(false, 'oe_CosEventComm_CAdmin':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'oe_CosEventComm_Channel' +%% Description: +%%----------------------------------------------------------------- +'oe_CosEventComm_Channel'(doc) -> [""]; +'oe_CosEventComm_Channel'(suite) -> []; +'oe_CosEventComm_Channel'(_) -> + ?nomatch(undefined, 'oe_CosEventComm_Channel':oe_tc(for_consumers)), + ?nomatch(undefined, 'oe_CosEventComm_Channel':oe_tc(for_suppliers)), + ?nomatch(undefined, 'oe_CosEventComm_Channel':oe_tc(destroy)), + ?nomatch(undefined, 'oe_CosEventComm_Channel':oe_tc(send)), + ?nomatch(undefined, 'oe_CosEventComm_Channel':oe_tc(send_sync)), + ?match(undefined, 'oe_CosEventComm_Channel':oe_tc(undefined)), + ?match([_|_], 'oe_CosEventComm_Channel':oe_get_interface()), + ?match("IDL:oe_CosEventComm/Channel:1.0", + 'oe_CosEventComm_Channel':typeID()), + check_tc('oe_CosEventComm_Channel':oe_get_interface()), + ?match(true, 'oe_CosEventComm_Channel':oe_is_a('oe_CosEventComm_Channel':typeID())), + ?match(true, 'oe_CosEventComm_Channel':oe_is_a('CosEventChannelAdmin_EventChannel':typeID())), + ?match(true, 'oe_CosEventComm_Channel':oe_is_a('oe_CosEventComm_Event':typeID())), + ?match(false, 'oe_CosEventComm_Channel':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'oe_CosEventComm_Event' +%% Description: +%%----------------------------------------------------------------- +'oe_CosEventComm_Event'(doc) -> [""]; +'oe_CosEventComm_Event'(suite) -> []; +'oe_CosEventComm_Event'(_) -> + ?nomatch(undefined, 'oe_CosEventComm_Event':oe_tc(send)), + ?nomatch(undefined, 'oe_CosEventComm_Event':oe_tc(send_sync)), + ?match(undefined, 'oe_CosEventComm_Event':oe_tc(undefined)), + ?match([_|_], 'oe_CosEventComm_Event':oe_get_interface()), + ?match("IDL:oe_CosEventComm/Event:1.0", + 'oe_CosEventComm_Event':typeID()), + check_tc('oe_CosEventComm_Event':oe_get_interface()), + ?match(true, 'oe_CosEventComm_Event':oe_is_a('oe_CosEventComm_Event':typeID())), + ?match(false, 'oe_CosEventComm_Event':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'oe_CosEventComm_PullerS' +%% Description: +%%----------------------------------------------------------------- +'oe_CosEventComm_PullerS'(doc) -> [""]; +'oe_CosEventComm_PullerS'(suite) -> []; +'oe_CosEventComm_PullerS'(_) -> + ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(connect_pull_consumer)), + ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(pull)), + ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(try_pull)), + ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(disconnect_pull_supplier)), + ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(send)), + ?nomatch(undefined, 'oe_CosEventComm_PullerS':oe_tc(send_sync)), + ?match(undefined, 'oe_CosEventComm_PullerS':oe_tc(undefined)), + ?match([_|_], 'oe_CosEventComm_PullerS':oe_get_interface()), + ?match("IDL:oe_CosEventComm/PullerS:1.0", + 'oe_CosEventComm_PullerS':typeID()), + check_tc('oe_CosEventComm_PullerS':oe_get_interface()), + ?match(true, 'oe_CosEventComm_PullerS':oe_is_a('oe_CosEventComm_PullerS':typeID())), + ?match(true, 'oe_CosEventComm_PullerS':oe_is_a('CosEventChannelAdmin_ProxyPullSupplier':typeID())), + ?match(true, 'oe_CosEventComm_PullerS':oe_is_a('CosEventComm_PullSupplier':typeID())), + ?match(true, 'oe_CosEventComm_PullerS':oe_is_a('oe_CosEventComm_Event':typeID())), + ?match(false, 'oe_CosEventComm_PullerS':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'oe_CosEventComm_PusherS' +%% Description: +%%----------------------------------------------------------------- +'oe_CosEventComm_PusherS'(doc) -> [""]; +'oe_CosEventComm_PusherS'(suite) -> []; +'oe_CosEventComm_PusherS'(_) -> + ?nomatch(undefined, 'oe_CosEventComm_PusherS':oe_tc(connect_push_consumer)), + ?nomatch(undefined, 'oe_CosEventComm_PusherS':oe_tc(disconnect_push_supplier)), + ?nomatch(undefined, 'oe_CosEventComm_PusherS':oe_tc(send)), + ?nomatch(undefined, 'oe_CosEventComm_PusherS':oe_tc(send_sync)), + ?match(undefined, 'oe_CosEventComm_PusherS':oe_tc(undefined)), + ?match([_|_], 'oe_CosEventComm_PusherS':oe_get_interface()), + ?match("IDL:oe_CosEventComm/PusherS:1.0", + 'oe_CosEventComm_PusherS':typeID()), + check_tc('oe_CosEventComm_PusherS':oe_get_interface()), + ?match(true, 'oe_CosEventComm_PusherS':oe_is_a('oe_CosEventComm_PusherS':typeID())), + ?match(true, 'oe_CosEventComm_PusherS':oe_is_a('CosEventChannelAdmin_ProxyPushSupplier':typeID())), + ?match(true, 'oe_CosEventComm_PusherS':oe_is_a('CosEventComm_PushSupplier':typeID())), + ?match(true, 'oe_CosEventComm_PusherS':oe_is_a('oe_CosEventComm_Event':typeID())), + ?match(false, 'oe_CosEventComm_PusherS':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventComm_PullConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosEventComm_PullConsumer'(doc) -> [""]; +'CosEventComm_PullConsumer'(suite) -> []; +'CosEventComm_PullConsumer'(_) -> + ?nomatch(undefined, 'CosEventComm_PullConsumer':oe_tc(disconnect_pull_consumer)), + ?match(undefined, 'CosEventComm_PullConsumer':oe_tc(undefined)), + ?match([_|_], 'CosEventComm_PullConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosEventComm/PullConsumer:1.0", + 'CosEventComm_PullConsumer':typeID()), + check_tc('CosEventComm_PullConsumer':oe_get_interface()), + ?match(true, 'CosEventComm_PullConsumer':oe_is_a('CosEventComm_PullConsumer':typeID())), + ?match(false, 'CosEventComm_PullConsumer':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventComm_PullSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosEventComm_PullSupplier'(doc) -> [""]; +'CosEventComm_PullSupplier'(suite) -> []; +'CosEventComm_PullSupplier'(_) -> + ?nomatch(undefined, 'CosEventComm_PullSupplier':oe_tc(pull)), + ?nomatch(undefined, 'CosEventComm_PullSupplier':oe_tc(try_pull)), + ?nomatch(undefined, 'CosEventComm_PullSupplier':oe_tc(disconnect_pull_supplier)), + ?match(undefined, 'CosEventComm_PullSupplier':oe_tc(undefined)), + ?match([_|_], 'CosEventComm_PullSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosEventComm/PullSupplier:1.0", + 'CosEventComm_PullSupplier':typeID()), + check_tc('CosEventComm_PullSupplier':oe_get_interface()), + ?match(true, 'CosEventComm_PullSupplier':oe_is_a('CosEventComm_PullSupplier':typeID())), + ?match(false, 'CosEventComm_PullSupplier':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventComm_PushConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosEventComm_PushConsumer'(doc) -> [""]; +'CosEventComm_PushConsumer'(suite) -> []; +'CosEventComm_PushConsumer'(_) -> + ?nomatch(undefined, 'CosEventComm_PushConsumer':oe_tc(push)), + ?nomatch(undefined, 'CosEventComm_PushConsumer':oe_tc(disconnect_push_consumer)), + ?match(undefined, 'CosEventComm_PushConsumer':oe_tc(undefined)), + ?match([_|_], 'CosEventComm_PushConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosEventComm/PushConsumer:1.0", + 'CosEventComm_PushConsumer':typeID()), + check_tc('CosEventComm_PushConsumer':oe_get_interface()), + ?match(true, 'CosEventComm_PushConsumer':oe_is_a('CosEventComm_PushConsumer':typeID())), + ?match(false, 'CosEventComm_PushConsumer':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventComm_PushSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosEventComm_PushSupplier'(doc) -> [""]; +'CosEventComm_PushSupplier'(suite) -> []; +'CosEventComm_PushSupplier'(_) -> + ?nomatch(undefined, 'CosEventComm_PushSupplier':oe_tc(disconnect_push_supplier)), + ?match(undefined, 'CosEventComm_PushSupplier':oe_tc(undefined)), + ?match([_|_], 'CosEventComm_PushSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosEventComm/PushSupplier:1.0", + 'CosEventComm_PushSupplier':typeID()), + check_tc('CosEventComm_PushSupplier':oe_get_interface()), + ?match(true, 'CosEventComm_PushSupplier':oe_is_a('CosEventComm_PushSupplier':typeID())), + ?match(false, 'CosEventComm_PushSupplier':oe_is_a("wrong")), + ok. + + + +%%----------------------------------------------------------------- +%% MISC functions +%%----------------------------------------------------------------- +check_tc([]) -> + ok; +check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) -> + io:format("checked - ~s~n", [Op]), + lists:all(?checktc(Op), [RetType|InParameters]), + lists:all(?checktc(Op), OutParameters), + check_tc(T). + + diff --git a/lib/cosEvent/test/idl_output/.gitignore b/lib/cosEvent/test/idl_output/.gitignore new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/cosEvent/test/idl_output/.gitignore diff --git a/lib/cosEventDomain/test/Makefile b/lib/cosEventDomain/test/Makefile new file mode 100644 index 0000000000..9893b05b8c --- /dev/null +++ b/lib/cosEventDomain/test/Makefile @@ -0,0 +1,104 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSEVENTDOMAIN_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/cosEventDomain_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = cosEventDomain.spec + + +MODULES = \ + event_domain_SUITE \ + generated_SUITE + +ERL_FILES = $(MODULES:%=%.erl) + +HRL_FILES = + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(SUITE_TARGET_FILES) + +# ---------------------------------------------------- +# PROGRAMS +# ---------------------------------------------------- +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/orber/ebin -pa $(ERL_TOP)/lib/ic/ebin + +ERL_COMPILE_FLAGS += \ + $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/test_server/ebin \ + -pa $(ERL_TOP)/lib/cosEventDomain/ebin \ + -pa $(ERL_TOP)/lib/cosEventDomain/include \ + -pa $(ERL_TOP)/lib/cosNotification/ebin \ + -pa $(ERL_TOP)/lib/cosNotification/include \ + -I$(ERL_TOP)/lib/cosEventDomain/include \ + -I$(ERL_TOP)/lib/cosNotification/include \ + -I$(ERL_TOP)/lib/cosNotification/ebin \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +tests debug opt: $(TARGET_FILES) + +clean: + rm -f $(TARGET_FILES) + rm -f errs core *~ + + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +# We don't copy generated intermediate erlang and hrl files + +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(TEST_SPEC_FILE) \ + $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + diff --git a/lib/cosEventDomain/test/cosEventDomain.spec b/lib/cosEventDomain/test/cosEventDomain.spec new file mode 100644 index 0000000000..0d3e307071 --- /dev/null +++ b/lib/cosEventDomain/test/cosEventDomain.spec @@ -0,0 +1,19 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +{topcase, {dir, "../cosEventDomain_test"}}. diff --git a/lib/cosEventDomain/test/event_domain_SUITE.erl b/lib/cosEventDomain/test/event_domain_SUITE.erl new file mode 100644 index 0000000000..ddf0af3489 --- /dev/null +++ b/lib/cosEventDomain/test/event_domain_SUITE.erl @@ -0,0 +1,456 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- + +-module(event_domain_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("cosNotification/include/CosNotifyChannelAdmin.hrl"). +-include_lib("cosNotification/include/CosNotification.hrl"). + +-include_lib("cosEventDomain/include/CosEventDomainAdmin.hrl"). +-include_lib("cosEventDomain/src/cosEventDomainApp.hrl"). + +%%----------------------------------------------------------------- +%% Macros +%%----------------------------------------------------------------- + +-define(default_timeout, ?t:minutes(5)). + + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, event_domain_api/1, event_domain_factory_api/1, + cases/0, init_all/1, finish_all/1, + init_per_testcase/2, fin_per_testcase/2, app_test/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- + +all(doc) -> ["API tests for the cosEventDomain interfaces", ""]; +all(suite) -> {req, + [mnesia, orber, cosNotification], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [event_domain_api, event_domain_factory_api, app_test]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + ok = corba:orb_init([{flags, 16#02}, + {orber_debug_level, 10}]), + orber:install([node()]), + application:start(mnesia), + application:start(orber), + cosEventApp:install(), + cosEventApp:start(), + cosNotificationApp:install(), + cosNotificationApp:start(), + cosEventDomainApp:install(), + cosEventDomainApp:start(), + Config. + +finish_all(Config) when is_list(Config) -> + cosEventDomainApp:stop(), + cosEventDomainApp:uninstall(), + cosNotificationApp:stop(), + cosNotificationApp:uninstall(), + cosEventApp:stop(), + cosEventApp:uninstall(), + application:stop(orber), + application:stop(mnesia), + mnesia:delete_schema([node()]), + Config. + +%%----------------------------------------------------------------- +%% Tests app file +%%----------------------------------------------------------------- +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ok=test_server:app_test(cosEventDomain), + ok. + + +event_domain_api(doc) -> ["Testing the CosEventDomain Domain API", ""]; +event_domain_api(suite) -> []; +event_domain_api(_Config) -> + + %% We will setup a cluster looking like: + %% 7-8---> + %% / + %% 2 - 4 6-> + %% \ / + %% 5---9-1-3 + + %% 2-4 + %% 4-1 + %% 1-3 + %% 3-6 + %% 5-9 + %% 9-1 + %% 4-7 + %% 7-8 + + + ChFac = ?match({_,key,_,_,_,_}, + cosNotificationApp:start_global_factory([{pullInterval,1}])), + {Ch0,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])), + Fac = ?match({_,key,_,_,_,_}, + cosEventDomainApp:start_factory()), + {ED, _} = ?match({{_,key,_,_,_,_}, _}, + 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [], [])), + ID0 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch0), + ?match(Ch0, 'CosEventDomainAdmin_EventDomain':get_channel(ED, ID0)), + ?match([0], 'CosEventDomainAdmin_EventDomain':get_all_channels(ED)), + ?match({'EXCEPTION',{'CosNotifyChannelAdmin_ChannelNotFound',_}}, + 'CosEventDomainAdmin_EventDomain':get_channel(ED, 100)), + ?match({'EXCEPTION',{'CosNotifyChannelAdmin_ChannelNotFound',_}}, + 'CosEventDomainAdmin_EventDomain':remove_channel(ED, 100)), + ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_channel(ED, 0)), + ?match([], 'CosEventDomainAdmin_EventDomain':get_all_channels(ED)), + ?match({'EXCEPTION',{'CosNotifyChannelAdmin_ChannelNotFound',_}}, + 'CosEventDomainAdmin_EventDomain':remove_channel(ED, 0)), + + %% Create a new event channel. + {Ch1,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])), + {Ch2,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])), + {Ch3,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])), + {Ch4,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])), + {Ch5,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])), + {Ch6,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])), + {Ch7,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])), + {Ch8,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])), + {Ch9,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(ChFac, [], [])), + + ID1 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch1), + ID2 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch2), + ID3 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch3), + ID4 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch4), + ID5 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch5), + ID6 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch6), + ID7 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch7), + ID8 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch8), + ID9 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch9), + ?match([_,_,_,_,_,_,_,_,_], + 'CosEventDomainAdmin_EventDomain':get_all_channels(ED)), + + ?match([], 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)), + C1 = #'CosEventDomainAdmin_Connection'{supplier_id=ID2, + consumer_id=ID4, + ctype='STRUCTURED_EVENT', + notification_style='Pull'}, + C2 = #'CosEventDomainAdmin_Connection'{supplier_id=ID4, + consumer_id=ID1, + ctype='ANY_EVENT', + notification_style='Push'}, + C3 = #'CosEventDomainAdmin_Connection'{supplier_id=ID1, + consumer_id=ID3, + ctype='ANY_EVENT', + notification_style='Pull'}, + C4 = #'CosEventDomainAdmin_Connection'{supplier_id=ID3, + consumer_id=ID6, + ctype='STRUCTURED_EVENT', + notification_style='Push'}, + C5 = #'CosEventDomainAdmin_Connection'{supplier_id=ID5, + consumer_id=ID9, + ctype='ANY_EVENT', + notification_style='Pull'}, + C6 = #'CosEventDomainAdmin_Connection'{supplier_id=ID9, + consumer_id=ID1, + ctype='ANY_EVENT', + notification_style='Push'}, + C7 = #'CosEventDomainAdmin_Connection'{supplier_id=ID4, + consumer_id=ID7, + ctype='STRUCTURED_EVENT', + notification_style='Pull'}, + C8 = #'CosEventDomainAdmin_Connection'{supplier_id=ID7, + consumer_id=ID8, + ctype='ANY_EVENT', + notification_style='Push'}, + C9 = #'CosEventDomainAdmin_Connection'{supplier_id=ID8, + consumer_id=ID4, + ctype='ANY_EVENT', + notification_style='Pull'}, + C10 = #'CosEventDomainAdmin_Connection'{supplier_id=ID5, + consumer_id=ID4, + ctype='ANY_EVENT', + notification_style='Pull'}, + C11 = #'CosEventDomainAdmin_Connection'{supplier_id=ID4, + consumer_id=ID6, + ctype='ANY_EVENT', + notification_style='Pull'}, + C12 = #'CosEventDomainAdmin_Connection'{supplier_id=ID8, + consumer_id=ID6, + ctype='ANY_EVENT', + notification_style='Pull'}, + + CID1 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C1), + ?match([CID1], 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)), + _CID2 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C2), + ?match([_,_], + 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)), + _CID3 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C3), + ?match([_,_,_], + 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)), + _CID4 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C4), + ?match([_,_,_,_], + 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)), + _CID5 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C5), + ?match([_,_,_,_,_], + 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)), + _CID6 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C6), + ?match([_,_,_,_,_,_], + 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)), + CID7 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C7), + ?match([_,_,_,_,_,_,_], + 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)), + _CID8 = 'CosEventDomainAdmin_EventDomain':add_connection(ED, C8), + ?match([_,_,_,_,_,_,_,_], + 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)), + + ?match({'EXCEPTION',{'CosEventDomainAdmin_AlreadyExists', _}}, + 'CosEventDomainAdmin_EventDomain':add_connection(ED, C8)), + %% No cycles should exist. + ?match([], 'CosEventDomainAdmin_EventDomain':get_cycles(ED)), + + ?match([_, _], 'CosEventDomainAdmin_EventDomain':get_qos(ED)), + AllowCyclic = #'CosNotification_Property'{name=?CycleDetection, + value=any:create(orber_tc:short(), + ?AuthorizeCycles)}, + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosEventDomainAdmin_EventDomain':set_qos(ED, [AllowCyclic])), + ForbidCyclic = #'CosNotification_Property'{name=?CycleDetection, + value=any:create(orber_tc:short(), + ?ForbidCycles)}, + %% The same as before; must work. + ?match(ok, 'CosEventDomainAdmin_EventDomain':set_qos(ED, [ForbidCyclic])), + + AllowDiamonds = #'CosNotification_Property'{name=?DiamondDetection, + value=any:create(orber_tc:short(), + ?AuthorizeDiamonds)}, + %% Since no diamonds allowed before this is always ok. + ?match(ok, 'CosEventDomainAdmin_EventDomain':set_qos(ED, [AllowDiamonds])), + + ?match([_, _], 'CosEventDomainAdmin_EventDomain':get_qos(ED)), + + ForbidDiamonds = #'CosNotification_Property'{name=?DiamondDetection, + value=any:create(orber_tc:short(), + ?ForbidDiamonds)}, + %% No diamonds created before. Hence, will work. + ?match(ok, 'CosEventDomainAdmin_EventDomain':set_qos(ED, [ForbidDiamonds])), + + ?match([_, _], 'CosEventDomainAdmin_EventDomain':get_qos(ED)), + + ?match({ok, [_]}, 'CosEventDomainAdmin_EventDomain':validate_qos(ED, + [ForbidDiamonds, + ForbidCyclic])), + %% No diamonds exists, hence, this is ok. + ?match({ok, [_]}, 'CosEventDomainAdmin_EventDomain':validate_qos(ED, + [AllowDiamonds, + ForbidCyclic])), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosEventDomainAdmin_EventDomain':validate_qos(ED, [ForbidDiamonds, + AllowCyclic])), + + %% Since the ED is started is asyclic we may not succeed with this invokation. + ?match({'EXCEPTION',{'CosEventDomainAdmin_CycleCreationForbidden',_,_}}, + 'CosEventDomainAdmin_EventDomain':add_connection(ED, C9)), + ?match([], 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, ID2)), + + ?match([2], 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, ID4)), + ?match([_,_,_], 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, ID8)), + ?match({'EXCEPTION',{'CosNotifyChannelAdmin_ChannelNotFound',_}}, + 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, 100)), + ?match([], 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, ID8)), + ?match([_,_,_,_,_], + 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, ID4)), + ?match([_,_,_,_,_,_], + 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, ID2)), + ?match({'EXCEPTION',{'CosNotifyChannelAdmin_ChannelNotFound',_}}, + 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, 100)), + Nil = corba:create_nil_objref(), + + P2=?match({_,key,_,_,_,_}, + 'CosEventDomainAdmin_EventDomain':connect_push_supplier_with_id(ED, Nil, ID2)), + P7=?match({_,key,_,_,_,_}, + 'CosEventDomainAdmin_EventDomain':connect_push_supplier_with_id(ED, Nil, ID7)), + P8=?match({_,key,_,_,_,_}, + 'CosEventDomainAdmin_EventDomain':connect_pull_consumer_with_id(ED, Nil, ID8)), + P6=?match({_,key,_,_,_,_}, + 'CosEventDomainAdmin_EventDomain':connect_pull_consumer_with_id(ED, Nil, ID6)), + E1 = #any{typecode=tk_long, value=1}, + E2 = #any{typecode=tk_long, value=2}, + + ?match(ok, 'CosNotifyChannelAdmin_ProxyPushConsumer':push(P2, E1)), + ?match(E1, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(P8)), + ?match(E1, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(P6)), + ?match(ok, 'CosNotifyChannelAdmin_ProxyPushConsumer':push(P7, E2)), + ?match(E2, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(P8)), + timer:sleep(10000), + ?match({_,false}, 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(P6)), + + ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID7)), + + ?match({'EXCEPTION',{'CosEventDomainAdmin_ConnectionNotFound',_}}, + 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID7)), + + ?match({'EXCEPTION',{'CosEventDomainAdmin_ConnectionNotFound',_}}, + 'CosEventDomainAdmin_EventDomain':remove_connection(ED, 100)), + + ?match([], 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, ID7)), + ?match([2], 'CosEventDomainAdmin_EventDomain':get_offer_channels(ED, ID4)), + + ?match([8], 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, ID7)), + ?match([_,_,_], 'CosEventDomainAdmin_EventDomain':get_subscription_channels(ED, ID4)), + + CID10 = ?match(8, 'CosEventDomainAdmin_EventDomain':add_connection(ED, C7)), + + %% Now we'll check diamond management. + %% Currently it should not be possible to create a diamond (due to QoS-setting). + ?match({'EXCEPTION',{'CosEventDomainAdmin_DiamondCreationForbidden',_,_}}, + 'CosEventDomainAdmin_EventDomain':add_connection(ED, C11)), + ?match({'EXCEPTION',{'CosEventDomainAdmin_DiamondCreationForbidden',_,_}}, + 'CosEventDomainAdmin_EventDomain':add_connection(ED, C10)), + ?match({'EXCEPTION',{'CosEventDomainAdmin_DiamondCreationForbidden',_,_}}, + 'CosEventDomainAdmin_EventDomain':add_connection(ED, C12)), + ?match(ok, 'CosEventDomainAdmin_EventDomain':set_qos(ED, [AllowDiamonds])), + + CID11 = ?match(9, 'CosEventDomainAdmin_EventDomain':add_connection(ED, C10)), + ?match([_,_,_,_,_,_,_,_,_], + 'CosEventDomainAdmin_EventDomain':get_all_connections(ED)), + ?match([_], 'CosEventDomainAdmin_EventDomain':get_diamonds(ED)), + + CID12 = ?match(10, 'CosEventDomainAdmin_EventDomain':add_connection(ED, C11)), + ?match([_, _, _], 'CosEventDomainAdmin_EventDomain':get_diamonds(ED)), + + CID13 = ?match(11, 'CosEventDomainAdmin_EventDomain':add_connection(ED, C12)), + + ?match([_, _, _], 'CosEventDomainAdmin_EventDomain':get_diamonds(ED)), + + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosEventDomainAdmin_EventDomain':set_qos(ED, [ForbidDiamonds])), + + ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID10)), + ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID11)), + ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID12)), + ?match(ok, 'CosEventDomainAdmin_EventDomain':remove_connection(ED, CID13)), + ?match(ok, 'CosEventDomainAdmin_EventDomain':set_qos(ED, [ForbidDiamonds])), + ?match([_, _], 'CosEventDomainAdmin_EventDomain':get_qos(ED)), + ?match({'EXCEPTION',{'CosEventDomainAdmin_DiamondCreationForbidden',_,_}}, + 'CosEventDomainAdmin_EventDomain':add_connection(ED, C10)), + + ?match(ok, 'CosEventDomainAdmin_EventDomain':destroy(ED)), + + ok. + +event_domain_factory_api(doc) -> ["Testing the CosEventDomain Factory API", ""]; +event_domain_factory_api(suite) -> []; +event_domain_factory_api(_Config) -> + + Cyclic = #'CosNotification_Property'{name=?CycleDetection, + value=any:create(orber_tc:short(), + ?ForbidCycles)}, + + BadProp = #'CosNotification_Property'{name="Wrong", + value=any:create(orber_tc:short(), + ?ForbidCycles)}, + + BadQoSVal = #'CosNotification_Property'{name=?CycleDetection, + value=any:create(orber_tc:short(), + 10)}, + + Fac = ?match({_,key,_,_,_,_}, + cosEventDomainApp:start_factory()), + ?match([], 'CosEventDomainAdmin_EventDomainFactory':get_all_domains(Fac)), + ?match({'EXCEPTION',{'CosEventDomainAdmin_DomainNotFound',_}}, + 'CosEventDomainAdmin_EventDomainFactory':get_event_domain(Fac, 0)), + {ED,_} = 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [Cyclic], []), + ?match([0], 'CosEventDomainAdmin_EventDomainFactory':get_all_domains(Fac)), + ED = 'CosEventDomainAdmin_EventDomainFactory':get_event_domain(Fac, 0), + ?match({'EXCEPTION',{'CosEventDomainAdmin_DomainNotFound',_}}, + 'CosEventDomainAdmin_EventDomainFactory':get_event_domain(Fac, 1)), + corba:dispose(ED), + timer:sleep(3000), + ?match([], 'CosEventDomainAdmin_EventDomainFactory':get_all_domains(Fac)), + ?match({'EXCEPTION',{'CosEventDomainAdmin_DomainNotFound',_}}, + 'CosEventDomainAdmin_EventDomainFactory':get_event_domain(Fac, 0)), + {ED2,_} = ?match({{_,key,_,_,_,_}, _}, + 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [], [])), + ?match([1], 'CosEventDomainAdmin_EventDomainFactory':get_all_domains(Fac)), + ?match(ED2, 'CosEventDomainAdmin_EventDomainFactory':get_event_domain(Fac, 1)), + corba:dispose(ED2), + + ?match({'EXCEPTION', {'CosNotification_UnsupportedQoS',_,_}}, + 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [BadProp], [])), + ?match({'EXCEPTION',{'CosNotification_UnsupportedAdmin',_,_}}, + 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [], [BadProp])), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [BadQoSVal], [])), + ?match({'EXCEPTION',{'CosNotification_UnsupportedAdmin',_,_}}, + 'CosEventDomainAdmin_EventDomainFactory':create_event_domain(Fac, [], [BadQoSVal])), + + corba:dispose(Fac), + ok. diff --git a/lib/cosEventDomain/test/generated_SUITE.erl b/lib/cosEventDomain/test/generated_SUITE.erl new file mode 100644 index 0000000000..6c6996ca79 --- /dev/null +++ b/lib/cosEventDomain/test/generated_SUITE.erl @@ -0,0 +1,390 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : generated_SUITE.erl +%% Purpose : +%%----------------------------------------------------------------- + +-module(generated_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(nomatch(Not, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + Not -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS); + _ -> + AcTuAlReS + end + end()). + + +-define(checktc(_Op), + fun(TC) -> + case orber_tc:check_tc(TC) of + false -> + io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]), + ?line exit(TC); + true -> + true + end + end). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["This suite is for testing IC generated files"]; +all(suite) -> + ['CosEventDomainAdmin', 'CosEventDomainAdmin_DiamondSeq', + 'CosEventDomainAdmin_AlreadyExists', 'CosEventDomainAdmin_DomainIDSeq', + 'CosEventDomainAdmin_Connection', 'CosEventDomainAdmin_ConnectionIDSeq', + 'CosEventDomainAdmin_ConnectionNotFound', 'CosEventDomainAdmin_CycleCreationForbidden', + 'CosEventDomainAdmin_CycleSeq', 'CosEventDomainAdmin_DiamondCreationForbidden', + 'CosEventDomainAdmin_DomainNotFound', 'CosEventDomainAdmin_MemberIDSeq', + 'CosEventDomainAdmin_RouteSeq', 'CosEventDomainAdmin_EventDomainFactory', + 'CosEventDomainAdmin_EventDomain']. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin'(doc) -> ["CosEventDomainAdmin"]; +'CosEventDomainAdmin'(suite) -> []; +'CosEventDomainAdmin'(_) -> + ?match("CycleDetection", 'CosEventDomainAdmin':'CycleDetection'()), + ?match(0, 'CosEventDomainAdmin':'AuthorizeCycles'()), + ?match(1, 'CosEventDomainAdmin':'ForbidCycles'()), + ?match("DiamondDetection", 'CosEventDomainAdmin':'DiamondDetection'()), + ?match(0, 'CosEventDomainAdmin':'AuthorizeDiamonds'()), + ?match(1, 'CosEventDomainAdmin':'ForbidDiamonds'()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_DiamondSeq' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_DiamondSeq'(doc) -> ["CosEventDomainAdmin_DiamondSeq"]; +'CosEventDomainAdmin_DiamondSeq'(suite) -> []; +'CosEventDomainAdmin_DiamondSeq'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_DiamondSeq':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/DiamondSeq:1.0", + 'CosEventDomainAdmin_DiamondSeq':id()), + ?match("CosEventDomainAdmin_DiamondSeq", + 'CosEventDomainAdmin_DiamondSeq':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_AlreadyExists' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_AlreadyExists'(doc) -> ["CosEventDomainAdmin_AlreadyExists"]; +'CosEventDomainAdmin_AlreadyExists'(suite) -> []; +'CosEventDomainAdmin_AlreadyExists'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_AlreadyExists':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/AlreadyExists:1.0", + 'CosEventDomainAdmin_AlreadyExists':id()), + ?match("CosEventDomainAdmin_AlreadyExists", + 'CosEventDomainAdmin_AlreadyExists':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_DomainIDSeq' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_DomainIDSeq'(doc) -> ["CosEventDomainAdmin_DomainIDSeq"]; +'CosEventDomainAdmin_DomainIDSeq'(suite) -> []; +'CosEventDomainAdmin_DomainIDSeq'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_DomainIDSeq':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/DomainIDSeq:1.0", + 'CosEventDomainAdmin_DomainIDSeq':id()), + ?match("CosEventDomainAdmin_DomainIDSeq", + 'CosEventDomainAdmin_DomainIDSeq':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_Connection' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_Connection'(doc) -> ["CosEventDomainAdmin_Connection"]; +'CosEventDomainAdmin_Connection'(suite) -> []; +'CosEventDomainAdmin_Connection'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_Connection':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/Connection:1.0", + 'CosEventDomainAdmin_Connection':id()), + ?match("CosEventDomainAdmin_Connection", + 'CosEventDomainAdmin_Connection':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_ConnectionIDSeq' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_ConnectionIDSeq'(doc) -> ["CosEventDomainAdmin_ConnectionIDSeq"]; +'CosEventDomainAdmin_ConnectionIDSeq'(suite) -> []; +'CosEventDomainAdmin_ConnectionIDSeq'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_ConnectionIDSeq':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/ConnectionIDSeq:1.0", + 'CosEventDomainAdmin_ConnectionIDSeq':id()), + ?match("CosEventDomainAdmin_ConnectionIDSeq", + 'CosEventDomainAdmin_ConnectionIDSeq':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_ConnectionNotFound' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_ConnectionNotFound'(doc) -> ["CosEventDomainAdmin_ConnectionNotFound"]; +'CosEventDomainAdmin_ConnectionNotFound'(suite) -> []; +'CosEventDomainAdmin_ConnectionNotFound'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_ConnectionNotFound':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/ConnectionNotFound:1.0", + 'CosEventDomainAdmin_ConnectionNotFound':id()), + ?match("CosEventDomainAdmin_ConnectionNotFound", + 'CosEventDomainAdmin_ConnectionNotFound':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_CycleCreationForbidden' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_CycleCreationForbidden'(doc) -> ["CosEventDomainAdmin_CycleCreationForbidden"]; +'CosEventDomainAdmin_CycleCreationForbidden'(suite) -> []; +'CosEventDomainAdmin_CycleCreationForbidden'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_CycleCreationForbidden':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/CycleCreationForbidden:1.0", + 'CosEventDomainAdmin_CycleCreationForbidden':id()), + ?match("CosEventDomainAdmin_CycleCreationForbidden", + 'CosEventDomainAdmin_CycleCreationForbidden':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_CycleSeq' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_CycleSeq'(doc) -> ["CosEventDomainAdmin_CycleSeq"]; +'CosEventDomainAdmin_CycleSeq'(suite) -> []; +'CosEventDomainAdmin_CycleSeq'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_CycleSeq':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/CycleSeq:1.0", + 'CosEventDomainAdmin_CycleSeq':id()), + ?match("CosEventDomainAdmin_CycleSeq", + 'CosEventDomainAdmin_CycleSeq':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_DiamondCreationForbidden' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_DiamondCreationForbidden'(doc) -> ["CosEventDomainAdmin_DiamondCreationForbidden"]; +'CosEventDomainAdmin_DiamondCreationForbidden'(suite) -> []; +'CosEventDomainAdmin_DiamondCreationForbidden'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_DiamondCreationForbidden':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/DiamondCreationForbidden:1.0", + 'CosEventDomainAdmin_DiamondCreationForbidden':id()), + ?match("CosEventDomainAdmin_DiamondCreationForbidden", + 'CosEventDomainAdmin_DiamondCreationForbidden':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_DomainNotFound' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_DomainNotFound'(doc) -> ["CosEventDomainAdmin_DomainNotFound"]; +'CosEventDomainAdmin_DomainNotFound'(suite) -> []; +'CosEventDomainAdmin_DomainNotFound'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_DomainNotFound':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/DomainNotFound:1.0", + 'CosEventDomainAdmin_DomainNotFound':id()), + ?match("CosEventDomainAdmin_DomainNotFound", + 'CosEventDomainAdmin_DomainNotFound':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_MemberIDSeq' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_MemberIDSeq'(doc) -> ["CosEventDomainAdmin_MemberIDSeq"]; +'CosEventDomainAdmin_MemberIDSeq'(suite) -> []; +'CosEventDomainAdmin_MemberIDSeq'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_MemberIDSeq':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/MemberIDSeq:1.0", + 'CosEventDomainAdmin_MemberIDSeq':id()), + ?match("CosEventDomainAdmin_MemberIDSeq", + 'CosEventDomainAdmin_MemberIDSeq':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_RouteSeq' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_RouteSeq'(doc) -> ["CosEventDomainAdmin_RouteSeq"]; +'CosEventDomainAdmin_RouteSeq'(suite) -> []; +'CosEventDomainAdmin_RouteSeq'(_) -> + ?match(true, orber_tc:check_tc('CosEventDomainAdmin_RouteSeq':tc())), + ?match("IDL:omg.org/CosEventDomainAdmin/RouteSeq:1.0", + 'CosEventDomainAdmin_RouteSeq':id()), + ?match("CosEventDomainAdmin_RouteSeq", + 'CosEventDomainAdmin_RouteSeq':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_EventDomainFactory' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_EventDomainFactory'(doc) -> ["CosEventDomainAdmin_EventDomainFactory"]; +'CosEventDomainAdmin_EventDomainFactory'(suite) -> []; +'CosEventDomainAdmin_EventDomainFactory'(_) -> + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomainFactory':oe_tc(create_event_domain)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomainFactory':oe_tc(get_all_domains)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomainFactory':oe_tc(get_event_domain)), + ?match(undefined, 'CosEventDomainAdmin_EventDomainFactory':oe_tc(undefined)), + ?match([_|_], 'CosEventDomainAdmin_EventDomainFactory':oe_get_interface()), + ?match("IDL:omg.org/CosEventDomainAdmin/EventDomainFactory:1.0", + 'CosEventDomainAdmin_EventDomainFactory':typeID()), + check_tc('CosEventDomainAdmin_EventDomainFactory':oe_get_interface()), + ?match(true, 'CosEventDomainAdmin_EventDomainFactory':oe_is_a('CosEventDomainAdmin_EventDomainFactory':typeID())), + ?match(false, 'CosEventDomainAdmin_EventDomainFactory':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosEventDomainAdmin_EventDomain' +%% Description: +%%----------------------------------------------------------------- +'CosEventDomainAdmin_EventDomain'(doc) -> ["CosEventDomainAdmin_EventDomain"]; +'CosEventDomainAdmin_EventDomain'(suite) -> []; +'CosEventDomainAdmin_EventDomain'(_) -> + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(add_channel)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_all_channels)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_channel)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(remove_channel)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(add_connection)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_all_connections)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_connection)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(remove_connection)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_offer_channels)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_subscription_channels)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(destroy)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_cycles)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_diamonds)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(set_default_consumer_channel)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(set_default_supplier_channel)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_push_consumer)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_pull_consumer)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_push_supplier)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_pull_supplier)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_push_consumer)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_pull_consumer)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_push_supplier)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_pull_supplier)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_push_consumer)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_pull_consumer)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_push_supplier)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_pull_supplier)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_push_consumer_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_pull_consumer_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_push_supplier_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_pull_supplier_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_push_consumer_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_pull_consumer_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_push_supplier_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_structured_pull_supplier_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_push_consumer_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_pull_consumer_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_push_supplier_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(connect_sequence_pull_supplier_with_id)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_qos)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(set_qos)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(get_admin)), + ?nomatch(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(set_admin)), + ?match(undefined, 'CosEventDomainAdmin_EventDomain':oe_tc(undefined)), + ?match([_|_], 'CosEventDomainAdmin_EventDomain':oe_get_interface()), + ?match("IDL:omg.org/CosEventDomainAdmin/EventDomain:1.0", + 'CosEventDomainAdmin_EventDomain':typeID()), + check_tc('CosEventDomainAdmin_EventDomain':oe_get_interface()), + ?match(true, 'CosEventDomainAdmin_EventDomain':oe_is_a('CosEventDomainAdmin_EventDomain':typeID())), + ?match(true, 'CosEventDomainAdmin_EventDomain':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosEventDomainAdmin_EventDomain':oe_is_a('CosNotification_AdminPropertiesAdmin':typeID())), + ?match(false, 'CosEventDomainAdmin_EventDomain':oe_is_a("wrong")), + ok. + + + +%%----------------------------------------------------------------- +%% MISC functions +%%----------------------------------------------------------------- +check_tc([]) -> + ok; +check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) -> + io:format("checked - ~s~n", [Op]), + lists:all(?checktc(Op), [RetType|InParameters]), + lists:all(?checktc(Op), OutParameters), + check_tc(T). + + diff --git a/lib/cosFileTransfer/test/Makefile b/lib/cosFileTransfer/test/Makefile new file mode 100644 index 0000000000..60f72644bd --- /dev/null +++ b/lib/cosFileTransfer/test/Makefile @@ -0,0 +1,132 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2000-2010. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSFILETRANSFER_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/cosFileTransfer_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = cosFileTransfer.spec + + +IDL_FILES = + +IDLOUTDIR = idl_output + +MODULES = \ + fileTransfer_SUITE \ + +GEN_MODULES = \ + +GEN_HRL_FILES = \ + +ERL_FILES = $(MODULES:%=%.erl) + +HRL_FILES = + +GEN_FILES = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl) + +GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR)) + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(GEN_TARGET_FILES) \ + $(SUITE_TARGET_FILES) + + +# ---------------------------------------------------- +# PROGRAMS +# ---------------------------------------------------- +LOCAL_CLASSPATH = $(ERL_TOP)lib/cosFileTransfer/priv:$(ERL_TOP)lib/cosFileTransfer/test +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosFileTransfer/ebin \ + -pa $(ERL_TOP)/lib/cosFileTransfer/src \ + -pa $(ERL_TOP)/lib/cosFileTransfer/include \ + -pa $(ERL_TOP)/lib/cosProperty/ebin \ + -pa $(ERL_TOP)/lib/cosProperty/include \ + -pa $(ERL_TOP)/lib/orber/ebin \ + -pa $(ERL_TOP)/lib/ic/ebin + +ERL_COMPILE_FLAGS += \ + $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/orber/include \ + -pa $(ERL_TOP)/lib/cosProperty/include \ + -pa $(ERL_TOP)/internal_tools/test_server/ebin \ + -pa $(ERL_TOP)/lib/cosFileTransfer/ebin \ + -pa $(ERL_TOP)/lib/cosFileTransfer/include \ + -pa $(ERL_TOP)/lib/cosFileTransfer/test/idl_output \ + -I$(ERL_TOP)/lib/orber/include \ + -I$(ERL_TOP)/lib/cosProperty/include \ + -I$(ERL_TOP)/lib/cosFileTransfer/src \ + -I$(ERL_TOP)/lib/cosFileTransfer/include \ + -I$(ERL_TOP)/lib/cosFileTransfer \ + -I$(ERL_TOP)/lib/cosFileTransfer/test/$(IDLOUTDIR) \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + + +tests debug opt: $(TARGET_FILES) + +clean: + rm -f idl_output/* + rm -f $(TARGET_FILES) + rm -f errs core *~ + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +# We don't copy generated intermediate erlang and hrl files + +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ + $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + chmod -f -R u+w $(RELSYSDIR) diff --git a/lib/cosFileTransfer/test/cosFileTransfer.spec b/lib/cosFileTransfer/test/cosFileTransfer.spec new file mode 100644 index 0000000000..80fe919f2a --- /dev/null +++ b/lib/cosFileTransfer/test/cosFileTransfer.spec @@ -0,0 +1 @@ +{topcase, {dir, "../cosFileTransfer_test"}}. diff --git a/lib/cosFileTransfer/test/fileTransfer_SUITE.erl b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl new file mode 100644 index 0000000000..f877e3ceda --- /dev/null +++ b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl @@ -0,0 +1,954 @@ +%%----------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : fileTransfer_SUITE.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module(fileTransfer_SUITE). + + + +%%--------------- INCLUDES ----------------------------------- +-include_lib("cosFileTransfer/src/cosFileTransferApp.hrl"). + +-include("test_server.hrl"). + +%%--------------- DEFINES ------------------------------------ +-define(default_timeout, ?t:minutes(20)). +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + exit(AcTuAlReS) + end + end()). + +-define(matchnopr(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT (~p) ------~n", [?LINE]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + exit(AcTuAlReS) + end + end()). + + + + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, + cases/0, + init_all/1, + finish_all/1, + fileIterator_api/1, + fts_ftp_file_api/1, + fts_ftp_file_ssl_api/1, + fts_ftp_dir_api/1, + fts_native_file_api/1, + fts_native_file_ssl_api/1, + fts_native_dir_api/1, + init_per_testcase/2, + fin_per_testcase/2, + install_data/2, + uninstall_data/1, + slave_sup/0, + app_test/1]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for the cosFileTransfer interfaces", ""]; +all(suite) -> {req, + [mnesia, orber], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [fts_ftp_dir_api, fts_ftp_file_api, fts_ftp_file_ssl_api, + fts_native_dir_api, fts_native_file_api, fts_native_file_ssl_api, + fileIterator_api, app_test]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + orber:jump_start(), + cosProperty:install(), + cosProperty:start(), + Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), + %% Client + cosFileTransferApp:configure(ssl_client_certfile, + filename:join([Dir, "client", "cert.pem"])), + cosFileTransferApp:configure(ssl_client_cacertfile, + filename:join([Dir, "client", "cacerts.pem"])), + cosFileTransferApp:configure(ssl_client_verify, 1), + cosFileTransferApp:configure(ssl_client_depth, 0), + %% Server + cosFileTransferApp:configure(ssl_server_certfile, + filename:join([Dir, "server", "cert.pem"])), + cosFileTransferApp:configure(ssl_server_cacertfile, + filename:join([Dir, "server", "cacerts.pem"])), + cosFileTransferApp:configure(ssl_server_verify, 1), + cosFileTransferApp:configure(ssl_server_depth, 0), + crypto:start(), + ssl:start(), + cosFileTransferApp:install(), + cosFileTransferApp:start(), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + ssl:stop(), + crypto:stop(), + cosFileTransferApp:stop(), + cosProperty:stop(), + cosProperty:uninstall(), + cosFileTransferApp:uninstall(), + orber:jump_stop(), + Config. + +%%----------------------------------------------------------------- +%% Local definitions +%%----------------------------------------------------------------- +-define(FTP_USER, "anonymous"). +-define(FTP_PASS, "fileTransfer_SUITE@localhost"). +-define(TEST_DIR,["/", "incoming"]). + + +-define(FTP_PORT, 21). +-define(FTP_ACC, "anonymous"). + +-define(BAD_HOST, "badhostname"). +-define(BAD_USER, "baduser"). +-define(BAD_DIR, "baddirectory"). + +-define(TEST_FILE_DATA, "If this file exists after a completed test an error occurred."). +-define(TEST_FILE_DATA2, "1234567890123"). + + +%%----------------------------------------------------------------- +%% aoo-file test +%%----------------------------------------------------------------- +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ?line ok=?t:app_test(cosFileTransfer), + ok. + +%%----------------------------------------------------------------- +%% FileIterator API tests +%%----------------------------------------------------------------- +fileIterator_api(doc) -> ["CosFileTransfer FileIterator API tests.", ""]; +fileIterator_api(suite) -> []; +fileIterator_api(Config) -> + case ftp_host(Config) of + {skipped, SkippedReason} -> + {skipped, SkippedReason}; + Host -> + + ?line {ok, Node} = create_node("fileIterator_api", 4008, normal), + ?line ?match(ok, remote_apply(Node, ?MODULE, install_data, + [tcp, {{'NATIVE', + 'cosFileTransferNATIVE_file'}, Host, + "fileIterator_api"}])), + + %% Create a Virtual File System. +%% ?line VFS = ?match({_,_,_,_,_,_}, +%% cosFileTransferApp:create_VFS({'NATIVE', +%% 'cosFileTransferNATIVE_file'}, +%% [], Host, ?FTP_PORT)), + ?line VFS = ?matchnopr({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_}, + corba:string_to_object("corbaname::1.2@localhost:4008/NameService#fileIterator_api")), + + %% Start two File Transfer Sessions (Source and Target). + ?line {FS, Dir} = ?matchnopr({{_,_,_},{_,_,_}}, + 'CosFileTransfer_VirtualFileSystem':login(VFS, + ?FTP_USER, + ?FTP_PASS, + ?FTP_ACC)), + + %% Do some basic test on one of the Directories attributes. + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(Dir)), + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(Dir)), + ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(Dir)), + ?line ?matchnopr(FS, 'CosFileTransfer_Directory':'_get_associated_session'(Dir)), + {ok,[],FileIter} = ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir, 0)), + %% Usually the working directory for the test is not empty so no need for + %% creating files of our own?! + #any{value=Children} = ?match({any, _, _}, + 'CosPropertyService_PropertySet': + get_property_value(Dir, "num_children")), + + if + Children > 5 -> + ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_one(FileIter)), + ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_n(FileIter, 3)), + ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_n(FileIter, + Children)), + ?line ?matchnopr({false, _}, 'CosFileTransfer_FileIterator':next_one(FileIter)), + ?line ?match({false, []}, 'CosFileTransfer_FileIterator':next_n(FileIter, 1)), + ok; + true -> + ok + end, + ?line ?match(ok, 'CosFileTransfer_FileIterator':destroy(FileIter)), + ?line ?match(false, corba_object:non_existent(FS)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FS)), + %% To make sure Orber can remove it from mnesia. + timer:sleep(1000), + ?line ?match(true, corba_object:non_existent(FS)), + ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, ["fileIterator_api"])), + stop_orber_remote(Node, normal), + ok + end. + + +%%----------------------------------------------------------------- +%% FileTransferSession API tests +%%----------------------------------------------------------------- +fts_ftp_file_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""]; +fts_ftp_file_api(suite) -> []; +fts_ftp_file_api(Config) -> + ?line {ok, Node} = create_node("ftp_file_api", 4004, normal), + file_helper(Config, 'FTP', ?TEST_DIR, Node, 4004, "ftp_file_api", tcp). + +fts_ftp_file_ssl_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""]; +fts_ftp_file_ssl_api(suite) -> []; +fts_ftp_file_ssl_api(Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + ?line {ok, Node} = create_node("ftp_file_api_ssl", {4005, 1}, ssl), + file_helper(Config, 'FTP', ?TEST_DIR, Node, 4005, "ftp_file_api_ssl", ssl) + end. + +fts_native_file_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""]; +fts_native_file_api(suite) -> []; +fts_native_file_api(Config) -> + ?line {ok, Node} = create_node("native_file_api", 4006, normal), + {ok, Pwd} = file:get_cwd(), + file_helper(Config,{'NATIVE', 'cosFileTransferNATIVE_file'},filename:split(Pwd), + Node, 4006, "native_file_api", tcp). + +fts_native_file_ssl_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""]; +fts_native_file_ssl_api(suite) -> []; +fts_native_file_ssl_api(Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + ?line {ok, Node} = create_node("native_file_ssl_api", {4007, 1}, ssl), + {ok, Pwd} = file:get_cwd(), + file_helper(Config,{'NATIVE', 'cosFileTransferNATIVE_file'},filename:split(Pwd), + Node, 4007, "native_file_ssl_api", ssl) + end. + + + +file_helper(Config, WhichType, TEST_DIR, Node, Port, Name, Type) -> + case ftp_host(Config) of + {skipped, SkippedReason} -> + {skipped, SkippedReason}; + Host -> + TEST_SOURCE = TEST_DIR ++ [create_name(remove_me_source)], + TEST_SOURCE2 = TEST_DIR ++ [create_name(remove_me_source)], + TEST_TARGET = TEST_DIR ++ [create_name(remove_me_target)], + + io:format("<<<<<< CosFileTransfer Testing Configuration >>>>>>~n",[]), + io:format("Source: ~p~nTarget: ~p~n", [TEST_SOURCE, TEST_TARGET]), + + ?line ?match(ok, remote_apply(Node, ?MODULE, install_data, + [Type, {WhichType, Host, Name}])), + + ?line VFST = ?match({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_}, + corba:string_to_object("corbaname::1.2@localhost:"++integer_to_list(Port)++"/NameService#"++Name)), + + + %% Create a Virtual File System. + ?line VFS = ?match({_,_,_,_,_,_}, + cosFileTransferApp:create_VFS(WhichType, [], Host, ?FTP_PORT, + [{protocol, Type}])), + %% Start two File Transfer Sessions (Source and Target). + ?line {FST, _DirT} = ?match({{_,_,_},{_,_,_}}, + 'CosFileTransfer_VirtualFileSystem':login(VFST, + ?FTP_USER, + ?FTP_PASS, + ?FTP_ACC)), + ?line {FSS, DirS} = ?match({{_,_,_,_,_,_},{_,_,_,_,_,_}}, + 'CosFileTransfer_VirtualFileSystem':login(VFS, + ?FTP_USER, + ?FTP_PASS, + ?FTP_ACC)), + + %% Do some basic test on one of the Directories attributes. + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(DirS)), + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(DirS)), + ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(DirS)), + ?line ?match(FSS, 'CosFileTransfer_Directory':'_get_associated_session'(DirS)), + + %% Get a FileList before we create any new Files + ?line #'CosFileTransfer_FileWrapper'{the_file = Dir} = + ?match({'CosFileTransfer_FileWrapper', _, ndirectory}, + 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_DIR)), + ?line {ok,FileList, Iter1} = ?match({ok,_,_}, 'CosFileTransfer_Directory':list(Dir, 10)), + ?line loop_files(FileList), + + case Iter1 of + {'IOP_IOR',[],[]} -> + ok; + _-> + ?line ?match(ok, 'CosFileTransfer_FileIterator':destroy(Iter1)) + end, + + #any{value=Count1} = ?match({any, _, _}, 'CosPropertyService_PropertySet': + get_property_value(Dir, "num_children")), + + %% Now we want to transfer a file from source to target. First, we'll create + %% a a file to work with. + ?line create_file_on_source_node(WhichType, Config, Host, + filename:join(TEST_SOURCE), TEST_DIR, + ?TEST_FILE_DATA), + ?line create_file_on_source_node(WhichType, Config, Host, + filename:join(TEST_SOURCE2), TEST_DIR, + ?TEST_FILE_DATA2), + + ?line #'CosFileTransfer_FileWrapper'{the_file = FileS} = + ?matchnopr({'CosFileTransfer_FileWrapper', _, nfile}, + 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_SOURCE)), + ?line #'CosFileTransfer_FileWrapper'{the_file = FileS2} = + ?matchnopr({'CosFileTransfer_FileWrapper', _, nfile}, + 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_SOURCE2)), + + #any{value=Count2} = ?match({any, _, _}, 'CosPropertyService_PropertySet': + get_property_value(Dir, "num_children")), + timer:sleep(2000), + ?match(true, (Count1+2 == Count2)), + + %% Create a target File + ?line FileT = ?matchnopr({_,_,_}, + 'CosFileTransfer_FileTransferSession':create_file(FST, TEST_TARGET)), + %% Try to delete the non-existing file. + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_FileTransferSession':delete(FST, FileT)), + + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':transfer(FSS, FileS, FileT)), + + %% Remove this test when ftp supports append. + case WhichType of + {'NATIVE', 'cosFileTransferNATIVE_file'} -> + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':append(FSS, FileS, FileT)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':insert(FSS, FileS2, FileT, 7)); + _-> + ok + end, + + %% Delete source and target files + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FSS, FileS)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FSS, FileS2)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FST, FileT)), + + %% Should be back where we started. + timer:sleep(2000), + #any{value=Count3} = ?match({any, _, _}, 'CosPropertyService_PropertySet': + get_property_value(Dir, "num_children")), + ?match(true, (Count1 == Count3)), + + + ?line ?match(false, corba_object:non_existent(FSS)), + ?line ?match(false, corba_object:non_existent(FST)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FSS)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FST)), + %% To make sure Orber can remove it from mnesia. + timer:sleep(2000), + ?line ?match(true, corba_object:non_existent(FSS)), + ?line ?match(true, corba_object:non_existent(FST)), + ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, [Name])), + stop_orber_remote(Node, normal), + ok + end. + +%%----------------------------------------------------------------- +%% FileTransferSession API tests +%%----------------------------------------------------------------- +fts_ftp_dir_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""]; +fts_ftp_dir_api(suite) -> []; +fts_ftp_dir_api(Config) -> + ?line {ok, Node} = create_node("ftp_dir_api", 4009, normal), + dir_helper(Config, 'FTP', ?TEST_DIR, Node, 4009, "ftp_dir_api"). + + +fts_native_dir_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""]; +fts_native_dir_api(suite) -> []; +fts_native_dir_api(Config) -> + ?line {ok, Node} = create_node("native_dir_api", 4010, normal), + {ok, Pwd} = file:get_cwd(), + dir_helper(Config, {'NATIVE', 'cosFileTransferNATIVE_file'}, + filename:split(Pwd), Node, 4010, "native_dir_api"). + +dir_helper(Config, WhichType, TEST_DIR, Node, Port, Name) -> + case ftp_host(Config) of + {skipped, SkippedReason} -> + {skipped, SkippedReason}; + Host -> + TEST_DIR_LEVEL1 = TEST_DIR ++ [create_name(remove_me_dir1)], + TEST_DIR_LEVEL2 = TEST_DIR_LEVEL1 ++ [create_name(remove_me_dir2)], + + io:format("<<<<<< CosFileTransfer Testing Configuration >>>>>>~n",[]), + io:format("Top Dir: ~p~nLevel2 Dir: ~p~n", [TEST_DIR_LEVEL1, TEST_DIR_LEVEL2]), + + ?line ?match(ok, remote_apply(Node, ?MODULE, install_data, + [tcp, {WhichType, Host, Name}])), + + ?line VFS = ?matchnopr({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_}, + corba:string_to_object("corbaname::1.2@localhost:"++integer_to_list(Port)++"/NameService#"++Name)), + + %% Start two File Transfer Sessions (Source and Target). + ?line {FS, DirS} = ?matchnopr({{'IOP_IOR',_,_}, _}, + 'CosFileTransfer_VirtualFileSystem':login(VFS, + ?FTP_USER, + ?FTP_PASS, + ?FTP_ACC)), + + %% Do some basic test on one of the Directories attributes. + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(DirS)), + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(DirS)), + ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(DirS)), + ?line ?matchnopr(FS, 'CosFileTransfer_Directory':'_get_associated_session'(DirS)), + + %% Create a Root Directory. Currently we only need to create one but + %% later on, when supporting other protocols than FTP it's not enough. + ?line Dir1 = 'CosFileTransfer_FileTransferSession':create_directory(FS, + TEST_DIR_LEVEL1), + io:format("<<<<<< CosFileTransfer Testing Properties >>>>>>~n",[]), + ?line ?match({ok, [tk_long, tk_boolean]}, + 'CosFileTransfer_Directory':get_allowed_property_types(Dir1)), + ?line ?match({ok, [_,_]}, + 'CosFileTransfer_Directory':get_allowed_properties(Dir1)), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property_with_mode(Dir1, + "num_children", + #any{typecode=tk_long, value=0}, + fixed_readonly)), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property_with_mode(Dir1, + "wrong", + #any{typecode=tk_long, value=0}, + fixed_readonly)), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property_with_mode(Dir1, + "num_children", + #any{typecode=tk_short, value=0}, + fixed_readonly)), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property_with_mode(Dir1, + "num_children", + #any{typecode=tk_long, value=0}, + fixed_normal)), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_properties_with_modes(Dir1, + [#'CosPropertyService_PropertyDef' + {property_name = "num_children", + property_value = #any{typecode=tk_long, value=0}, + property_mode = fixed_readonly}])), + ?line ?match(fixed_readonly, + 'CosFileTransfer_Directory':get_property_mode(Dir1, "num_children")), + ?line ?match({true, + [#'CosPropertyService_PropertyMode'{property_name = "num_children", + property_mode = fixed_readonly}]}, + 'CosFileTransfer_Directory':get_property_modes(Dir1, ["num_children"])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':set_property_mode(Dir1, "num_children", fixed_readonly)), + + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + set_property_modes(Dir1, + [#'CosPropertyService_PropertyMode' + {property_name = "num_children", + property_mode = fixed_readonly}])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + set_property_modes(Dir1, + [#'CosPropertyService_PropertyMode' + {property_name = "wrong", + property_mode = fixed_readonly}])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + set_property_modes(Dir1, + [#'CosPropertyService_PropertyMode' + {property_name = "num_children", + property_mode = fixed_normal}])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property(Dir1, + "num_children", + #any{typecode=tk_long, value=0})), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property(Dir1, + "wrong", + #any{typecode=tk_long, value=0})), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property(Dir1, + "num_children", + #any{typecode=tk_short, value=0})), + + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property(Dir1, + "num_children", + #any{typecode=tk_long, value=0})), + + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + define_properties(Dir1, + [#'CosPropertyService_Property' + {property_name = "num_children", + property_value = #any{typecode=tk_long, + value=0}}])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + define_properties(Dir1, + [#'CosPropertyService_Property' + {property_name = "wrong", + property_value = #any{typecode=tk_long, + value=0}}])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + define_properties(Dir1, + [#'CosPropertyService_Property' + {property_name = "num_children", + property_value = #any{typecode=tk_short, + value=0}}])), + ?line ?match(2, 'CosFileTransfer_Directory':get_number_of_properties(Dir1)), + + ?line ?match({ok, ["num_children", "is_directory"], {'IOP_IOR',[],[]}}, + 'CosFileTransfer_Directory':get_all_property_names(Dir1, 2)), + ?line ?match({ok, ["is_directory"], _}, + 'CosFileTransfer_Directory':get_all_property_names(Dir1, 1)), + + ?line ?match(#any{}, + 'CosFileTransfer_Directory':get_property_value(Dir1, "num_children")), + ?line ?match(#any{}, + 'CosFileTransfer_Directory':get_property_value(Dir1, "is_directory")), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':get_property_value(Dir1, "wrong")), + + ?line ?match({true, + [#'CosPropertyService_Property'{property_name = "num_children"}]}, + 'CosFileTransfer_Directory':get_properties(Dir1, ["num_children"])), + ?line ?match({false, + [#'CosPropertyService_Property'{property_name = "wrong"}]}, + 'CosFileTransfer_Directory':get_properties(Dir1, ["wrong"])), + + ?line ?match({ok, [_],_}, + 'CosFileTransfer_Directory':get_all_properties(Dir1, 1)), + ?line ?match({ok, [_,_], {'IOP_IOR',[],[]}}, + 'CosFileTransfer_Directory':get_all_properties(Dir1, 2)), + + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':delete_property(Dir1, "num_children")), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':delete_property(Dir1, "wrong")), + + + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':delete_properties(Dir1, ["num_children"])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':delete_properties(Dir1, ["wrong"])), + ?line ?match(false, 'CosFileTransfer_Directory':delete_all_properties(Dir1)), + ?line ?match(true, + 'CosFileTransfer_Directory':is_property_defined(Dir1, "num_children")), + ?line ?match(false, + 'CosFileTransfer_Directory':is_property_defined(Dir1, "wrong")), + + %% The Top Dir should be empty and ... + ?line ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir1, 1000)), + ?line ?match( #any{value=0}, + 'CosPropertyService_PropertySet':get_property_value(Dir1, "num_children")), + %% Create a sub-directory. + ?line Dir2 = 'CosFileTransfer_FileTransferSession':create_directory(FS, + TEST_DIR_LEVEL2), + ?line ?match( #any{value=1}, + 'CosPropertyService_PropertySet':get_property_value(Dir1, "num_children")), + + ?line ?match({ok, [_,_], {'IOP_IOR',[],[]}}, + 'CosFileTransfer_Directory':get_all_properties(Dir1, 2)), + ?line {_,_,Iterator1} = ?match({ok, [_], _}, + 'CosFileTransfer_Directory':get_all_properties(Dir1, 1)), + ?line ?match({false, [_]}, + 'CosPropertyService_PropertiesIterator':next_n(Iterator1,4)), + + ?line {_,_,Iterator0} = ?match({ok, [], _}, + 'CosFileTransfer_Directory':get_all_properties(Dir1, 0)), + + ?line ?match({false, [_, {'CosPropertyService_Property', + "num_children",{any,tk_long,1}}]}, + 'CosPropertyService_PropertiesIterator':next_n(Iterator0,4)), + + ?line ?match({true, + [#'CosPropertyService_Property'{property_name = "num_children"}]}, + 'CosFileTransfer_Directory':get_properties(Dir1, ["num_children"])), + + %% The Top Directory is not emtpy any more and ... + ?line {ok,[#'CosFileTransfer_FileWrapper'{the_file = DirRef}],_} = + ?matchnopr({ok,[{'CosFileTransfer_FileWrapper', _, ndirectory}],_}, + 'CosFileTransfer_Directory':list(Dir1, 1000)), + %% ... its name eq. to 'TEST_DIR_LEVEL2' + ?line ?match(TEST_DIR_LEVEL2, + 'CosFileTransfer_Directory':'_get_complete_file_name'(DirRef)), + + ?line #'CosFileTransfer_FileWrapper'{the_file = Dir3} = + ?matchnopr({'CosFileTransfer_FileWrapper', _, ndirectory}, + 'CosFileTransfer_FileTransferSession':get_file(FS, TEST_DIR_LEVEL1)), + + %% Must get the same result for the 'get_file' operation. + ?line {ok,[#'CosFileTransfer_FileWrapper'{the_file = DirRef2}],_} = + ?matchnopr({ok,[{'CosFileTransfer_FileWrapper', _, ndirectory}],_}, + 'CosFileTransfer_Directory':list(Dir3,1000)), + ?line ?match(TEST_DIR_LEVEL2, + 'CosFileTransfer_Directory':'_get_complete_file_name'(DirRef2)), + + %% Since the top directory isn't empty deleting it must fail. + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_FileTransferSession':delete(FS, Dir1)), + + %% Delete the sub-directory and ... + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FS, Dir2)), + %% ... see if the top directory realyy is empty. + ?line ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir1, 1000)), + + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FS, Dir1)), + %% Test if the top directory been removed as intended. + ?line ?match({'EXCEPTION', {'CosFileTransfer_FileNotFoundException', _, _}}, + 'CosFileTransfer_FileTransferSession':get_file(FS, TEST_DIR_LEVEL1)), + + ?line ?match(false, corba_object:non_existent(FS)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FS)), + %% To make sure Orber can remove it from mnesia. + timer:sleep(1000), + ?line ?match(true, corba_object:non_existent(FS)), + ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, [Name])), + stop_orber_remote(Node, normal), + ok + end. + + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- +ftp_host(Config) -> + case ?config(ftp_remote_host, Config) of + undefined -> + {skipped, "The configuration parameter 'ftp_remote_host' not defined."}; + Host -> + Host + end. + +loop_files([]) -> + io:format("@@@ DONE @@@~n", []); +loop_files([#'CosFileTransfer_FileWrapper'{the_file = H}|T]) -> + FullName = 'CosFileTransfer_File':'_get_complete_file_name'(H), + Name = 'CosFileTransfer_File':'_get_name'(H), + io:format("FULL NAME: ~p SHORT NAME: ~p~n", [FullName, Name]), + loop_files(T). + + +create_file_on_source_node('FTP', _Config, Host, FileName, Path, Data) -> + io:format("<<<<<< CosFileTransfer Testing File >>>>>>~n",[]), + io:format("Host: ~p~nPath: ~p~nFile: ~p~n", [Host, Path, FileName]), + {ok, Pid} = ?match({ok, _}, inets:start(ftpc, [{host, Host}], stand_alone)), + ?match(ok, ftp:user(Pid, ?FTP_USER, ?FTP_PASS)), + ?match(ok, ftp:cd(Pid, Path)), + ?match(ok, ftp:send_bin(Pid, list_to_binary(Data), FileName)), + ?match(ok, inets:stop(ftpc, Pid)); +create_file_on_source_node({'NATIVE', _}, _Config, Host, FileName, Path, Data) -> + io:format("<<<<<< CosFileTransfer Testing File >>>>>>~n",[]), + io:format("Host: ~p~nPath: ~p~nFile: ~p~n", [Host, Path, FileName]), + ?match(ok, file:write_file(FileName, list_to_binary(Data))). + +create_name(Type) -> + {MSec, Sec, USec} = erlang:now(), + lists:concat([Type,'_',MSec, '_', Sec, '_', USec]). + + + + +%%------------------------------------------------------------ +%% function : create_node/4 +%% Arguments: Name - the name of the new node (atom()) +%% Port - which iiop_port (integer()) +%% Domain - which domain. +%% Type - if /4 used the types defines the extra arguments +%% to be used. +%% Returns : {ok, Node} | {error, _} +%% Effect : Starts a new slave-node with given (optinally) +%% extra arguments. If fails it retries 'Retries' times. +%%------------------------------------------------------------ +create_node(Name, Port, normal) -> + Args = basic_args(Name), + create_node(Name, Port, 10, normal, Args, []); +create_node(Name, {Port, _Depth}, ssl) -> + Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), + Args = basic_args(Name), + {ok, Node} = create_node(list_to_atom(Name), Port, 10, ssl, Args, []), + %% Client + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_certfile, + filename:join([Dir, "client", "cert.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_cacertfile, + filename:join([Dir, "client", "cacerts.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_keyfile, + filename:join([Dir, "client", "key.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_verify, 1]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_depth, 0]), + + %% Server + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_certfile, + filename:join([Dir, "server", "cert.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_cacertfile, + filename:join([Dir, "server", "cacerts.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_keyfile, + filename:join([Dir, "server", "key.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_verify, 1]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_depth, 0]), + {ok, Node}. + +%create_node(Name, {Port, Depth}, ssl) -> +% TestLibs = filename:join(filename:dirname(code:which(?MODULE)), "ssl_data"), +% Args = basic_args(Name), +% SArgs = basic_ssl_args(TestLibs, Args), +% LArgs = level_based_ssl(Depth, TestLibs, SArgs), +% create_node(list_to_atom(Name), Port, 10, ssl, LArgs, [{sslpath, TestLibs}]). + +create_node(Name, Port, Retries, Type, Args, Options) -> + [_, Host] = ?match([_,_],string:tokens(atom_to_list(node()), [$@])), + case starter(Host, Name, Args) of + {ok, NewNode} -> + ?line ?match(pong, net_adm:ping(NewNode)), + {ok, Cwd} = file:get_cwd(), + Path = code:get_path(), + ?line ?match(ok, rpc:call(NewNode, file, set_cwd, [Cwd])), + true = rpc:call(NewNode, code, set_path, [Path]), + ?match(ok, start_orber_remote(NewNode, Type, Options, Port)), + spawn_link(NewNode, ?MODULE, slave_sup, []), + rpc:multicall([node() | nodes()], global, sync, []), + {ok, NewNode}; + {error, Reason} when Retries == 0-> + {error, Reason}; + {error, Reason} -> + io:format("Could not start slavenode ~p ~p retrying~n", + [{Host, Name, Args}, Reason]), + timer:sleep(500), + create_node(Name, Port, Retries - 1, Type, Args, Options) + end. + +starter(Host, Name, Args) -> + case os:type() of + vxworks -> + test_server:start_node(Name, slave, [{args,Args}]); + _ -> + slave:start(Host, Name, Args) + end. + +slave_sup() -> + process_flag(trap_exit, true), + receive + {'EXIT', _, _} -> + case os:type() of + vxworks -> + erlang:halt(); + _ -> + ignore + end + end. + + +%%------------------------------------------------------------ +%% function : destroy_node +%% Arguments: Node - which node to destroy. +%% Type - normal | ssl +%% Returns : +%% Effect : +%%------------------------------------------------------------ +-ifdef(false). +destroy_node(Node, Type) -> + stopper(Node, Type). + +stopper(Node, Type) -> + catch stop_orber_remote(Node, Type), + case os:type() of + vxworks -> + test_server:stop_node(Node); + _ -> + slave:stop(Node) + end. +-endif. + +%%------------------------------------------------------------ +%% function : remote_apply +%% Arguments: N - Node, M - Module, +%% F - Function, A - Arguments (list) +%% Returns : +%% Effect : +%%------------------------------------------------------------ +remote_apply(N, M,F,A) -> + case rpc:call(N, M, F, A) of + {badrpc, Reason} -> + exit(Reason); + Other -> + Other + end. + +%%------------------------------------------------------------ +%% function : stop_orber_remote +%% Arguments: Node - which node to stop orber on. +%% Type - normal | ssl | light | ....... +%% Returns : ok +%% Effect : Stops orber on given node and, if specified, +%% other applications or programs. +%%------------------------------------------------------------ +stop_orber_remote(Node, ssl) -> + rpc:call(Node, ssl, stop, []), + rpc:call(Node, crypto, stop, []), + orb_rpc_blast(Node, ssl); +stop_orber_remote(Node, Type) -> + orb_rpc_blast(Node, Type). + +orb_rpc_blast(Node, _) -> + rpc:call(Node, cosFileTransferApp, stop, []), + rpc:call(Node, cosProperty, stop, []), + rpc:call(Node, cosFileTransferApp, uninstall, []), + rpc:call(Node, cosProperty, uninstall, []), + rpc:call(Node, orber, jump_stop, []). + +%%------------------------------------------------------------ +%% function : start_orber_remote +%% Arguments: Node - which node to start orber on. +%% Type - normal | ssl | light | ....... +%% Returns : ok +%% Effect : Starts orber on given node and, if specified, +%% other applications or programs. +%%------------------------------------------------------------ +start_orber_remote(Node, ssl, _Options, Port) -> + rpc:call(Node, ssl, start, []), + rpc:call(Node, crypto, start, []), + rpc:call(Node, ssl, seed, ["testing"]), + orb_rpc_setup(Node, ssl, Port); +start_orber_remote(Node, Type, _, Port) -> + orb_rpc_setup(Node, Type, Port). + +orb_rpc_setup(Node, _, Port) -> + rpc:call(Node, orber, jump_start, [Port]), + rpc:call(Node, cosProperty, install, []), + rpc:call(Node, cosProperty, start, []), + rpc:call(Node, cosFileTransferApp, install, []). + +%%--------------- MISC FUNCTIONS ----------------------------- +basic_args(_Name) -> + TestLibs = filename:dirname(code:which(?MODULE)), + " -orber orber_debug_level 10" ++ + " -pa " ++ + TestLibs ++ + " -pa " ++ + filename:join(TestLibs, "all_SUITE_data") ++ + " -pa " ++ + filename:dirname(code:which(cosFileTransferApp)). + +-ifdef(false). +basic_ssl_args(TestLibs, Args) -> +% Args ++ +% " -cosFileTransfer ssl_client_certfile \\\"" ++ +% filename:join(TestLibs, "ssl_client_cert.pem") ++ +% "\\\" -cosFileTransfer ssl_server_certfile \\\""++ +% filename:join(TestLibs, "ssl_server_cert.pem")++"\\\"". + + io:format("<<<<<< SSL LIBS ~p >>>>>>~n",[TestLibs]), + NewArgs = Args ++ + " -cosFileTransfer ssl_client_certfile \\\"" ++ + filename:join(TestLibs, "ssl_client_cert.pem") ++ + "\\\" -cosFileTransfer ssl_server_certfile \\\""++ + filename:join(TestLibs, "ssl_server_cert.pem")++"\\\"", + io:format("<<<<<< SSL LIBS ARGS ~p >>>>>>~n",[NewArgs]), + NewArgs. + +level_based_ssl(1, _TestLibs, Args) -> + Args; +level_based_ssl(2, _TestLibs, Args) -> + Args.% ++ +% " -cosFileTransfer ssl_server_depth 2 " ++ +% " -cosFileTransfer ssl_client_depth 2 " ++ +% " -cosFileTransfer ssl_server_verify " ++ +% " -cosFileTransfer ssl_client_verify " ++ +% " -cosFileTransfer ssl_server_cacertfile " ++ +% " -cosFileTransfer ssl_client_cacertfile " ++ + +-endif. + +install_data(Protocol, {WhichType, Host, Name}) -> + io:format("<<<<<< Starting ~p/~p VFS at ~p/~p>>>>>>~n", + [Protocol, WhichType, Host, Name]), + %% Create a Virtual File System. + ?line VFS = ?match({_,_,_,_,_,_}, + cosFileTransferApp:create_VFS(WhichType, [], Host, ?FTP_PORT, + [{protocol, Protocol}])), + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), Name), + N = lname:insert_component(lname:create(), 1, NC1), + 'CosNaming_NamingContext':rebind(NS, N, VFS). + +uninstall_data(Name) -> + ?line VFS = ?match({_,_,_,_,_,_}, + corba:string_to_object("corbaname:rir:/NameService#"++Name)), + ?line ?match(ok, corba:dispose(VFS)), + ok. + + + +%%------------------- EOF MODULE----------------------------------- diff --git a/lib/cosNotification/test/Makefile b/lib/cosNotification/test/Makefile new file mode 100644 index 0000000000..df8f9e919b --- /dev/null +++ b/lib/cosNotification/test/Makefile @@ -0,0 +1,190 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1999-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSNOTIFICATION_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/cosNotification_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = cosNotification.spec + + +IDL_FILES = + +IDLOUTDIR = idl_output + +MODULES = \ + notification_SUITE \ + grammar_SUITE \ + eventDB_SUITE \ + generated_SUITE \ + notify_test_impl + +GEN_MODULES = \ + oe_notify_test_server \ + notify_test_data \ + notify_test_computer \ + notify_test_studies \ + notify_test_ShortArray \ + notify_test_uni1 \ + notify_test_uni2 \ + notify_test_X \ + notify_test_K \ + notify_test_SeqPushC \ + notify_test_StrPushC \ + notify_test_AnyPushC \ + notify_test_SeqPullC \ + notify_test_StrPullC \ + notify_test_AnyPullC \ + notify_test_SeqPushS \ + notify_test_StrPushS \ + notify_test_AnyPushS \ + notify_test_SeqPullS \ + notify_test_StrPullS \ + notify_test_AnyPullS \ + notify_test_funcs + +GEN_HRL_FILES = \ + oe_notify_test_server.hrl \ + notify_test_SeqPushC.hrl \ + notify_test_StrPushC.hrl \ + notify_test_AnyPushC.hrl \ + notify_test_SeqPullC.hrl \ + notify_test_StrPullC.hrl \ + notify_test_AnyPullC.hrl \ + notify_test_SeqPushS.hrl \ + notify_test_StrPushS.hrl \ + notify_test_AnyPushS.hrl \ + notify_test_SeqPullS.hrl \ + notify_test_StrPullS.hrl \ + notify_test_AnyPullS.hrl \ + notify_test.hrl \ + notify_test_funcs.hrl + +ERL_FILES = $(MODULES:%=%.erl) + +HRL_FILES = + +GEN_FILES = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl) + +GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR)) + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(GEN_TARGET_FILES) \ + $(SUITE_TARGET_FILES) + + +# ---------------------------------------------------- +# PROGRAMS +# ---------------------------------------------------- +LOCAL_CLASSPATH = $(ERL_TOP)lib/cosNotification/priv:$(ERL_TOP)lib/cosNotification/test +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += \ + -pa $(ERL_TOP)/lib/cosNotification/ebin \ + -pa $(ERL_TOP)/lib/cosNotification/src \ + -pa $(ERL_TOP)/lib/cosTime/ebin \ + -pa $(ERL_TOP)/lib/cosTime/include \ + -pa $(ERL_TOP)/lib/orber/ebin \ + -pa $(ERL_TOP)/lib/ic/ebin \ + -pa $(ERL_TOP)/lib/cosNotification/include \ + -I$(ERL_TOP)/lib/cosEvent/src \ + -I$(ERL_TOP)/lib/cosNotification/include \ + +ERL_COMPILE_FLAGS += \ + $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/orber/include \ + -pa $(ERL_TOP)/internal_tools/test_server/ebin \ + -pa $(ERL_TOP)/lib/cosNotification/ebin \ + -pa $(ERL_TOP)/lib/cosNotification/test/idl_output \ + -pa $(ERL_TOP)/lib/cosTime/ebin \ + -pa $(ERL_TOP)/lib/cosTime/include \ + -pa $(ERL_TOP)/lib/cosNotification/include \ + -pa $(ERL_TOP)/lib/ic/ebin \ + -I$(ERL_TOP)/lib/cosTime/ebin \ + -I$(ERL_TOP)/lib/cosTime/include \ + -I$(ERL_TOP)/lib/orber/include \ + -I$(ERL_TOP)/lib/cosNotification/src \ + -I$(ERL_TOP)/lib/cosNotification/include \ + -I$(ERL_TOP)/lib/cosNotification \ + -I$(ERL_TOP)/lib/cosNotification/test/$(IDLOUTDIR) \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + + +tests debug opt: $(TARGET_FILES) + +clean: + rm -f idl_output/* + rm -f $(TARGET_FILES) + rm -f errs core *~ + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + +TGT_TEST = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl) + +$(TGT_TEST): notify_test_server.idl + erlc $(ERL_COMPILE_FLAGS) -o$(IDLOUTDIR) \ + +'{cfgfile,"notify_test_server.cfg"}' notify_test_server.idl + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +# We don't copy generated intermediate erlang and hrl files + +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ + $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) + $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ + $(RELSYSDIR)/$(IDLOUTDIR) + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + diff --git a/lib/cosNotification/test/cosNotification.spec b/lib/cosNotification/test/cosNotification.spec new file mode 100644 index 0000000000..8df89e7908 --- /dev/null +++ b/lib/cosNotification/test/cosNotification.spec @@ -0,0 +1,19 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +{topcase, {dir, "../cosNotification_test"}}. diff --git a/lib/cosNotification/test/eventDB_SUITE.erl b/lib/cosNotification/test/eventDB_SUITE.erl new file mode 100644 index 0000000000..9ddfb3d902 --- /dev/null +++ b/lib/cosNotification/test/eventDB_SUITE.erl @@ -0,0 +1,902 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%-------------------------------------------------------------------- +%% File : eventDB_SUITE.erl +%% Purpose : +%%-------------------------------------------------------------------- + +-module(eventDB_SUITE). +%%--------------- INCLUDES ----------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/include/ifr_types.hrl"). +%% cosEvent files. +-include_lib("cosEvent/include/CosEventChannelAdmin.hrl"). +%% cosTime files. +-include_lib("cosTime/include/TimeBase.hrl"). +%% Application files +-include_lib("cosNotification/include/CosNotification.hrl"). +-include_lib("cosNotification/include/CosNotifyChannelAdmin.hrl"). +-include_lib("cosNotification/include/CosNotifyComm.hrl"). +-include_lib("cosNotification/include/CosNotifyFilter.hrl"). + +-include_lib("cosNotification/src/CosNotification_Definitions.hrl"). + +-include("idl_output/notify_test.hrl"). + +-include("test_server.hrl"). + +%%--------------- DEFINES ------------------------------------ +-define(default_timeout, ?t:minutes(20)). +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + + +-define(EVENT1, ?not_CreateSE("","event1","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), 0)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=900000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=900000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="Timeout", + value=any:create(orber_tc:unsigned_long_long(), 900000000)}], + [], any:create(orber_tc:null(), null))). +-define(EVENT2, ?not_CreateSE("","event2","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), 0)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=800000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=800000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="Timeout", + value=any:create(orber_tc:unsigned_long_long(), 800000000)}], + [], any:create(orber_tc:null(), null))). +-define(EVENT3, ?not_CreateSE("","event3","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), 0)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=700000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=700000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="Timeout", + value=any:create(orber_tc:unsigned_long_long(), 700000000)}], + [], any:create(orber_tc:null(), null))). +-define(EVENT4, ?not_CreateSE("","event4","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), 2)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=300000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=300000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="Timeout", + value=any:create(orber_tc:unsigned_long_long(), 300000000)}], + [], any:create(orber_tc:null(), null))). +-define(EVENT5, ?not_CreateSE("","event5","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), 2)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=200000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=200000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="Timeout", + value=any:create(orber_tc:unsigned_long_long(), 200000000)}], + [], any:create(orber_tc:null(), null))). +-define(EVENT6, ?not_CreateSE("","event6","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), 0)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=500000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=500000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="Timeout", + value=any:create(orber_tc:unsigned_long_long(), 500000000)}], + [], any:create(orber_tc:null(), null))). +-define(EVENT7, ?not_CreateSE("","event7","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), -1)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=400000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=400000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="Timeout", + value=any:create(orber_tc:unsigned_long_long(), 400000000)}], + [], any:create(orber_tc:null(), null))). +-define(EVENT8, ?not_CreateSE("","event8","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), -1)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=600000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=600000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="Timeout", + value=any:create(orber_tc:unsigned_long_long(), 600000000)}], + [], any:create(orber_tc:null(), null))). +-define(EVENT9, ?not_CreateSE("","event9","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), 0)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=100000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), + #'TimeBase_UtcT' + {time=100000000, + inacclo=0, inacchi=0, tdf=2})}, + #'CosNotification_Property' + {name="Timeout", + value=any:create(orber_tc:unsigned_long_long(), 100000000)}], + [], any:create(orber_tc:null(), null))). + +-define(EVENTS, [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5, ?EVENT6, ?EVENT7, + ?EVENT8, ?EVENT9]). + + +-define(PRIOORDER, [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3, ?EVENT6, ?EVENT9, + ?EVENT7, ?EVENT8]). + +-define(FIFOORDER, ?EVENTS). + +-define(DEADLINEORDER, [?EVENT9, ?EVENT5, ?EVENT4, ?EVENT7, ?EVENT6, ?EVENT8, ?EVENT3, + ?EVENT2, ?EVENT1]). + +-define(NO_OF_EVENTS, 9). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, reorder_api/1, lookup_api/1, + discard_api/1, max_events_api/1, gc_api/1, auto_gc_api/1, + start_stop_time_api/1, mapping_filter_api/1, persisten_event_api/1, + init_per_testcase/2, fin_per_testcase/2]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for the cosNotification interfaces", ""]; +all(suite) -> {req, + [mnesia, orber], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [persisten_event_api, start_stop_time_api, mapping_filter_api, + max_events_api, discard_api, reorder_api, lookup_api, gc_api, + auto_gc_api]. + + + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + orber:jump_start(), + cosTime:install_time(), + cosTime:start(), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + cosTime:stop(), + cosTime:uninstall_time(), + orber:jump_stop(), + Config. + + +%%----------------------------------------------------------------- +%% cosNotification_eventDB lookup API tests +%%----------------------------------------------------------------- +mapping_filter_api(doc) -> ["The event DB is used to store events which cannot be", + "delivered at once. This case is supposed to test", + "that the events are delivered in the correct order", + "if a MappingFilter have benn associated.", + ""]; +mapping_filter_api(suite) -> []; +mapping_filter_api(_Config) -> + InitQoS = ?not_CreateInitQoS(), + InitQoS2 = ?not_SetMaxEventsPerConsumer(InitQoS,100), + InitQoS3 = ?not_SetStartTimeSupported(InitQoS2, false), + InitQoS4 = ?not_SetStopTimeSupported(InitQoS3, true), + QoS = ?not_SetDiscardPolicy(InitQoS4, ?not_AnyOrder), + + PriorityQoS = ?not_SetOrderPolicy(QoS, ?not_PriorityOrder), + DeadlineQoS = ?not_SetOrderPolicy(QoS, ?not_DeadlineOrder), + + %% "Calculate" data once: + %% NOTE! Even though the an Event do not match any of the constarints the + %% default value will be used. Hence, the events will not be stored in the + %% way described in the definitions above. For example, when using deadline order + %% all the events will be stored in FIFO order since the usag of a MappingFilter + %% all evnts will have the same deadline (except event6). + Events = ?EVENTS, + PrioOrder = [?EVENT6, ?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5, ?EVENT7, + ?EVENT8, ?EVENT9], + DeadlineOrder = [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5, ?EVENT7, ?EVENT8, + ?EVENT9], + + + FiFac = 'CosNotifyFilter_FilterFactory':oe_create(), + ?match({_,key,_,_,_,_}, FiFac), + + PrioFilter = 'CosNotifyFilter_FilterFactory': + create_mapping_filter(FiFac, "EXTENDED_TCL", any:create(orber_tc:short(), 0)), + DLFilter = 'CosNotifyFilter_FilterFactory': + create_mapping_filter(FiFac, "EXTENDED_TCL", any:create(orber_tc:unsigned_long_long(), 1000000000)), + + ?match([_], + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(PrioFilter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "", + type_name = "event6"}], + constraint_expr = "2==2"}, + result_to_set = any:create(orber_tc:short(), 10)}])), + ?match([_], + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(DLFilter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "", + type_name = "event6"}], + constraint_expr = "2==2"}, + result_to_set = any:create(orber_tc:unsigned_long_long(), 200000000)}])), + + + do_lookup(PriorityQoS, Events, PrioOrder, "Priority Order", undefined, PrioFilter, 0), + do_lookup(DeadlineQoS, Events, DeadlineOrder, "Deadline Order", DLFilter, undefined, 23000), + ok. + +do_lookup(QoS, Events, Return, Txt, DLFilter, PrioFilter, Timeout) -> + io:format("#################### ~s ###################~n", [Txt]), + Ref = cosNotification_eventDB:create_db(QoS, 60, 50, undefined), + create_loop(Events, Ref, DLFilter, PrioFilter), + timer:sleep(Timeout), + ?match({Return,_}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + cosNotification_eventDB:destroy_db(Ref). + +%%----------------------------------------------------------------- +%% cosNotification_eventDB discard API tests +%%----------------------------------------------------------------- +discard_api(doc) -> ["The event DB is used to store events which cannot be", + "delivered at once. If MaxEvents limit is reached there", + "different ways we can discard the. This case will test", + "all permutations of order and discard policies.", + ""]; +discard_api(suite) -> []; +discard_api(_Config) -> + InitQoS1 = ?not_CreateInitQoS(), + InitQoS2 = ?not_SetPriority(InitQoS1, 10), + InitQoS3 = ?not_SetStartTimeSupported(InitQoS2, false), + QoS = ?not_SetMaxEventsPerConsumer(InitQoS3, 5), + %% The different order policies. To each order we must apply every possible + %% discard policy to each order policy setting. We also have to test and + %% change the policies for each setting. + AnyQoS = ?not_SetOrderPolicy(QoS, ?not_AnyOrder), + PriorityQoS = ?not_SetOrderPolicy(QoS, ?not_PriorityOrder), + FifoQoS = ?not_SetOrderPolicy(QoS, ?not_FifoOrder), + DeadlineQoS = ?not_SetOrderPolicy(QoS, ?not_DeadlineOrder), + + Events = ?EVENTS, + + %% Test using Any discard policy + do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_AnyOrder), + [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3], + "Discard and Order eq. Any"), + do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_AnyOrder), + [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3], + "Discard Any and Order Priority"), + do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_AnyOrder), + [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5], + "Discard Any and Order Fifo"), + do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_AnyOrder), + [?EVENT5, ?EVENT4, ?EVENT3, ?EVENT2, ?EVENT1], + "Discard Any and Order Deadline"), + + %% Test using RejectNewEvents discard policy + do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_RejectNewEvents), + [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3], + "Discard RejectNewEvents and Order Any"), + do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_RejectNewEvents), + [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3], + "Discard RejectNewEvents and Order Priority"), + do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_RejectNewEvents), + [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5], + "Discard RejectNewEvents and Order Fifo"), + do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_RejectNewEvents), + [?EVENT5, ?EVENT4, ?EVENT3, ?EVENT2, ?EVENT1], + "Discard RejectNewEvents and Order Deadline"), + + %% Test using Lifo discard policy + do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_LifoOrder), + [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3], + "Discard Lifo and Order Any"), + do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_LifoOrder), + [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3], + "Discard Lifo and Order Priority"), + do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_LifoOrder), + [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5], + "Discard Lifo and Order Fifo"), + do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_LifoOrder), + [?EVENT5, ?EVENT4, ?EVENT3, ?EVENT2, ?EVENT1], + "Discard Lifo and Order Deadline"), + + %% Test using Fifo discard policy + do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_FifoOrder), + [?EVENT5, ?EVENT6, ?EVENT9, ?EVENT7, ?EVENT8], + "Discard Fifo and Order Any"), + do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_FifoOrder), + [?EVENT5, ?EVENT6, ?EVENT9, ?EVENT7, ?EVENT8], + "Discard Fifo and Order Priority"), + do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_FifoOrder), + [?EVENT5, ?EVENT6, ?EVENT7, ?EVENT8, ?EVENT9], + "Discard Fifo and Order Fifo"), + do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_FifoOrder), + [?EVENT9, ?EVENT5, ?EVENT7, ?EVENT6, ?EVENT8], + "Discard Fifo and Order Deadline"), + + %% Test using Priority discard policy + do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_PriorityOrder), + [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3], + "Discard Priority and Order Any"), + do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_PriorityOrder), + [?EVENT4, ?EVENT5, ?EVENT1, ?EVENT2, ?EVENT3], + "Discard Priority and Order Priority"), + do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_PriorityOrder), + [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5], + "Discard Priority and Order Fifo"), + do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_PriorityOrder), + [?EVENT5, ?EVENT4, ?EVENT3, ?EVENT2, ?EVENT1], + "Discard Priority and Order Deadline"), + + %% Test using Deadline discard policy + do_discard(Events, ?not_SetDiscardPolicy(AnyQoS, ?not_DeadlineOrder), + [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT6, ?EVENT8], + "Discard Deadline and Order Any"), + do_discard(Events, ?not_SetDiscardPolicy(PriorityQoS, ?not_DeadlineOrder), + [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT6, ?EVENT8], + "Discard Deadline and Order Priority"), + do_discard(Events, ?not_SetDiscardPolicy(FifoQoS, ?not_DeadlineOrder), + [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT6, ?EVENT8], + "Discard Deadline and Order Fifo"), + do_discard(Events, ?not_SetDiscardPolicy(DeadlineQoS, ?not_DeadlineOrder), + [?EVENT6, ?EVENT8, ?EVENT3, ?EVENT2, ?EVENT1], + "Discard Deadline and Order Deadline"), + + ok. + +do_discard(Events, QoS, Reply, Txt) -> + io:format("################# ~s #################~n", [Txt]), + Ref = cosNotification_eventDB:create_db(QoS, 60, 50, undefined), + create_loop(Events, Ref), + ?match({Reply,_}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + cosNotification_eventDB:destroy_db(Ref). + + +%%----------------------------------------------------------------- +%% cosNotification_eventDB lookup API tests +%%----------------------------------------------------------------- +lookup_api(doc) -> ["The event DB is used to store events which cannot be", + "delivered at once. This case is supposed to test", + "that the events are delivered in the correct order.", + ""]; +lookup_api(suite) -> []; +lookup_api(_Config) -> + InitQoS = ?not_CreateInitQoS(), + InitQoS2 = ?not_SetMaxEventsPerConsumer(InitQoS,100), + InitQoS3 = ?not_SetStartTimeSupported(InitQoS2, false), + QoS = ?not_SetDiscardPolicy(InitQoS3, ?not_AnyOrder), + + AnyQoS = ?not_SetOrderPolicy(QoS, ?not_AnyOrder), + PriorityQoS = ?not_SetOrderPolicy(QoS, ?not_PriorityOrder), + FifoQoS = ?not_SetOrderPolicy(QoS, ?not_FifoOrder), + DeadlineQoS = ?not_SetOrderPolicy(QoS, ?not_DeadlineOrder), + + %% "Calculate" data once: + Events = ?EVENTS, + PrioOrder = ?PRIOORDER, + FifoOrder = ?FIFOORDER, + DeadlineOrder = ?DEADLINEORDER, + + do_lookup(PriorityQoS, Events, PrioOrder, "Priority Order"), + do_lookup(FifoQoS, Events, FifoOrder, "Fifo Order"), + do_lookup(DeadlineQoS, Events, DeadlineOrder, "Deadline Order"), + do_lookup(AnyQoS, Events, PrioOrder, "Any Order"), + ok. + +do_lookup(QoS, Events, Return, Txt) -> + io:format("#################### ~s ###################~n", [Txt]), + Ref = cosNotification_eventDB:create_db(QoS, 60, 50, undefined), + create_loop(Events, Ref), + ?match({Return,_}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + cosNotification_eventDB:destroy_db(Ref). + + +%%----------------------------------------------------------------- +%% cosNotification_eventDB max events API tests +%%----------------------------------------------------------------- +max_events_api(doc) -> ["The event DB is used to store events which cannot be", + "delivered at once. If the MaxEvents QoS is updated we must be", + "able to reduce the amount of stored events.", + ""]; +max_events_api(suite) -> []; +max_events_api(_Config) -> + + QoS1 = ?not_CreateInitQoS(), + QoS2 = ?not_SetOrderPolicy(QoS1, ?not_FifoOrder), + QoS3 = ?not_SetDiscardPolicy(QoS2, ?not_RejectNewEvents), + QoS4 = ?not_SetStartTimeSupported(QoS3, false), + QoS_NO_OF_EVENTS = ?not_SetMaxEventsPerConsumer(QoS4, ?NO_OF_EVENTS), + QoS_5_EVENTS = ?not_SetMaxEventsPerConsumer(QoS4, 5), + + Events = ?EVENTS, + Events5 = [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT5], + + %% Initiate DB and 'NO_OF_EVENTS' events. + Ref1 = cosNotification_eventDB:create_db(QoS_NO_OF_EVENTS, 60, 50, undefined), + create_loop(Events, Ref1), + + %% Reduce the limit to 5 and extract all and see if it's ok. + Ref2 = cosNotification_eventDB:update(Ref1, QoS_5_EVENTS), + ?match({Events5, true}, cosNotification_eventDB:get_events(Ref2, ?NO_OF_EVENTS)), + + %% Add 'NO_OF_EVENTS' events. Since the only allow 5 events the DB will only + %% contain 5 events. + create_loop(Events, Ref2), + Ref3 = cosNotification_eventDB:update(Ref2, QoS_NO_OF_EVENTS), + + ?match({Events5, true}, cosNotification_eventDB:get_events(Ref3, ?NO_OF_EVENTS)), + create_loop(Events, Ref3), + ?match({Events, true}, cosNotification_eventDB:get_events(Ref3, ?NO_OF_EVENTS)), + cosNotification_eventDB:destroy_db(Ref3), + ok. + + +%%----------------------------------------------------------------- +%% cosNotification_eventDB persisten events API tests +%%----------------------------------------------------------------- +persisten_event_api(doc) -> ["The event DB is used to store events which cannot be", + "delivered at once.", + ""]; +persisten_event_api(suite) -> []; +persisten_event_api(_Config) -> + + QoS1 = ?not_CreateInitQoS(), + QoS2 = ?not_SetOrderPolicy(QoS1, ?not_FifoOrder), + QoS3 = ?not_SetDiscardPolicy(QoS2, ?not_RejectNewEvents), + QoS4 = ?not_SetStartTimeSupported(QoS3, false), + QoS = ?not_SetMaxEventsPerConsumer(QoS4, ?NO_OF_EVENTS), + + Event1 = ?EVENT1, + + Ref = cosNotification_eventDB:create_db(QoS, 60, 50, undefined), + %% Clean DB, should be empty + ?match(0, cosNotification_eventDB:status(Ref, eventCounter)), + cosNotification_eventDB:add_event(Ref, Event1), + ?match(1, cosNotification_eventDB:status(Ref, eventCounter)), + %% Get event without removing it. Should still be one event stored + ?match({[Event1], _, _}, cosNotification_eventDB:get_events(Ref, 2, false)), + ?match(1, cosNotification_eventDB:status(Ref, eventCounter)), + {_, _, Keys} = + ?match({Event1, _, _}, cosNotification_eventDB:get_event(Ref, false)), + ?match(1, cosNotification_eventDB:status(Ref, eventCounter)), + %% Clear the events and check that the DB is empty. + cosNotification_eventDB:delete_events(Keys), + ?match(0, cosNotification_eventDB:status(Ref, eventCounter)), + ?match({[], _, []}, cosNotification_eventDB:get_event(Ref, false)), + ?match({[], _, []}, cosNotification_eventDB:get_events(Ref, 2, false)), + + cosNotification_eventDB:destroy_db(Ref), + ok. + +%%----------------------------------------------------------------- +%% cosNotification_eventDB gc API tests +%%----------------------------------------------------------------- +gc_api(doc) -> ["The event DB is used to store events which cannot be", + "delivered at once. If Deadline defined the events that", + "are older must be discarded.", + ""]; +gc_api(suite) -> []; +gc_api(_Config) -> + + QoS1 = ?not_CreateInitQoS(), + QoS2 = ?not_SetOrderPolicy(QoS1, ?not_FifoOrder), + QoS3 = ?not_SetDiscardPolicy(QoS2, ?not_RejectNewEvents), + QoS4 = ?not_SetStartTimeSupported(QoS3, false), + QoS_NO_OF_EVENTS = ?not_SetMaxEventsPerConsumer(QoS4, ?NO_OF_EVENTS), + + Events = ?EVENTS, + Events6 = [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT6, ?EVENT7, ?EVENT8], + %% Initiate DB and 'NO_OF_EVENTS' events. + Ref = cosNotification_eventDB:create_db(QoS_NO_OF_EVENTS, 60, 50, undefined), + create_loop(Events, Ref), + + %% Sleep so some events will get 'old'. + timer:sleep(23000), + + %% Reduce the limit to 5 and extract all and see if it's ok. + cosNotification_eventDB:gc_events(Ref, high), + + %% Since gc is done by another process we must wait so it will have a chance + %% to complete the job. + timer:sleep(2000), + + ?match({Events6, true}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + + create_loop(Events, Ref), + timer:sleep(23000), + ?match({Events6, true}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + cosNotification_eventDB:destroy_db(Ref), + ok. + + +%%----------------------------------------------------------------- +%% cosNotification_eventDB gc API tests +%%----------------------------------------------------------------- +auto_gc_api(doc) -> ["The event DB is used to store events which cannot be", + "delivered at once. If Deadline defined the events that", + "are older must be discarded.", + ""]; +auto_gc_api(suite) -> []; +auto_gc_api(_Config) -> + + QoS1 = ?not_CreateInitQoS(), + QoS2 = ?not_SetOrderPolicy(QoS1, ?not_FifoOrder), + QoS3 = ?not_SetDiscardPolicy(QoS2, ?not_RejectNewEvents), + QoS4 = ?not_SetStopTimeSupported(QoS3, true), + QoS5 = ?not_SetStartTimeSupported(QoS4, false), + QoS_NO_OF_EVENTS = ?not_SetMaxEventsPerConsumer(QoS5, ?NO_OF_EVENTS), + + Events6 = [?EVENT1, ?EVENT2, ?EVENT3, ?EVENT7, ?EVENT8, ?EVENT9], + %% Initiate DB + Ref = cosNotification_eventDB:create_db(QoS_NO_OF_EVENTS, 50, 50, undefined), + create_loop([?EVENT1, ?EVENT2, ?EVENT3, ?EVENT4, ?EVENT6], Ref), + + %% Sleep so some events will get 'old'. + timer:sleep(60000), + create_loop([?EVENT7, ?EVENT8, ?EVENT9], Ref), + + %% Since gc is done by another process we must wait so it will have a chance + %% to complete the job. + timer:sleep(2000), + + ?match({Events6, true}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + + cosNotification_eventDB:destroy_db(Ref), + + ok. + + +%%----------------------------------------------------------------- +%% cosNotification_eventDB start- and stop-time API tests +%%----------------------------------------------------------------- +start_stop_time_api(doc) -> ["The event DB is used to store events which cannot be", + "delivered at once. If Deadline defined the events that", + "are older must be discarded.", + ""]; +start_stop_time_api(suite) -> []; +start_stop_time_api(_Config) -> + + QoS1 = ?not_CreateInitQoS(), + QoS2 = ?not_SetOrderPolicy(QoS1, ?not_FifoOrder), + QoS3 = ?not_SetDiscardPolicy(QoS2, ?not_RejectNewEvents), + QoS4 = ?not_SetStopTimeSupported(QoS3, true), + QoS5 = ?not_SetStartTimeSupported(QoS4, true), + QoS_NO_OF_EVENTS = ?not_SetMaxEventsPerConsumer(QoS5, ?NO_OF_EVENTS), + + %% Initiate DB + TimeService = cosTime:start_time_service(2, 0), + Ref = cosNotification_eventDB:create_db(QoS_NO_OF_EVENTS, 50, 50, TimeService), + + T1 = 'CosTime_UTO':'_get_utc_time'('CosTime_UTO': + absolute_time('CosTime_TimeService': + new_universal_time(TimeService, + 100000000, 0, 2))), + T2 = 'CosTime_UTO':'_get_utc_time'('CosTime_UTO': + absolute_time('CosTime_TimeService': + new_universal_time(TimeService, + 200000000, 0, 2))), + T3 = 'CosTime_UTO':'_get_utc_time'('CosTime_UTO': + absolute_time('CosTime_TimeService': + new_universal_time(TimeService, + 300000000, 0, 2))), + T4 = 'CosTime_UTO':'_get_utc_time'('CosTime_UTO': + absolute_time('CosTime_TimeService': + new_universal_time(TimeService, + 400000000, 0, 2))), + %% Delivered after 10 seconds discarded after 20. + EVENT1 = ?not_CreateSE("","event1","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), 1)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), T1)}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), T2)}], + [], any:create(orber_tc:null(), null)), + + %% Delivered after 30 seconds discarded after 10, i.e., always discarded. + EVENT2 = ?not_CreateSE("","event2","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), 3)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), T3)}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), T1)}], + [], any:create(orber_tc:null(), null)), + + %% Delivered after 20 seconds discarded after 40 + EVENT3 = ?not_CreateSE("","event3","", + [#'CosNotification_Property' + {name="Priority", + value=any:create(orber_tc:short(), 2)}, + #'CosNotification_Property' + {name="StartTime", + value=any:create('TimeBase_UtcT':tc(), T2)}, + #'CosNotification_Property' + {name="StopTime", + value=any:create('TimeBase_UtcT':tc(), T4)}], + [], any:create(orber_tc:null(), null)), + + + + + create_loop([EVENT1, EVENT2, EVENT3], Ref), + + ?match({[], false}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + + %% Sleep so some events will get 'old'. + timer:sleep(12000), + + ?match({[EVENT1], true}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + + ?match({[], false}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + + timer:sleep(10000), + + ?match({[EVENT3], true}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + + timer:sleep(20000), + + %% See if EVENT2 really have been discarded. + ?match({[], false}, cosNotification_eventDB:get_events(Ref, ?NO_OF_EVENTS)), + + cosNotification_eventDB:destroy_db(Ref), + + cosTime:stop_time_service(TimeService), + + ok. + + +%%----------------------------------------------------------------- +%% cosNotification_eventDB order API tests +%%----------------------------------------------------------------- +reorder_api(doc) -> ["The event DB is used to store events which cannot be", + "delivered at once. If the QoS is updated we must be", + "able to change the ordering of events as the discard", + "and order policies tells us.", + ""]; +reorder_api(suite) -> []; +reorder_api(_Config) -> + %% We need to test switching between: + %% * Priority -> Fifo + %% * Priority -> Deadline + %% * Fifo -> Priority + %% * Fifo -> Deadline + %% * Deadline -> Priority + %% * Deadline -> Fifo + QoS = ?not_CreateInitQoS(), + QoS2 = ?not_SetMaxEventsPerConsumer(QoS,100), + QoS3 = ?not_SetPriority(QoS2, 10), + QoS4 = ?not_SetStartTimeSupported(QoS3, false), + QoS5 = ?not_SetOrderPolicy(QoS4, ?not_AnyOrder), + + + %% Test all order policies using Any order discard policy. + reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_AnyOrder), "Discard Any"), + reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_PriorityOrder), "Discard Priority"), + reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_DeadlineOrder), "Discard Deadline"), + reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_FifoOrder), "Discard Fifo"), + reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_LifoOrder), "Discard Lifo"), + reorder_helper(?not_SetDiscardPolicy(QoS5, ?not_RejectNewEvents), "Reject New Events"), + + ok. + + +reorder_helper(QoS, Txt) -> + io:format("$$$$$$$$$$$$$$$$$$$$ ~s $$$$$$$$$$$$$$$$$$$~n", [Txt]), + %% Create a DB with the above settings. + Ref = cosNotification_eventDB:create_db(QoS, 60, 50, undefined), + + Events = ?EVENTS, + PrioOrder = ?PRIOORDER, + FifoOrder = ?FIFOORDER, + DeadlineOrder = ?DEADLINEORDER, + + %% Test all order policies using Any order discard policy. + Ref2 = do_reorder(Ref, Events, ?not_SetOrderPolicy(QoS, ?not_FifoOrder), + FifoOrder, "Priority -> Fifo"), + Ref3 = do_reorder(Ref2, Events, ?not_SetOrderPolicy(QoS, ?not_PriorityOrder), + PrioOrder, "Fifo -> Priority"), + Ref4 = do_reorder(Ref3, Events, ?not_SetOrderPolicy(QoS, ?not_DeadlineOrder), + DeadlineOrder, "Priority -> Deadline"), + + Ref5 = do_reorder(Ref4, Events, ?not_SetOrderPolicy(QoS, ?not_PriorityOrder), + PrioOrder, "Deadline -> Priority"), + + Ref6 = do_reorder(Ref5, Events, ?not_SetOrderPolicy(QoS, ?not_FifoOrder), + FifoOrder, "Priority -> Fifo"), + + Ref7 = do_reorder(Ref6, Events, ?not_SetOrderPolicy(QoS, ?not_DeadlineOrder), + DeadlineOrder, "Fifo -> Deadline"), + + Ref8 = do_reorder(Ref7, Events, ?not_SetOrderPolicy(QoS, ?not_FifoOrder), + FifoOrder, "Deadline -> Fifo"), + cosNotification_eventDB:destroy_db(Ref8), + ok. + + + +do_reorder(Ref, Events, QoS, Reply, Txt) -> + create_loop(Events, Ref), + io:format("################# ~s #################~n", [Txt]), + NewRef = cosNotification_eventDB:update(Ref, QoS), + ?match({Reply,_}, cosNotification_eventDB:get_events(NewRef, ?NO_OF_EVENTS)), + NewRef. + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- +%% This functions takes as argument a list of structured events. +create_loop([], _Ref) -> + ok; +create_loop([H|T], Ref) -> + catch cosNotification_eventDB:add_event(Ref, H), + create_loop(T, Ref). + +create_loop([], _Ref, _Life, _Prio) -> + ok; +create_loop([H|T], Ref, Life, Prio) -> + catch cosNotification_eventDB:add_event(Ref, H, Life, Prio), + create_loop(T, Ref, Life, Prio). + +%%-------------------- End of Module ------------------------------ diff --git a/lib/cosNotification/test/generated_SUITE.erl b/lib/cosNotification/test/generated_SUITE.erl new file mode 100644 index 0000000000..34b84041f0 --- /dev/null +++ b/lib/cosNotification/test/generated_SUITE.erl @@ -0,0 +1,2042 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : generated_SUITE.erl +%% Purpose : +%%----------------------------------------------------------------- + +-module(generated_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(nomatch(Not, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + Not -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS); + _ -> + AcTuAlReS + end + end()). + + +-define(checktc(_Op), + fun(TC) -> + case orber_tc:check_tc(TC) of + false -> + io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]), + ?line exit(TC); + true -> + true + end + end). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["This suite is for testing IC generated files"]; +all(suite) -> + ['CosNotification', 'CosNotification_AdminPropertiesAdmin', + 'CosNotification_EventHeader', 'CosNotification_EventType', + 'CosNotification_FixedEventHeader', 'CosNotification_NamedPropertyRange', + 'CosNotification_Property', 'CosNotification_PropertyError', + 'CosNotification_PropertyRange', 'CosNotification_QoSAdmin', + 'CosNotification_StructuredEvent', 'CosNotification_UnsupportedAdmin', + 'CosNotification_UnsupportedQoS', 'CosNotification_EventBatch', + 'CosNotification_EventTypeSeq', 'CosNotification_NamedPropertyRangeSeq', + 'CosNotification_PropertyErrorSeq', 'CosNotifyChannelAdmin_AdminLimit', + 'CosNotifyChannelAdmin_AdminNotFound', 'CosNotifyChannelAdmin_ChannelNotFound', + 'CosNotifyChannelAdmin_ConnectionAlreadyActive', 'CosNotifyChannelAdmin_ConnectionAlreadyInactive', + 'CosNotifyChannelAdmin_NotConnected', 'CosNotifyChannelAdmin_AdminIDSeq', + 'CosNotifyChannelAdmin_ChannelIDSeq', 'CosNotifyChannelAdmin_ProxyIDSeq', + 'CosNotifyFilter_CallbackNotFound', 'CosNotifyFilter_ConstraintExp', + 'CosNotifyFilter_ConstraintInfo', 'CosNotifyFilter_ConstraintNotFound', + 'CosNotifyFilter_DuplicateConstraintID', 'CosNotifyFilter_FilterNotFound', + 'CosNotifyFilter_InvalidConstraint', 'CosNotifyFilter_InvalidGrammar', + 'CosNotifyFilter_InvalidValue', 'CosNotifyFilter_MappingConstraintInfo', + 'CosNotifyFilter_MappingConstraintPair', 'CosNotifyFilter_UnsupportedFilterableData', + 'CosNotifyFilter_CallbackIDSeq', 'CosNotifyFilter_ConstraintExpSeq', + 'CosNotifyFilter_ConstraintIDSeq', 'CosNotifyFilter_ConstraintInfoSeq', + 'CosNotifyFilter_FilterIDSeq', 'CosNotifyFilter_MappingConstraintInfoSeq', + 'CosNotifyFilter_MappingConstraintPairSeq', 'CosNotifyComm_InvalidEventType', + 'CosNotifyChannelAdmin_ConsumerAdmin', 'CosNotifyChannelAdmin_EventChannel', + 'CosNotifyChannelAdmin_EventChannelFactory', 'CosNotifyChannelAdmin_ProxyConsumer', + 'CosNotifyChannelAdmin_ProxyNotFound', 'CosNotifyChannelAdmin_ProxyPullConsumer', + 'CosNotifyChannelAdmin_ProxyPullSupplier', 'CosNotifyChannelAdmin_ProxyPushConsumer', + 'CosNotifyChannelAdmin_ProxyPushSupplier', 'CosNotifyChannelAdmin_ProxySupplier', + 'CosNotifyChannelAdmin_SequenceProxyPullConsumer', 'CosNotifyChannelAdmin_SequenceProxyPullSupplier', + 'CosNotifyChannelAdmin_SequenceProxyPushConsumer', 'CosNotifyChannelAdmin_SequenceProxyPushSupplier', + 'CosNotifyChannelAdmin_StructuredProxyPullConsumer', 'CosNotifyChannelAdmin_StructuredProxyPullSupplier', + 'CosNotifyChannelAdmin_StructuredProxyPushConsumer', 'CosNotifyChannelAdmin_StructuredProxyPushSupplier', + 'CosNotifyChannelAdmin_SupplierAdmin', 'CosNotifyFilter_Filter', + 'CosNotifyFilter_FilterAdmin', 'CosNotifyFilter_FilterFactory', + 'CosNotifyFilter_MappingFilter', 'CosNotifyComm_NotifyPublish', + 'CosNotifyComm_NotifySubscribe', 'CosNotifyComm_PullConsumer', + 'CosNotifyComm_PullSupplier', 'CosNotifyComm_PushConsumer', + 'CosNotifyComm_PushSupplier', 'CosNotifyComm_SequencePullConsumer', + 'CosNotifyComm_SequencePullSupplier', 'CosNotifyComm_SequencePushConsumer', + 'CosNotifyComm_SequencePushSupplier', 'CosNotifyComm_StructuredPullConsumer', + 'CosNotifyComm_StructuredPullSupplier', 'CosNotifyComm_StructuredPushConsumer', + 'CosNotifyComm_StructuredPushSupplier', 'oe_CosNotificationComm_Event', + 'CosNotification_PropertySeq']. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification' +%% Description: +%%----------------------------------------------------------------- +'CosNotification'(doc) -> ["CosNotification"]; +'CosNotification'(suite) -> []; +'CosNotification'(_) -> + ?match("EventReliability", 'CosNotification':'EventReliability'()), + ?match(0, 'CosNotification':'BestEffort'()), + ?match(1, 'CosNotification':'Persistent'()), + ?match("ConnectionReliability", 'CosNotification':'ConnectionReliability'()), + ?match("Priority", 'CosNotification':'Priority'()), + ?match(-32767, 'CosNotification':'LowestPriority'()), + ?match(32767, 'CosNotification':'HighestPriority'()), + ?match(0, 'CosNotification':'DefaultPriority'()), + ?match("StartTime", 'CosNotification':'StartTime'()), + ?match("StopTime", 'CosNotification':'StopTime'()), + ?match("Timeout", 'CosNotification':'Timeout'()), + ?match("OrderPolicy", 'CosNotification':'OrderPolicy'()), + ?match(0, 'CosNotification':'AnyOrder'()), + ?match(1, 'CosNotification':'FifoOrder'()), + ?match(2, 'CosNotification':'PriorityOrder'()), + ?match(3, 'CosNotification':'DeadlineOrder'()), + ?match("DiscardPolicy", 'CosNotification':'DiscardPolicy'()), + ?match(4, 'CosNotification':'LifoOrder'()), + ?match(5, 'CosNotification':'RejectNewEvents'()), + ?match("MaximumBatchSize", 'CosNotification':'MaximumBatchSize'()), + ?match("PacingInterval", 'CosNotification':'PacingInterval'()), + ?match("StartTimeSupported", 'CosNotification':'StartTimeSupported'()), + ?match("StopTimeSupported", 'CosNotification':'StopTimeSupported'()), + ?match("MaxEventsPerConsumer", 'CosNotification':'MaxEventsPerConsumer'()), + ?match("MaxQueueLength", 'CosNotification':'MaxQueueLength'()), + ?match("MaxConsumers", 'CosNotification':'MaxConsumers'()), + ?match("MaxSuppliers", 'CosNotification':'MaxSuppliers'()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_EventHeader' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_EventHeader'(doc) -> ["CosNotification_EventHeader"]; +'CosNotification_EventHeader'(suite) -> []; +'CosNotification_EventHeader'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_EventHeader':tc())), + ?match("IDL:omg.org/CosNotification/EventHeader:1.0", + 'CosNotification_EventHeader':id()), + ?match("CosNotification_EventHeader", + 'CosNotification_EventHeader':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_EventType' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_EventType'(doc) -> ["CosNotification_EventType"]; +'CosNotification_EventType'(suite) -> []; +'CosNotification_EventType'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_EventType':tc())), + ?match("IDL:omg.org/CosNotification/EventType:1.0", + 'CosNotification_EventType':id()), + ?match("CosNotification_EventType", + 'CosNotification_EventType':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_FixedEventHeader' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_FixedEventHeader'(doc) -> ["CosNotification_FixedEventHeader"]; +'CosNotification_FixedEventHeader'(suite) -> []; +'CosNotification_FixedEventHeader'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_FixedEventHeader':tc())), + ?match("IDL:omg.org/CosNotification/FixedEventHeader:1.0", + 'CosNotification_FixedEventHeader':id()), + ?match("CosNotification_FixedEventHeader", + 'CosNotification_FixedEventHeader':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_NamedPropertyRange' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_NamedPropertyRange'(doc) -> ["CosNotification_NamedPropertyRange"]; +'CosNotification_NamedPropertyRange'(suite) -> []; +'CosNotification_NamedPropertyRange'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_NamedPropertyRange':tc())), + ?match("IDL:omg.org/CosNotification/NamedPropertyRange:1.0", + 'CosNotification_NamedPropertyRange':id()), + ?match("CosNotification_NamedPropertyRange", + 'CosNotification_NamedPropertyRange':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_Property' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_Property'(doc) -> ["CosNotification_Property"]; +'CosNotification_Property'(suite) -> []; +'CosNotification_Property'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_Property':tc())), + ?match("IDL:omg.org/CosNotification/Property:1.0", + 'CosNotification_Property':id()), + ?match("CosNotification_Property", + 'CosNotification_Property':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_PropertyError' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_PropertyError'(doc) -> ["CosNotification_PropertyError"]; +'CosNotification_PropertyError'(suite) -> []; +'CosNotification_PropertyError'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_PropertyError':tc())), + ?match("IDL:omg.org/CosNotification/PropertyError:1.0", + 'CosNotification_PropertyError':id()), + ?match("CosNotification_PropertyError", + 'CosNotification_PropertyError':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_PropertyRange' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_PropertyRange'(doc) -> [""]; +'CosNotification_PropertyRange'(suite) -> []; +'CosNotification_PropertyRange'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_PropertyRange':tc())), + ?match("IDL:omg.org/CosNotification/PropertyRange:1.0", + 'CosNotification_PropertyRange':id()), + ?match("CosNotification_PropertyRange", + 'CosNotification_PropertyRange':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_StructuredEvent' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_StructuredEvent'(doc) -> ["CosNotification_StructuredEvent"]; +'CosNotification_StructuredEvent'(suite) -> []; +'CosNotification_StructuredEvent'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_StructuredEvent':tc())), + ?match("IDL:omg.org/CosNotification/StructuredEvent:1.0", + 'CosNotification_StructuredEvent':id()), + ?match("CosNotification_StructuredEvent", + 'CosNotification_StructuredEvent':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_UnsupportedAdmin' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_UnsupportedAdmin'(doc) -> ["CosNotification_UnsupportedAdmin"]; +'CosNotification_UnsupportedAdmin'(suite) -> []; +'CosNotification_UnsupportedAdmin'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_UnsupportedAdmin':tc())), + ?match("IDL:omg.org/CosNotification/UnsupportedAdmin:1.0", + 'CosNotification_UnsupportedAdmin':id()), + ?match("CosNotification_UnsupportedAdmin", + 'CosNotification_UnsupportedAdmin':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_UnsupportedQoS' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_UnsupportedQoS'(doc) -> ["CosNotification_UnsupportedQoS"]; +'CosNotification_UnsupportedQoS'(suite) -> []; +'CosNotification_UnsupportedQoS'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_UnsupportedQoS':tc())), + ?match("IDL:omg.org/CosNotification/UnsupportedQoS:1.0", + 'CosNotification_UnsupportedQoS':id()), + ?match("CosNotification_UnsupportedQoS", + 'CosNotification_UnsupportedQoS':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_EventBatch' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_EventBatch'(doc) -> ["CosNotification_EventBatch"]; +'CosNotification_EventBatch'(suite) -> []; +'CosNotification_EventBatch'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_EventBatch':tc())), + ?match("IDL:omg.org/CosNotification/EventBatch:1.0", + 'CosNotification_EventBatch':id()), + ?match("CosNotification_EventBatch", + 'CosNotification_EventBatch':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_EventTypeSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_EventTypeSeq'(doc) -> ["CosNotification_EventTypeSeq"]; +'CosNotification_EventTypeSeq'(suite) -> []; +'CosNotification_EventTypeSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_EventTypeSeq':tc())), + ?match("IDL:omg.org/CosNotification/EventTypeSeq:1.0", + 'CosNotification_EventTypeSeq':id()), + ?match("CosNotification_EventTypeSeq", + 'CosNotification_EventTypeSeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_NamedPropertyRangeSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_NamedPropertyRangeSeq'(doc) -> ["CosNotification_NamedPropertyRangeSeq"]; +'CosNotification_NamedPropertyRangeSeq'(suite) -> []; +'CosNotification_NamedPropertyRangeSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_NamedPropertyRangeSeq':tc())), + ?match("IDL:omg.org/CosNotification/NamedPropertyRangeSeq:1.0", + 'CosNotification_NamedPropertyRangeSeq':id()), + ?match("CosNotification_NamedPropertyRangeSeq", + 'CosNotification_NamedPropertyRangeSeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_PropertyErrorSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_PropertyErrorSeq'(doc) -> ["CosNotification_PropertyErrorSeq"]; +'CosNotification_PropertyErrorSeq'(suite) -> []; +'CosNotification_PropertyErrorSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_PropertyErrorSeq':tc())), + ?match("IDL:omg.org/CosNotification/PropertyErrorSeq:1.0", + 'CosNotification_PropertyErrorSeq':id()), + ?match("CosNotification_PropertyErrorSeq", + 'CosNotification_PropertyErrorSeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_PropertySeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_PropertySeq'(doc) -> ["CosNotification_PropertySeq"]; +'CosNotification_PropertySeq'(suite) -> []; +'CosNotification_PropertySeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotification_PropertySeq':tc())), + ?match("IDL:omg.org/CosNotification/PropertySeq:1.0", + 'CosNotification_PropertySeq':id()), + ?match("CosNotification_PropertySeq", + 'CosNotification_PropertySeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_AdminLimit' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_AdminLimit'(doc) -> ["CosNotifyChannelAdmin_AdminLimit"]; +'CosNotifyChannelAdmin_AdminLimit'(suite) -> []; +'CosNotifyChannelAdmin_AdminLimit'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_AdminLimit':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/AdminLimit:1.0", + 'CosNotifyChannelAdmin_AdminLimit':id()), + ?match("CosNotifyChannelAdmin_AdminLimit", + 'CosNotifyChannelAdmin_AdminLimit':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_AdminLimitExceeded' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_AdminLimitExceeded'(doc) -> ["CosNotifyChannelAdmin_AdminLimitExceeded"]; +'CosNotifyChannelAdmin_AdminLimitExceeded'(suite) -> []; +'CosNotifyChannelAdmin_AdminLimitExceeded'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_AdminLimitExceeded':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/AdminLimitExceeded:1.0", + 'CosNotifyChannelAdmin_AdminLimitExceeded':id()), + ?match("CosNotifyChannelAdmin_AdminLimitExceeded", + 'CosNotifyChannelAdmin_AdminLimitExceeded':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_AdminNotFound' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_AdminNotFound'(doc) -> ["CosNotifyChannelAdmin_AdminNotFound"]; +'CosNotifyChannelAdmin_AdminNotFound'(suite) -> []; +'CosNotifyChannelAdmin_AdminNotFound'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_AdminNotFound':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/AdminNotFound:1.0", + 'CosNotifyChannelAdmin_AdminNotFound':id()), + ?match("CosNotifyChannelAdmin_AdminNotFound", + 'CosNotifyChannelAdmin_AdminNotFound':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ChannelNotFound' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ChannelNotFound'(doc) -> ["CosNotifyChannelAdmin_ChannelNotFound"]; +'CosNotifyChannelAdmin_ChannelNotFound'(suite) -> []; +'CosNotifyChannelAdmin_ChannelNotFound'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ChannelNotFound':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ChannelNotFound:1.0", + 'CosNotifyChannelAdmin_ChannelNotFound':id()), + ?match("CosNotifyChannelAdmin_ChannelNotFound", + 'CosNotifyChannelAdmin_ChannelNotFound':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ConnectionAlreadyActive' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ConnectionAlreadyActive'(doc) -> ["CosNotifyChannelAdmin_ConnectionAlreadyActive"]; +'CosNotifyChannelAdmin_ConnectionAlreadyActive'(suite) -> []; +'CosNotifyChannelAdmin_ConnectionAlreadyActive'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ConnectionAlreadyActive':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ConnectionAlreadyActive:1.0", + 'CosNotifyChannelAdmin_ConnectionAlreadyActive':id()), + ?match("CosNotifyChannelAdmin_ConnectionAlreadyActive", + 'CosNotifyChannelAdmin_ConnectionAlreadyActive':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ConnectionAlreadyInactive' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ConnectionAlreadyInactive'(doc) -> ["CosNotifyChannelAdmin_ConnectionAlreadyInactive"]; +'CosNotifyChannelAdmin_ConnectionAlreadyInactive'(suite) -> []; +'CosNotifyChannelAdmin_ConnectionAlreadyInactive'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ConnectionAlreadyInactive':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ConnectionAlreadyInactive:1.0", + 'CosNotifyChannelAdmin_ConnectionAlreadyInactive':id()), + ?match("CosNotifyChannelAdmin_ConnectionAlreadyInactive", + 'CosNotifyChannelAdmin_ConnectionAlreadyInactive':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_NotConnected' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_NotConnected'(doc) -> ["CosNotifyChannelAdmin_NotConnected"]; +'CosNotifyChannelAdmin_NotConnected'(suite) -> []; +'CosNotifyChannelAdmin_NotConnected'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_NotConnected':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/NotConnected:1.0", + 'CosNotifyChannelAdmin_NotConnected':id()), + ?match("CosNotifyChannelAdmin_NotConnected", + 'CosNotifyChannelAdmin_NotConnected':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_AdminIDSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_AdminIDSeq'(doc) -> ["CosNotifyChannelAdmin_AdminIDSeq"]; +'CosNotifyChannelAdmin_AdminIDSeq'(suite) -> []; +'CosNotifyChannelAdmin_AdminIDSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_AdminIDSeq':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/AdminIDSeq:1.0", + 'CosNotifyChannelAdmin_AdminIDSeq':id()), + ?match("CosNotifyChannelAdmin_AdminIDSeq", + 'CosNotifyChannelAdmin_AdminIDSeq':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ChannelIDSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ChannelIDSeq'(doc) -> ["CosNotifyChannelAdmin_ChannelIDSeq"]; +'CosNotifyChannelAdmin_ChannelIDSeq'(suite) -> []; +'CosNotifyChannelAdmin_ChannelIDSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ChannelIDSeq':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ChannelIDSeq:1.0", + 'CosNotifyChannelAdmin_ChannelIDSeq':id()), + ?match("CosNotifyChannelAdmin_ChannelIDSeq", + 'CosNotifyChannelAdmin_ChannelIDSeq':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ProxyIDSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ProxyIDSeq'(doc) -> ["CosNotifyChannelAdmin_ProxyIDSeq"]; +'CosNotifyChannelAdmin_ProxyIDSeq'(suite) -> []; +'CosNotifyChannelAdmin_ProxyIDSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ProxyIDSeq':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyIDSeq:1.0", + 'CosNotifyChannelAdmin_ProxyIDSeq':id()), + ?match("CosNotifyChannelAdmin_ProxyIDSeq", + 'CosNotifyChannelAdmin_ProxyIDSeq':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_CallbackNotFound' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_CallbackNotFound'(doc) -> ["CosNotifyFilter_CallbackNotFound"]; +'CosNotifyFilter_CallbackNotFound'(suite) -> []; +'CosNotifyFilter_CallbackNotFound'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_CallbackNotFound':tc())), + ?match("IDL:omg.org/CosNotifyFilter/CallbackNotFound:1.0", + 'CosNotifyFilter_CallbackNotFound':id()), + ?match("CosNotifyFilter_CallbackNotFound", + 'CosNotifyFilter_CallbackNotFound':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_ConstraintExp' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_ConstraintExp'(doc) -> ["CosNotifyFilter_ConstraintExp"]; +'CosNotifyFilter_ConstraintExp'(suite) -> []; +'CosNotifyFilter_ConstraintExp'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintExp':tc())), + ?match("IDL:omg.org/CosNotifyFilter/ConstraintExp:1.0", + 'CosNotifyFilter_ConstraintExp':id()), + ?match("CosNotifyFilter_ConstraintExp", + 'CosNotifyFilter_ConstraintExp':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_ConstraintInfo' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_ConstraintInfo'(doc) -> ["CosNotifyFilter_ConstraintInfo"]; +'CosNotifyFilter_ConstraintInfo'(suite) -> []; +'CosNotifyFilter_ConstraintInfo'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintInfo':tc())), + ?match("IDL:omg.org/CosNotifyFilter/ConstraintInfo:1.0", + 'CosNotifyFilter_ConstraintInfo':id()), + ?match("CosNotifyFilter_ConstraintInfo", + 'CosNotifyFilter_ConstraintInfo':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_ConstraintNotFound' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_ConstraintNotFound'(doc) -> ["CosNotifyFilter_ConstraintNotFound"]; +'CosNotifyFilter_ConstraintNotFound'(suite) -> []; +'CosNotifyFilter_ConstraintNotFound'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintNotFound':tc())), + ?match("IDL:omg.org/CosNotifyFilter/ConstraintNotFound:1.0", + 'CosNotifyFilter_ConstraintNotFound':id()), + ?match("CosNotifyFilter_ConstraintNotFound", + 'CosNotifyFilter_ConstraintNotFound':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_DuplicateConstraintID' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_DuplicateConstraintID'(doc) -> ["CosNotifyFilter_DuplicateConstraintID"]; +'CosNotifyFilter_DuplicateConstraintID'(suite) -> []; +'CosNotifyFilter_DuplicateConstraintID'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_DuplicateConstraintID':tc())), + ?match("IDL:omg.org/CosNotifyFilter/DuplicateConstraintID:1.0", + 'CosNotifyFilter_DuplicateConstraintID':id()), + ?match("CosNotifyFilter_DuplicateConstraintID", + 'CosNotifyFilter_DuplicateConstraintID':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_FilterNotFound' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_FilterNotFound'(doc) -> ["CosNotifyFilter_FilterNotFound"]; +'CosNotifyFilter_FilterNotFound'(suite) -> []; +'CosNotifyFilter_FilterNotFound'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_FilterNotFound':tc())), + ?match("IDL:omg.org/CosNotifyFilter/FilterNotFound:1.0", + 'CosNotifyFilter_FilterNotFound':id()), + ?match("CosNotifyFilter_FilterNotFound", + 'CosNotifyFilter_FilterNotFound':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_InvalidConstraint' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_InvalidConstraint'(doc) -> ["CosNotifyFilter_InvalidConstraint"]; +'CosNotifyFilter_InvalidConstraint'(suite) -> []; +'CosNotifyFilter_InvalidConstraint'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_InvalidConstraint':tc())), + ?match("IDL:omg.org/CosNotifyFilter/InvalidConstraint:1.0", + 'CosNotifyFilter_InvalidConstraint':id()), + ?match("CosNotifyFilter_InvalidConstraint", + 'CosNotifyFilter_InvalidConstraint':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_InvalidGrammar' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_InvalidGrammar'(doc) -> ["CosNotifyFilter_InvalidGrammar"]; +'CosNotifyFilter_InvalidGrammar'(suite) -> []; +'CosNotifyFilter_InvalidGrammar'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_InvalidGrammar':tc())), + ?match("IDL:omg.org/CosNotifyFilter/InvalidGrammar:1.0", + 'CosNotifyFilter_InvalidGrammar':id()), + ?match("CosNotifyFilter_InvalidGrammar", + 'CosNotifyFilter_InvalidGrammar':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_InvalidValue' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_InvalidValue'(doc) -> ["CosNotifyFilter_InvalidValue"]; +'CosNotifyFilter_InvalidValue'(suite) -> []; +'CosNotifyFilter_InvalidValue'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_InvalidValue':tc())), + ?match("IDL:omg.org/CosNotifyFilter/InvalidValue:1.0", + 'CosNotifyFilter_InvalidValue':id()), + ?match("CosNotifyFilter_InvalidValue", + 'CosNotifyFilter_InvalidValue':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_MappingConstraintInfo' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_MappingConstraintInfo'(doc) -> ["CosNotifyFilter_MappingConstraintInfo"]; +'CosNotifyFilter_MappingConstraintInfo'(suite) -> []; +'CosNotifyFilter_MappingConstraintInfo'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_MappingConstraintInfo':tc())), + ?match("IDL:omg.org/CosNotifyFilter/MappingConstraintInfo:1.0", + 'CosNotifyFilter_MappingConstraintInfo':id()), + ?match("CosNotifyFilter_MappingConstraintInfo", + 'CosNotifyFilter_MappingConstraintInfo':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_MappingConstraintPair' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_MappingConstraintPair'(doc) -> ["CosNotifyFilter_MappingConstraintPair"]; +'CosNotifyFilter_MappingConstraintPair'(suite) -> []; +'CosNotifyFilter_MappingConstraintPair'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_MappingConstraintPair':tc())), + ?match("IDL:omg.org/CosNotifyFilter/MappingConstraintPair:1.0", + 'CosNotifyFilter_MappingConstraintPair':id()), + ?match("CosNotifyFilter_MappingConstraintPair", + 'CosNotifyFilter_MappingConstraintPair':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_UnsupportedFilterableData' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_UnsupportedFilterableData'(doc) -> ["CosNotifyFilter_UnsupportedFilterableData"]; +'CosNotifyFilter_UnsupportedFilterableData'(suite) -> []; +'CosNotifyFilter_UnsupportedFilterableData'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_UnsupportedFilterableData':tc())), + ?match("IDL:omg.org/CosNotifyFilter/UnsupportedFilterableData:1.0", + 'CosNotifyFilter_UnsupportedFilterableData':id()), + ?match("CosNotifyFilter_UnsupportedFilterableData", + 'CosNotifyFilter_UnsupportedFilterableData':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_CallbackIDSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_CallbackIDSeq'(doc) -> ["CosNotifyFilter_CallbackIDSeq"]; +'CosNotifyFilter_CallbackIDSeq'(suite) -> []; +'CosNotifyFilter_CallbackIDSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_CallbackIDSeq':tc())), + ?match("IDL:omg.org/CosNotifyFilter/CallbackIDSeq:1.0", + 'CosNotifyFilter_CallbackIDSeq':id()), + ?match("CosNotifyFilter_CallbackIDSeq", + 'CosNotifyFilter_CallbackIDSeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_ConstraintExpSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_ConstraintExpSeq'(doc) -> ["CosNotifyFilter_ConstraintExpSeq"]; +'CosNotifyFilter_ConstraintExpSeq'(suite) -> []; +'CosNotifyFilter_ConstraintExpSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintExpSeq':tc())), + ?match("IDL:omg.org/CosNotifyFilter/ConstraintExpSeq:1.0", + 'CosNotifyFilter_ConstraintExpSeq':id()), + ?match("CosNotifyFilter_ConstraintExpSeq", + 'CosNotifyFilter_ConstraintExpSeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_ConstraintIDSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_ConstraintIDSeq'(doc) -> ["CosNotifyFilter_ConstraintIDSeq"]; +'CosNotifyFilter_ConstraintIDSeq'(suite) -> []; +'CosNotifyFilter_ConstraintIDSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintIDSeq':tc())), + ?match("IDL:omg.org/CosNotifyFilter/ConstraintIDSeq:1.0", + 'CosNotifyFilter_ConstraintIDSeq':id()), + ?match("CosNotifyFilter_ConstraintIDSeq", + 'CosNotifyFilter_ConstraintIDSeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_ConstraintInfoSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_ConstraintInfoSeq'(doc) -> ["CosNotifyFilter_ConstraintInfoSeq"]; +'CosNotifyFilter_ConstraintInfoSeq'(suite) -> []; +'CosNotifyFilter_ConstraintInfoSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_ConstraintInfoSeq':tc())), + ?match("IDL:omg.org/CosNotifyFilter/ConstraintInfoSeq:1.0", + 'CosNotifyFilter_ConstraintInfoSeq':id()), + ?match("CosNotifyFilter_ConstraintInfoSeq", + 'CosNotifyFilter_ConstraintInfoSeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_FilterIDSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_FilterIDSeq'(doc) -> ["CosNotifyFilter_FilterIDSeq"]; +'CosNotifyFilter_FilterIDSeq'(suite) -> []; +'CosNotifyFilter_FilterIDSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_FilterIDSeq':tc())), + ?match("IDL:omg.org/CosNotifyFilter/FilterIDSeq:1.0", + 'CosNotifyFilter_FilterIDSeq':id()), + ?match("CosNotifyFilter_FilterIDSeq", + 'CosNotifyFilter_FilterIDSeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_MappingConstraintInfoSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_MappingConstraintInfoSeq'(doc) -> ["CosNotifyFilter_MappingConstraintInfoSeq"]; +'CosNotifyFilter_MappingConstraintInfoSeq'(suite) -> []; +'CosNotifyFilter_MappingConstraintInfoSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_MappingConstraintInfoSeq':tc())), + ?match("IDL:omg.org/CosNotifyFilter/MappingConstraintInfoSeq:1.0", + 'CosNotifyFilter_MappingConstraintInfoSeq':id()), + ?match("CosNotifyFilter_MappingConstraintInfoSeq", + 'CosNotifyFilter_MappingConstraintInfoSeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_MappingConstraintPairSeq' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_MappingConstraintPairSeq'(doc) -> ["CosNotifyFilter_MappingConstraintPairSeq"]; +'CosNotifyFilter_MappingConstraintPairSeq'(suite) -> []; +'CosNotifyFilter_MappingConstraintPairSeq'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyFilter_MappingConstraintPairSeq':tc())), + ?match("IDL:omg.org/CosNotifyFilter/MappingConstraintPairSeq:1.0", + 'CosNotifyFilter_MappingConstraintPairSeq':id()), + ?match("CosNotifyFilter_MappingConstraintPairSeq", + 'CosNotifyFilter_MappingConstraintPairSeq':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_InvalidEventType' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_InvalidEventType'(doc) -> ["CosNotifyComm_InvalidEventType"]; +'CosNotifyComm_InvalidEventType'(suite) -> []; +'CosNotifyComm_InvalidEventType'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyComm_InvalidEventType':tc())), + ?match("IDL:omg.org/CosNotifyComm/InvalidEventType:1.0", + 'CosNotifyComm_InvalidEventType':id()), + ?match("CosNotifyComm_InvalidEventType", + 'CosNotifyComm_InvalidEventType':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ProxyNotFound' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ProxyNotFound'(doc) -> ["CosNotifyChannelAdmin_ProxyNotFound"]; +'CosNotifyChannelAdmin_ProxyNotFound'(suite) -> []; +'CosNotifyChannelAdmin_ProxyNotFound'(_) -> + ?match(true, orber_tc:check_tc('CosNotifyChannelAdmin_ProxyNotFound':tc())), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyNotFound:1.0", + 'CosNotifyChannelAdmin_ProxyNotFound':id()), + ?match("CosNotifyChannelAdmin_ProxyNotFound", + 'CosNotifyChannelAdmin_ProxyNotFound':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_AdminPropertiesAdmin' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_AdminPropertiesAdmin'(doc) -> ["CosNotification_AdminPropertiesAdmin"]; +'CosNotification_AdminPropertiesAdmin'(suite) -> []; +'CosNotification_AdminPropertiesAdmin'(_) -> + ?nomatch(undefined, 'CosNotification_AdminPropertiesAdmin':oe_tc(get_admin)), + ?nomatch(undefined, 'CosNotification_AdminPropertiesAdmin':oe_tc(set_admin)), + ?match(undefined, 'CosNotification_AdminPropertiesAdmin':oe_tc(undefined)), + ?match([_|_], 'CosNotification_AdminPropertiesAdmin':oe_get_interface()), + ?match("IDL:omg.org/CosNotification/AdminPropertiesAdmin:1.0", + 'CosNotification_AdminPropertiesAdmin':typeID()), + check_tc('CosNotification_AdminPropertiesAdmin':oe_get_interface()), + ?match(true, 'CosNotification_AdminPropertiesAdmin':oe_is_a('CosNotification_AdminPropertiesAdmin':typeID())), + ?match(false, 'CosNotification_AdminPropertiesAdmin':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotification_QoSAdmin' +%% Description: +%%----------------------------------------------------------------- +'CosNotification_QoSAdmin'(doc) -> ["CosNotification_QoSAdmin"]; +'CosNotification_QoSAdmin'(suite) -> []; +'CosNotification_QoSAdmin'(_) -> + ?nomatch(undefined, 'CosNotification_QoSAdmin':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotification_QoSAdmin':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotification_QoSAdmin':oe_tc(validate_qos)), + ?match(undefined, 'CosNotification_QoSAdmin':oe_tc(undefined)), + ?match([_|_], 'CosNotification_QoSAdmin':oe_get_interface()), + ?match("IDL:omg.org/CosNotification/QoSAdmin:1.0", + 'CosNotification_QoSAdmin':typeID()), + check_tc('CosNotification_QoSAdmin':oe_get_interface()), + ?match(true, 'CosNotification_QoSAdmin':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(false, 'CosNotification_QoSAdmin':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ConsumerAdmin' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ConsumerAdmin'(doc) -> ["CosNotifyChannelAdmin_ConsumerAdmin"]; +'CosNotifyChannelAdmin_ConsumerAdmin'(suite) -> []; +'CosNotifyChannelAdmin_ConsumerAdmin'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_MyID')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_MyChannel')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_MyOperator')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_set_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_set_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_pull_suppliers')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc('_get_push_suppliers')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(get_proxy_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(obtain_notification_pull_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(obtain_notification_push_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(destroy)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(subscription_change)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(obtain_push_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(obtain_pull_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(callSeq)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(callAny)), + ?match(undefined, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_ConsumerAdmin':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ConsumerAdmin:1.0", + 'CosNotifyChannelAdmin_ConsumerAdmin':typeID()), + check_tc('CosNotifyChannelAdmin_ConsumerAdmin':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('CosNotifyChannelAdmin_ConsumerAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('CosEventChannelAdmin_ConsumerAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a('oe_CosNotificationComm_Event':typeID())), + ?match(false, 'CosNotifyChannelAdmin_ConsumerAdmin':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_EventChannel' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_EventChannel'(doc) -> ["CosNotifyChannelAdmin_EventChannel"]; +'CosNotifyChannelAdmin_EventChannel'(suite) -> []; +'CosNotifyChannelAdmin_EventChannel'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc('_get_MyFactory')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc('_get_default_consumer_admin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc('_get_default_supplier_admin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc('_get_default_filter_factory')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(new_for_consumers)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(new_for_suppliers)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_consumeradmin)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_supplieradmin)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_all_consumeradmins)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_all_supplieradmins)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(get_admin)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(set_admin)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(for_consumers)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(for_suppliers)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(destroy)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(callSeq)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(callAny)), + ?match(undefined, 'CosNotifyChannelAdmin_EventChannel':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_EventChannel':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/EventChannel:1.0", + 'CosNotifyChannelAdmin_EventChannel':typeID()), + check_tc('CosNotifyChannelAdmin_EventChannel':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_EventChannel':oe_is_a('CosNotifyChannelAdmin_EventChannel':typeID())), + ?match(true, 'CosNotifyChannelAdmin_EventChannel':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_EventChannel':oe_is_a('CosNotification_AdminPropertiesAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_EventChannel':oe_is_a('CosEventChannelAdmin_EventChannel':typeID())), + ?match(true, 'CosNotifyChannelAdmin_EventChannel':oe_is_a('oe_CosNotificationComm_Event':typeID())), + ?match(false, 'CosNotifyChannelAdmin_EventChannel':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_EventChannelFactory' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_EventChannelFactory'(doc) -> ["CosNotifyChannelAdmin_EventChannelFactory"]; +'CosNotifyChannelAdmin_EventChannelFactory'(suite) -> []; +'CosNotifyChannelAdmin_EventChannelFactory'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannelFactory':oe_tc(create_channel)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannelFactory':oe_tc(get_all_channels)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_EventChannelFactory':oe_tc(get_event_channel)), + ?match(undefined, 'CosNotifyChannelAdmin_EventChannelFactory':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_EventChannelFactory':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/EventChannelFactory:1.0", + 'CosNotifyChannelAdmin_EventChannelFactory':typeID()), + check_tc('CosNotifyChannelAdmin_EventChannelFactory':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_EventChannelFactory':oe_is_a('CosNotifyChannelAdmin_EventChannelFactory':typeID())), + ?match(false, 'CosNotifyChannelAdmin_EventChannelFactory':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ProxyConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ProxyConsumer'(doc) -> ["CosNotifyChannelAdmin_ProxyConsumer"]; +'CosNotifyChannelAdmin_ProxyConsumer'(suite) -> []; +'CosNotifyChannelAdmin_ProxyConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(obtain_subscription_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(remove_all_filters)), + ?match(undefined, 'CosNotifyChannelAdmin_ProxyConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_ProxyConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyConsumer:1.0", + 'CosNotifyChannelAdmin_ProxyConsumer':typeID()), + check_tc('CosNotifyChannelAdmin_ProxyConsumer':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_ProxyConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(false, 'CosNotifyChannelAdmin_ProxyConsumer':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ProxyPullConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ProxyPullConsumer'(doc) -> ["CosNotifyChannelAdmin_ProxyPullConsumer"]; +'CosNotifyChannelAdmin_ProxyPullConsumer'(suite) -> []; +'CosNotifyChannelAdmin_ProxyPullConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(connect_any_pull_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(suspend_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(resume_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(obtain_subscription_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(offer_change)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(disconnect_pull_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(connect_pull_supplier)), + ?match(undefined, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyPullConsumer:1.0", + 'CosNotifyChannelAdmin_ProxyPullConsumer':typeID()), + check_tc('CosNotifyChannelAdmin_ProxyPullConsumer':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyPullConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotifyComm_PullConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosEventComm_PullConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a('CosEventChannelAdmin_ProxyPullConsumer':typeID())), + ?match(false, 'CosNotifyChannelAdmin_ProxyPullConsumer':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ProxyPullSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ProxyPullSupplier'(doc) -> ["CosNotifyChannelAdmin_ProxyPullSupplier"]; +'CosNotifyChannelAdmin_ProxyPullSupplier'(suite) -> []; +'CosNotifyChannelAdmin_ProxyPullSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_get_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_set_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_get_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc('_set_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(obtain_offered_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(subscription_change)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(pull)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(try_pull)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(disconnect_pull_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(connect_pull_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(callSeq)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(callAny)), + ?match(undefined, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyPullSupplier:1.0", + 'CosNotifyChannelAdmin_ProxyPullSupplier':typeID()), + check_tc('CosNotifyChannelAdmin_ProxyPullSupplier':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_ProxyPullSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotifyComm_PullSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosEventComm_PullSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('CosEventChannelAdmin_ProxyPullSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())), + ?match(false, 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ProxyPushConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ProxyPushConsumer'(doc) -> ["CosNotifyChannelAdmin_ProxyPushConsumer"]; +'CosNotifyChannelAdmin_ProxyPushConsumer'(suite) -> []; +'CosNotifyChannelAdmin_ProxyPushConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(connect_any_push_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(obtain_subscription_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(offer_change)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(push)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(disconnect_push_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(connect_push_supplier)), + ?match(undefined, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyPushConsumer:1.0", + 'CosNotifyChannelAdmin_ProxyPushConsumer':typeID()), + check_tc('CosNotifyChannelAdmin_ProxyPushConsumer':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyPushConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotifyComm_PushConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosEventComm_PushConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a('CosEventChannelAdmin_ProxyPushConsumer':typeID())), + ?match(false, 'CosNotifyChannelAdmin_ProxyPushConsumer':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ProxyPushSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ProxyPushSupplier'(doc) -> ["CosNotifyChannelAdmin_ProxyPushSupplier"]; +'CosNotifyChannelAdmin_ProxyPushSupplier'(suite) -> []; +'CosNotifyChannelAdmin_ProxyPushSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(connect_any_push_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(suspend_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(resume_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_get_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_set_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_get_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc('_set_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(obtain_offered_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(subscription_change)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(disconnect_push_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(connect_push_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(callSeq)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(callAny)), + ?match(undefined, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxyPushSupplier:1.0", + 'CosNotifyChannelAdmin_ProxyPushSupplier':typeID()), + check_tc('CosNotifyChannelAdmin_ProxyPushSupplier':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_ProxyPushSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotifyComm_PushSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosEventComm_PushSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('CosEventChannelAdmin_ProxyPushSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())), + ?match(false, 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_ProxySupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_ProxySupplier'(doc) -> ["CosNotifyChannelAdmin_ProxySupplier"]; +'CosNotifyChannelAdmin_ProxySupplier'(suite) -> []; +'CosNotifyChannelAdmin_ProxySupplier'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_get_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_set_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_get_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc('_set_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(obtain_offered_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(remove_all_filters)), + ?match(undefined, 'CosNotifyChannelAdmin_ProxySupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_ProxySupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/ProxySupplier:1.0", + 'CosNotifyChannelAdmin_ProxySupplier':typeID()), + check_tc('CosNotifyChannelAdmin_ProxySupplier':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_ProxySupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxySupplier':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_ProxySupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(false, 'CosNotifyChannelAdmin_ProxySupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_SequenceProxyPullConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_SequenceProxyPullConsumer'(doc) -> ["CosNotifyChannelAdmin_SequenceProxyPullConsumer"]; +'CosNotifyChannelAdmin_SequenceProxyPullConsumer'(suite) -> []; +'CosNotifyChannelAdmin_SequenceProxyPullConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(connect_sequence_pull_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(suspend_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(resume_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(obtain_subscription_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(disconnect_sequence_pull_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(offer_change)), + ?match(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/SequenceProxyPullConsumer:1.0", + 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':typeID()), + check_tc('CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_SequenceProxyPullConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotifyComm_SequencePullConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(false, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_SequenceProxyPullSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_SequenceProxyPullSupplier'(doc) -> ["CosNotifyChannelAdmin_SequenceProxyPullSupplier"]; +'CosNotifyChannelAdmin_SequenceProxyPullSupplier'(suite) -> []; +'CosNotifyChannelAdmin_SequenceProxyPullSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(connect_sequence_pull_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_get_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_set_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_get_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc('_set_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(obtain_offered_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(pull_structured_events)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(try_pull_structured_events)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(disconnect_sequence_pull_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(subscription_change)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(callSeq)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(callAny)), + ?match(undefined, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/SequenceProxyPullSupplier:1.0", + 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':typeID()), + check_tc('CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_SequenceProxyPullSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotifyComm_SequencePullSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())), + ?match(false, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_SequenceProxyPushConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_SequenceProxyPushConsumer'(doc) -> ["CosNotifyChannelAdmin_SequenceProxyPushConsumer"]; +'CosNotifyChannelAdmin_SequenceProxyPushConsumer'(suite) -> []; +'CosNotifyChannelAdmin_SequenceProxyPushConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(connect_sequence_push_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(obtain_subscription_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(push_structured_events)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(disconnect_sequence_push_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(offer_change)), + ?match(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/SequenceProxyPushConsumer:1.0", + 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':typeID()), + check_tc('CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_SequenceProxyPushConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotifyComm_SequencePushConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(false, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_SequenceProxyPushSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_SequenceProxyPushSupplier'(doc) -> ["CosNotifyChannelAdmin_SequenceProxyPushSupplier"]; +'CosNotifyChannelAdmin_SequenceProxyPushSupplier'(suite) -> []; +'CosNotifyChannelAdmin_SequenceProxyPushSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(connect_sequence_push_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(suspend_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(resume_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_get_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_set_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_get_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc('_set_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(obtain_offered_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(disconnect_sequence_push_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(subscription_change)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(callSeq)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(callAny)), + ?match(undefined, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/SequenceProxyPushSupplier:1.0", + 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':typeID()), + check_tc('CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_SequenceProxyPushSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotifyComm_SequencePushSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())), + ?match(false, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_StructuredProxyPullConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_StructuredProxyPullConsumer'(doc) -> ["CosNotifyChannelAdmin_StructuredProxyPullConsumer"]; +'CosNotifyChannelAdmin_StructuredProxyPullConsumer'(suite) -> []; +'CosNotifyChannelAdmin_StructuredProxyPullConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(connect_structured_pull_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(suspend_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(resume_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(obtain_subscription_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(disconnect_structured_pull_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(offer_change)), + ?match(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/StructuredProxyPullConsumer:1.0", + 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':typeID()), + check_tc('CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_StructuredProxyPullConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotifyComm_StructuredPullConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(false, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_StructuredProxyPullSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_StructuredProxyPullSupplier'(doc) -> ["CosNotifyChannelAdmin_StructuredProxyPullSupplier"]; +'CosNotifyChannelAdmin_StructuredProxyPullSupplier'(suite) -> []; +'CosNotifyChannelAdmin_StructuredProxyPullSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(connect_structured_pull_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_get_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_set_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_get_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc('_set_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(obtain_offered_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(pull_structured_event)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(try_pull_structured_event)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(disconnect_structured_pull_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(subscription_change)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(callSeq)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(callAny)), + ?match(undefined, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/StructuredProxyPullSupplier:1.0", + 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':typeID()), + check_tc('CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_StructuredProxyPullSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotifyComm_StructuredPullSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())), + ?match(false, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_StructuredProxyPushConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_StructuredProxyPushConsumer'(doc) -> ["CosNotifyChannelAdmin_StructuredProxyPushConsumer"]; +'CosNotifyChannelAdmin_StructuredProxyPushConsumer'(suite) -> []; +'CosNotifyChannelAdmin_StructuredProxyPushConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(connect_structured_push_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(obtain_subscription_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(push_structured_event)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(disconnect_structured_push_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(offer_change)), + ?match(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/StructuredProxyPushConsumer:1.0", + 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':typeID()), + check_tc('CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_StructuredProxyPushConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotifyChannelAdmin_ProxyConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotifyComm_StructuredPushConsumer':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(false, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_StructuredProxyPushSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_StructuredProxyPushSupplier'(doc) -> ["CosNotifyChannelAdmin_StructuredProxyPushSupplier"]; +'CosNotifyChannelAdmin_StructuredProxyPushSupplier'(suite) -> []; +'CosNotifyChannelAdmin_StructuredProxyPushSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(connect_structured_push_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(suspend_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(resume_connection)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_get_MyType')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_get_MyAdmin')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_get_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_set_priority_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_get_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc('_set_lifetime_filter')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(obtain_offered_types)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(validate_event_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(disconnect_structured_push_supplier)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(subscription_change)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(callSeq)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(callAny)), + ?match(undefined, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/StructuredProxyPushSupplier:1.0", + 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':typeID()), + check_tc('CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_StructuredProxyPushSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotifyChannelAdmin_ProxySupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotifyComm_StructuredPushSupplier':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(true, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a('oe_CosNotificationComm_Event':typeID())), + ?match(false, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyChannelAdmin_SupplierAdmin' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyChannelAdmin_SupplierAdmin'(doc) -> ["CosNotifyChannelAdmin_SupplierAdmin"]; +'CosNotifyChannelAdmin_SupplierAdmin'(suite) -> []; +'CosNotifyChannelAdmin_SupplierAdmin'(_) -> + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc('_get_MyID')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc('_get_MyChannel')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc('_get_MyOperator')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc('_get_pull_consumers')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc('_get_push_consumers')), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(get_proxy_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(obtain_notification_pull_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(obtain_notification_push_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(destroy)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(get_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(set_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(validate_qos)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(offer_change)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(remove_all_filters)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(obtain_push_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(obtain_pull_consumer)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(callSeq)), + ?nomatch(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(callAny)), + ?match(undefined, 'CosNotifyChannelAdmin_SupplierAdmin':oe_tc(undefined)), + ?match([_|_], 'CosNotifyChannelAdmin_SupplierAdmin':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyChannelAdmin/SupplierAdmin:1.0", + 'CosNotifyChannelAdmin_SupplierAdmin':typeID()), + check_tc('CosNotifyChannelAdmin_SupplierAdmin':oe_get_interface()), + ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('CosNotifyChannelAdmin_SupplierAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('CosNotification_QoSAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('CosEventChannelAdmin_SupplierAdmin':typeID())), + ?match(true, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a('oe_CosNotificationComm_Event':typeID())), + ?match(false, 'CosNotifyChannelAdmin_SupplierAdmin':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_Filter' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_Filter'(doc) -> ["CosNotifyFilter_Filter"]; +'CosNotifyFilter_Filter'(suite) -> []; +'CosNotifyFilter_Filter'(_) -> + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc('_get_constraint_grammar')), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(add_constraints)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(modify_constraints)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(get_constraints)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(get_all_constraints)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(remove_all_constraints)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(destroy)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(match)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(match_structured)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(match_typed)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(attach_callback)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(detach_callback)), + ?nomatch(undefined, 'CosNotifyFilter_Filter':oe_tc(get_callbacks)), + ?match(undefined, 'CosNotifyFilter_Filter':oe_tc(undefined)), + ?match([_|_], 'CosNotifyFilter_Filter':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyFilter/Filter:1.0", + 'CosNotifyFilter_Filter':typeID()), + check_tc('CosNotifyFilter_Filter':oe_get_interface()), + ?match(true, 'CosNotifyFilter_Filter':oe_is_a('CosNotifyFilter_Filter':typeID())), + ?match(false, 'CosNotifyFilter_Filter':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_FilterAdmin' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_FilterAdmin'(doc) -> ["CosNotifyFilter_FilterAdmin"]; +'CosNotifyFilter_FilterAdmin'(suite) -> []; +'CosNotifyFilter_FilterAdmin'(_) -> + ?nomatch(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(add_filter)), + ?nomatch(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(remove_filter)), + ?nomatch(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(get_filter)), + ?nomatch(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(get_all_filters)), + ?nomatch(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(remove_all_filters)), + ?match(undefined, 'CosNotifyFilter_FilterAdmin':oe_tc(undefined)), + ?match([_|_], 'CosNotifyFilter_FilterAdmin':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyFilter/FilterAdmin:1.0", + 'CosNotifyFilter_FilterAdmin':typeID()), + check_tc('CosNotifyFilter_FilterAdmin':oe_get_interface()), + ?match(true, 'CosNotifyFilter_FilterAdmin':oe_is_a('CosNotifyFilter_FilterAdmin':typeID())), + ?match(false, 'CosNotifyFilter_FilterAdmin':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_FilterFactory' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_FilterFactory'(doc) -> ["CosNotifyFilter_FilterFactory"]; +'CosNotifyFilter_FilterFactory'(suite) -> []; +'CosNotifyFilter_FilterFactory'(_) -> + ?nomatch(undefined, 'CosNotifyFilter_FilterFactory':oe_tc(create_filter)), + ?nomatch(undefined, 'CosNotifyFilter_FilterFactory':oe_tc(create_mapping_filter)), + ?match(undefined, 'CosNotifyFilter_FilterFactory':oe_tc(undefined)), + ?match([_|_], 'CosNotifyFilter_FilterFactory':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyFilter/FilterFactory:1.0", + 'CosNotifyFilter_FilterFactory':typeID()), + check_tc('CosNotifyFilter_FilterFactory':oe_get_interface()), + ?match(true, 'CosNotifyFilter_FilterFactory':oe_is_a('CosNotifyFilter_FilterFactory':typeID())), + ?match(false, 'CosNotifyFilter_FilterFactory':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyFilter_MappingFilter' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyFilter_MappingFilter'(doc) -> ["CosNotifyFilter_MappingFilter"]; +'CosNotifyFilter_MappingFilter'(suite) -> []; +'CosNotifyFilter_MappingFilter'(_) -> + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc('_get_constraint_grammar')), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc('_get_value_type')), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc('_get_default_value')), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(add_mapping_constraints)), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(modify_mapping_constraints)), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(get_mapping_constraints)), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(get_all_mapping_constraints)), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(remove_all_mapping_constraints)), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(destroy)), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(match)), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(match_structured)), + ?nomatch(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(match_typed)), + ?match(undefined, 'CosNotifyFilter_MappingFilter':oe_tc(undefined)), + ?match([_|_], 'CosNotifyFilter_MappingFilter':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyFilter/MappingFilter:1.0", + 'CosNotifyFilter_MappingFilter':typeID()), + check_tc('CosNotifyFilter_MappingFilter':oe_get_interface()), + ?match(true, 'CosNotifyFilter_MappingFilter':oe_is_a('CosNotifyFilter_MappingFilter':typeID())), + ?match(false, 'CosNotifyFilter_MappingFilter':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_NotifyPublish' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_NotifyPublish'(doc) -> ["CosNotifyComm_NotifyPublish"]; +'CosNotifyComm_NotifyPublish'(suite) -> []; +'CosNotifyComm_NotifyPublish'(_) -> + ?nomatch(undefined, 'CosNotifyComm_NotifyPublish':oe_tc(offer_change)), + ?match(undefined, 'CosNotifyComm_NotifyPublish':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_NotifyPublish':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/NotifyPublish:1.0", + 'CosNotifyComm_NotifyPublish':typeID()), + check_tc('CosNotifyComm_NotifyPublish':oe_get_interface()), + ?match(true, 'CosNotifyComm_NotifyPublish':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(false, 'CosNotifyComm_NotifyPublish':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_NotifySubscribe' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_NotifySubscribe'(doc) -> ["CosNotifyComm_NotifySubscribe"]; +'CosNotifyComm_NotifySubscribe'(suite) -> []; +'CosNotifyComm_NotifySubscribe'(_) -> + ?nomatch(undefined, 'CosNotifyComm_NotifySubscribe':oe_tc(subscription_change)), + ?match(undefined, 'CosNotifyComm_NotifySubscribe':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_NotifySubscribe':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/NotifySubscribe:1.0", + 'CosNotifyComm_NotifySubscribe':typeID()), + check_tc('CosNotifyComm_NotifySubscribe':oe_get_interface()), + ?match(true, 'CosNotifyComm_NotifySubscribe':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(false, 'CosNotifyComm_NotifySubscribe':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_PullConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_PullConsumer'(doc) -> ["CosNotifyComm_PullConsumer"]; +'CosNotifyComm_PullConsumer'(suite) -> []; +'CosNotifyComm_PullConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyComm_PullConsumer':oe_tc(offer_change)), + ?nomatch(undefined, 'CosNotifyComm_PullConsumer':oe_tc(disconnect_pull_consumer)), + ?match(undefined, 'CosNotifyComm_PullConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_PullConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/PullConsumer:1.0", + 'CosNotifyComm_PullConsumer':typeID()), + check_tc('CosNotifyComm_PullConsumer':oe_get_interface()), + ?match(true, 'CosNotifyComm_PullConsumer':oe_is_a('CosNotifyComm_PullConsumer':typeID())), + ?match(true, 'CosNotifyComm_PullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(true, 'CosNotifyComm_PullConsumer':oe_is_a('CosEventComm_PullConsumer':typeID())), + ?match(false, 'CosNotifyComm_PullConsumer':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_PullSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_PullSupplier'(doc) -> ["CosNotifyComm_PullSupplier"]; +'CosNotifyComm_PullSupplier'(suite) -> []; +'CosNotifyComm_PullSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyComm_PullSupplier':oe_tc(subscription_change)), + ?nomatch(undefined, 'CosNotifyComm_PullSupplier':oe_tc(pull)), + ?nomatch(undefined, 'CosNotifyComm_PullSupplier':oe_tc(try_pull)), + ?nomatch(undefined, 'CosNotifyComm_PullSupplier':oe_tc(disconnect_pull_supplier)), + ?match(undefined, 'CosNotifyComm_PullSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_PullSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/PullSupplier:1.0", + 'CosNotifyComm_PullSupplier':typeID()), + check_tc('CosNotifyComm_PullSupplier':oe_get_interface()), + ?match(true, 'CosNotifyComm_PullSupplier':oe_is_a('CosNotifyComm_PullSupplier':typeID())), + ?match(true, 'CosNotifyComm_PullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(true, 'CosNotifyComm_PullSupplier':oe_is_a('CosEventComm_PullSupplier':typeID())), + ?match(false, 'CosNotifyComm_PullSupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_PushConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_PushConsumer'(doc) -> ["CosNotifyComm_PushConsumer"]; +'CosNotifyComm_PushConsumer'(suite) -> []; +'CosNotifyComm_PushConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyComm_PushConsumer':oe_tc(offer_change)), + ?nomatch(undefined, 'CosNotifyComm_PushConsumer':oe_tc(push)), + ?nomatch(undefined, 'CosNotifyComm_PushConsumer':oe_tc(disconnect_push_consumer)), + ?match(undefined, 'CosNotifyComm_PushConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_PushConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/PushConsumer:1.0", + 'CosNotifyComm_PushConsumer':typeID()), + check_tc('CosNotifyComm_PushConsumer':oe_get_interface()), + ?match(true, 'CosNotifyComm_PushConsumer':oe_is_a('CosNotifyComm_PushConsumer':typeID())), + ?match(true, 'CosNotifyComm_PushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(true, 'CosNotifyComm_PushConsumer':oe_is_a('CosEventComm_PushConsumer':typeID())), + ?match(false, 'CosNotifyComm_PushConsumer':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_PushSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_PushSupplier'(doc) -> ["CosNotifyComm_PushSupplier"]; +'CosNotifyComm_PushSupplier'(suite) -> []; +'CosNotifyComm_PushSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyComm_PushSupplier':oe_tc(subscription_change)), + ?nomatch(undefined, 'CosNotifyComm_PushSupplier':oe_tc(disconnect_push_supplier)), + ?match(undefined, 'CosNotifyComm_PushSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_PushSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/PushSupplier:1.0", + 'CosNotifyComm_PushSupplier':typeID()), + check_tc('CosNotifyComm_PushSupplier':oe_get_interface()), + ?match(true, 'CosNotifyComm_PushSupplier':oe_is_a('CosNotifyComm_PushSupplier':typeID())), + ?match(true, 'CosNotifyComm_PushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(true, 'CosNotifyComm_PushSupplier':oe_is_a('CosEventComm_PushSupplier':typeID())), + ?match(false, 'CosNotifyComm_PushSupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_SequencePullConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_SequencePullConsumer'(doc) -> ["CosNotifyComm_SequencePullConsumer"]; +'CosNotifyComm_SequencePullConsumer'(suite) -> []; +'CosNotifyComm_SequencePullConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyComm_SequencePullConsumer':oe_tc(disconnect_sequence_pull_consumer)), + ?nomatch(undefined, 'CosNotifyComm_SequencePullConsumer':oe_tc(offer_change)), + ?match(undefined, 'CosNotifyComm_SequencePullConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_SequencePullConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/SequencePullConsumer:1.0", + 'CosNotifyComm_SequencePullConsumer':typeID()), + check_tc('CosNotifyComm_SequencePullConsumer':oe_get_interface()), + ?match(true, 'CosNotifyComm_SequencePullConsumer':oe_is_a('CosNotifyComm_SequencePullConsumer':typeID())), + ?match(true, 'CosNotifyComm_SequencePullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(false, 'CosNotifyComm_SequencePullConsumer':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_SequencePullSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_SequencePullSupplier'(doc) -> ["CosNotifyComm_SequencePullSupplier"]; +'CosNotifyComm_SequencePullSupplier'(suite) -> []; +'CosNotifyComm_SequencePullSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyComm_SequencePullSupplier':oe_tc(pull_structured_events)), + ?nomatch(undefined, 'CosNotifyComm_SequencePullSupplier':oe_tc(try_pull_structured_events)), + ?nomatch(undefined, 'CosNotifyComm_SequencePullSupplier':oe_tc(disconnect_sequence_pull_supplier)), + ?nomatch(undefined, 'CosNotifyComm_SequencePullSupplier':oe_tc(subscription_change)), + ?match(undefined, 'CosNotifyComm_SequencePullSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_SequencePullSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/SequencePullSupplier:1.0", + 'CosNotifyComm_SequencePullSupplier':typeID()), + check_tc('CosNotifyComm_SequencePullSupplier':oe_get_interface()), + ?match(true, 'CosNotifyComm_SequencePullSupplier':oe_is_a('CosNotifyComm_SequencePullSupplier':typeID())), + ?match(true, 'CosNotifyComm_SequencePullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(false, 'CosNotifyComm_SequencePullSupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_SequencePushConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_SequencePushConsumer'(doc) -> ["CosNotifyComm_SequencePushConsumer"]; +'CosNotifyComm_SequencePushConsumer'(suite) -> []; +'CosNotifyComm_SequencePushConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyComm_SequencePushConsumer':oe_tc(push_structured_events)), + ?nomatch(undefined, 'CosNotifyComm_SequencePushConsumer':oe_tc(disconnect_sequence_push_consumer)), + ?nomatch(undefined, 'CosNotifyComm_SequencePushConsumer':oe_tc(offer_change)), + ?match(undefined, 'CosNotifyComm_SequencePushConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_SequencePushConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/SequencePushConsumer:1.0", + 'CosNotifyComm_SequencePushConsumer':typeID()), + check_tc('CosNotifyComm_SequencePushConsumer':oe_get_interface()), + ?match(true, 'CosNotifyComm_SequencePushConsumer':oe_is_a('CosNotifyComm_SequencePushConsumer':typeID())), + ?match(true, 'CosNotifyComm_SequencePushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(false, 'CosNotifyComm_SequencePushConsumer':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_SequencePushSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_SequencePushSupplier'(doc) -> ["CosNotifyComm_SequencePushSupplier"]; +'CosNotifyComm_SequencePushSupplier'(suite) -> []; +'CosNotifyComm_SequencePushSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyComm_SequencePushSupplier':oe_tc(disconnect_sequence_push_supplier)), + ?nomatch(undefined, 'CosNotifyComm_SequencePushSupplier':oe_tc(subscription_change)), + ?match(undefined, 'CosNotifyComm_SequencePushSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_SequencePushSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/SequencePushSupplier:1.0", + 'CosNotifyComm_SequencePushSupplier':typeID()), + check_tc('CosNotifyComm_SequencePushSupplier':oe_get_interface()), + ?match(true, 'CosNotifyComm_SequencePushSupplier':oe_is_a('CosNotifyComm_SequencePushSupplier':typeID())), + ?match(true, 'CosNotifyComm_SequencePushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(false, 'CosNotifyComm_SequencePushSupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_StructuredPullConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_StructuredPullConsumer'(doc) -> ["CosNotifyComm_StructuredPullConsumer"]; +'CosNotifyComm_StructuredPullConsumer'(suite) -> []; +'CosNotifyComm_StructuredPullConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyComm_StructuredPullConsumer':oe_tc(disconnect_structured_pull_consumer)), + ?nomatch(undefined, 'CosNotifyComm_StructuredPullConsumer':oe_tc(offer_change)), + ?match(undefined, 'CosNotifyComm_StructuredPullConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_StructuredPullConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/StructuredPullConsumer:1.0", + 'CosNotifyComm_StructuredPullConsumer':typeID()), + check_tc('CosNotifyComm_StructuredPullConsumer':oe_get_interface()), + ?match(true, 'CosNotifyComm_StructuredPullConsumer':oe_is_a('CosNotifyComm_StructuredPullConsumer':typeID())), + ?match(true, 'CosNotifyComm_StructuredPullConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(false, 'CosNotifyComm_StructuredPullConsumer':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_StructuredPullSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_StructuredPullSupplier'(doc) -> ["CosNotifyComm_StructuredPullSupplier"]; +'CosNotifyComm_StructuredPullSupplier'(suite) -> []; +'CosNotifyComm_StructuredPullSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyComm_StructuredPullSupplier':oe_tc(pull_structured_event)), + ?nomatch(undefined, 'CosNotifyComm_StructuredPullSupplier':oe_tc(try_pull_structured_event)), + ?nomatch(undefined, 'CosNotifyComm_StructuredPullSupplier':oe_tc(disconnect_structured_pull_supplier)), + ?nomatch(undefined, 'CosNotifyComm_StructuredPullSupplier':oe_tc(subscription_change)), + ?match(undefined, 'CosNotifyComm_StructuredPullSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_StructuredPullSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/StructuredPullSupplier:1.0", + 'CosNotifyComm_StructuredPullSupplier':typeID()), + check_tc('CosNotifyComm_StructuredPullSupplier':oe_get_interface()), + ?match(true, 'CosNotifyComm_StructuredPullSupplier':oe_is_a('CosNotifyComm_StructuredPullSupplier':typeID())), + ?match(true, 'CosNotifyComm_StructuredPullSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(false, 'CosNotifyComm_StructuredPullSupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_StructuredPushConsumer' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_StructuredPushConsumer'(doc) -> ["CosNotifyComm_StructuredPushConsumer"]; +'CosNotifyComm_StructuredPushConsumer'(suite) -> []; +'CosNotifyComm_StructuredPushConsumer'(_) -> + ?nomatch(undefined, 'CosNotifyComm_StructuredPushConsumer':oe_tc(push_structured_event)), + ?nomatch(undefined, 'CosNotifyComm_StructuredPushConsumer':oe_tc(disconnect_structured_push_consumer)), + ?nomatch(undefined, 'CosNotifyComm_StructuredPushConsumer':oe_tc(offer_change)), + ?match(undefined, 'CosNotifyComm_StructuredPushConsumer':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_StructuredPushConsumer':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/StructuredPushConsumer:1.0", + 'CosNotifyComm_StructuredPushConsumer':typeID()), + check_tc('CosNotifyComm_StructuredPushConsumer':oe_get_interface()), + ?match(true, 'CosNotifyComm_StructuredPushConsumer':oe_is_a('CosNotifyComm_StructuredPushConsumer':typeID())), + ?match(true, 'CosNotifyComm_StructuredPushConsumer':oe_is_a('CosNotifyComm_NotifyPublish':typeID())), + ?match(false, 'CosNotifyComm_StructuredPushConsumer':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNotifyComm_StructuredPushSupplier' +%% Description: +%%----------------------------------------------------------------- +'CosNotifyComm_StructuredPushSupplier'(doc) -> ["CosNotifyComm_StructuredPushSupplier"]; +'CosNotifyComm_StructuredPushSupplier'(suite) -> []; +'CosNotifyComm_StructuredPushSupplier'(_) -> + ?nomatch(undefined, 'CosNotifyComm_StructuredPushSupplier':oe_tc(disconnect_structured_push_supplier)), + ?nomatch(undefined, 'CosNotifyComm_StructuredPushSupplier':oe_tc(subscription_change)), + ?match(undefined, 'CosNotifyComm_StructuredPushSupplier':oe_tc(undefined)), + ?match([_|_], 'CosNotifyComm_StructuredPushSupplier':oe_get_interface()), + ?match("IDL:omg.org/CosNotifyComm/StructuredPushSupplier:1.0", + 'CosNotifyComm_StructuredPushSupplier':typeID()), + check_tc('CosNotifyComm_StructuredPushSupplier':oe_get_interface()), + ?match(true, 'CosNotifyComm_StructuredPushSupplier':oe_is_a('CosNotifyComm_StructuredPushSupplier':typeID())), + ?match(true, 'CosNotifyComm_StructuredPushSupplier':oe_is_a('CosNotifyComm_NotifySubscribe':typeID())), + ?match(false, 'CosNotifyComm_StructuredPushSupplier':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'oe_CosNotificationComm_Event' +%% Description: +%%----------------------------------------------------------------- +'oe_CosNotificationComm_Event'(doc) -> ["oe_CosNotificationComm_Event"]; +'oe_CosNotificationComm_Event'(suite) -> []; +'oe_CosNotificationComm_Event'(_) -> + ?nomatch(undefined, 'oe_CosNotificationComm_Event':oe_tc(callSeq)), + ?nomatch(undefined, 'oe_CosNotificationComm_Event':oe_tc(callAny)), + ?match(undefined, 'oe_CosNotificationComm_Event':oe_tc(undefined)), + ?match([_|_], 'oe_CosNotificationComm_Event':oe_get_interface()), + ?match("IDL:oe_CosNotificationComm/Event:1.0", + 'oe_CosNotificationComm_Event':typeID()), + check_tc('oe_CosNotificationComm_Event':oe_get_interface()), + ?match(true, 'oe_CosNotificationComm_Event':oe_is_a('oe_CosNotificationComm_Event':typeID())), + ?match(false, 'oe_CosNotificationComm_Event':oe_is_a("wrong")), + ok. + + + + +%%----------------------------------------------------------------- +%% MISC functions +%%----------------------------------------------------------------- +check_tc([]) -> + ok; +check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) -> + io:format("checked - ~s~n", [Op]), + lists:all(?checktc(Op), [RetType|InParameters]), + lists:all(?checktc(Op), OutParameters), + check_tc(T). + + diff --git a/lib/cosNotification/test/grammar_SUITE.erl b/lib/cosNotification/test/grammar_SUITE.erl new file mode 100644 index 0000000000..30aec89e5f --- /dev/null +++ b/lib/cosNotification/test/grammar_SUITE.erl @@ -0,0 +1,1094 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%-------------------------------------------------------------------- +%% File : grammar_SUITE.erl +%% Purpose : Testing the CosNotification BNF grammar. +%%-------------------------------------------------------------------- + +-module(grammar_SUITE). + + + +%%--------------- INCLUDES ----------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/include/ifr_types.hrl"). +%% cosEvent files. +-include_lib("cosEvent/include/CosEventChannelAdmin.hrl"). +%% Application files +-include_lib("cosNotification/include/CosNotification.hrl"). +-include_lib("cosNotification/include/CosNotifyChannelAdmin.hrl"). +-include_lib("cosNotification/include/CosNotifyComm.hrl"). +-include_lib("cosNotification/include/CosNotifyFilter.hrl"). + +-include_lib("cosNotification/src/CosNotification_Definitions.hrl"). + +-include("idl_output/notify_test.hrl"). + +-include("test_server.hrl"). + +%%--------------- DEFINES ------------------------------------ +-define(default_timeout, ?t:minutes(20)). +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, + union_api/1, enum_api/1, simple_types_api/1, + components_api/1, positional_api/1, variable_api/1, + init_per_testcase/2, fin_per_testcase/2]). + +-import(cosNotification_Filter, [create_filter/1, eval/2]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for the cosNotification interfaces", ""]; +all(suite) -> {req, + [], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [variable_api, union_api, enum_api, simple_types_api, components_api, + positional_api]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Config. + + +%%----------------------------------------------------------------- +%% simple types grammar tests +%%----------------------------------------------------------------- +simple_types_api(doc) -> ["CosNotification simple types grammar tests", ""]; +simple_types_api(suite) -> []; +simple_types_api(_Config) -> + %% Will always be true, no matter what kind of event we receive. + {ok,T1} = ?match({ok, _}, create_filter("2==2 and 3<4")), + ?match(true, eval(T1, ?not_CreateSE("DomainName","TypeName","EventName", + [],[], any:create(orber_tc:null(), null)))), + + %% Will always be true, no matter what kind of event we receive. + {ok,T2} = ?match({ok, _}, create_filter("")), + ?match(true, eval(T2, ?not_CreateSE("DomainName","TypeName","EventName", + [],[], any:create(orber_tc:null(), null)))), + + %% Check if $variable works + {ok,T3} = ?match({ok, _}, create_filter("$city == \'Berlin\'")), + ?match(true, eval(T3, ?not_CreateSE("DomainName","TypeName","EventName", + [#'CosNotification_Property'{name="city", + value=any:create(orber_tc:string(0), "Berlin")}], + [], any:create(orber_tc:null(), null)))), + ?match(false, eval(T3, ?not_CreateSE("DomainName","TypeName", "EventName", + [#'CosNotification_Property'{name="city", + value=any:create(orber_tc:string(0), "Dallas")}], + + [], any:create(orber_tc:null(), null)))), + + + {ok,T4} = ?match({ok, _}, create_filter("$zip == 44")), + ?match(true, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName", + [#'CosNotification_Property'{name="zip", + value=any:create(orber_tc:short(), 44)}], + + [], any:create(orber_tc:null(), null)))), + ?match(true, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName", + [],[], + any:create('CosNotification_Property':tc(), + #'CosNotification_Property' + {name="zip", + value=any:create(orber_tc:short(), + 44)})))), + ?match(false, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName", + [#'CosNotification_Property'{name="zip", + value=any:create(orber_tc:short(), 33)}], + + [], any:create(orber_tc:null(), null)))), + + %% Will always be true, no matter what kind of event we receive. + {ok,T5} = ?match({ok, _}, create_filter("\'oo'\~\'foobar\'")), + ?match(true, eval(T5, ?not_CreateSE("DomainName","TypeName","EventName", + [],[], any:create(orber_tc:null(), null)))), + %% Will always be false, no matter what kind of event we receive. + {ok,T6} = ?match({ok, _}, create_filter("\'o1'\~\'foobar\'")), + ?match(false, eval(T6, ?not_CreateSE("DomainName","TypeName","EventName", + [],[], any:create(orber_tc:null(), null)))), + + %% Can we apply the ~ operation as above using a variable + {ok,T7} = ?match({ok, _}, create_filter("$str~\'foobar\'")), + ?match(true, eval(T7, ?not_CreateSE("DomainName","TypeName","EventName", + [#'CosNotification_Property'{name="str", + value=any:create(orber_tc:string(0), "oo")}], + [], any:create(orber_tc:null(), null)))), + ?match(false, eval(T7, ?not_CreateSE("DomainName","TypeName","EventName", + [#'CosNotification_Property'{name="str", + value=any:create(orber_tc:string(0), "ok")}], + [], any:create(orber_tc:null(), null)))), + + + + {ok,_T8} = ?match({ok, _}, create_filter("$\\zip == 44444")), + + ok. + +%%----------------------------------------------------------------- +%% enum grammar tests +%%----------------------------------------------------------------- +enum_api(doc) -> ["CosNotification enum grammar tests", ""]; +enum_api(suite) -> []; +enum_api(_Config) -> + %% Accept events whose 'in' enum is set to the value 'HOUSE' or 'CAR'. + {ok,T1} = ?match({ok, _}, create_filter("$.\\in == HOUSE or $.\\in == CAR")), + + ?match(true, eval(T1, any:create(orber_tc:alias("IFRId","in",tk_any), + any:create({tk_enum, "IFRId", "in", ["HOUSE", "CAR"]}, + 'HOUSE')))), + ?match(false, eval(T1, any:create(orber_tc:alias("IFRId","in",tk_any), + any:create({tk_enum, "IFRId", "in", ["HOUSE", "CAR"]}, + 'GARAGE')))), + ok. + + +%%----------------------------------------------------------------- +%% Union grammar tests +%%----------------------------------------------------------------- +union_api(doc) -> ["CosNotification union grammar tests", ""]; +union_api(suite) -> []; +union_api(_Config) -> + {ok,T1} = ?match({ok, _}, create_filter("exist $.uni1._d and $.uni1._d == 1 and $.uni1.(1) == 10")), + {ok,T2} = ?match({ok, _}, create_filter("default $.uni1._d and $.uni1.() == 10")), + {ok,T3} = ?match({ok, _}, create_filter("default $.uni1._d and $.uni1.(999) == 10")), + ?match(true, eval(T1, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName",[],[], + any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0", + "uni1", + tk_any), + any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 1, + value=10}))))), + ?match(true, eval(T2, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName",[],[], + any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0", + "uni1", + tk_any), + any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 100, + value=10}))))), + ?match(true, eval(T3, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName",[],[], + any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0", + "uni1", + tk_any), + any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 100, + value=10}))))), + ?match(true, eval(T1, any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0", + "uni1", + tk_any), + any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 1, + value=10})))), + ?match(false, eval(T2, any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0", + "uni1", + tk_any), + any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 1, + value=10})))), + ?match(false, eval(T3, any:create(orber_tc:alias("IDL:notify_test/namedAny:1.0", + "uni1", + tk_any), + any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 1, + value=10})))), + ?match(true, eval(T1, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName",[],[], + any:create(notify_test_studies:tc(), #notify_test_studies + {uni1 = #notify_test_uni1{label= 1, value=10}, + gpa = 90, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 60)}], + monthly_attendance = {0,1,2,10}})))), + ?match(false, eval(T2, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName",[],[], + any:create(notify_test_studies:tc(), #notify_test_studies + {uni1 = #notify_test_uni1{label= 1, value=10}, + gpa = 90, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 60)}], + monthly_attendance = {0,1,2,10}})))), + ?match(false, eval(T3, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName",[],[], + any:create(notify_test_studies:tc(), #notify_test_studies + {uni1 = #notify_test_uni1{label= 1, value=10}, + gpa = 90, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 60)}], + monthly_attendance = {0,1,2,10}})))), + ?match(true, eval(T1, any:create(notify_test_studies:tc(), #notify_test_studies + {uni1 = #notify_test_uni1{label= 1, value=10}, + gpa = 90, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 60)}], + monthly_attendance = {0,1,2,10}}))), + ?match(false, eval(T2, any:create(notify_test_studies:tc(), #notify_test_studies + {uni1 = #notify_test_uni1{label= 1, value=10}, + gpa = 90, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 60)}], + monthly_attendance = {0,1,2,10}}))), + ?match(false, eval(T3, any:create(notify_test_studies:tc(), #notify_test_studies + {uni1 = #notify_test_uni1{label= 1, value=10}, + gpa = 90, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 60)}], + monthly_attendance = {0,1,2,10}}))), + + {ok,T4} = ?match({ok, _}, create_filter("exist $.alias.uni1._d and $.alias.uni1._d == 1 and $.alias.uni1.(1) == 10")), + ?match(true, eval(T4, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName",[],[], + any:create(orber_tc:alias(notify_test_studies:id(), + "alias", + notify_test_studies:tc()), + #notify_test_studies + {uni1 = #notify_test_uni1{label= 1, value=10}, + gpa = 90, tests = [], + monthly_attendance = {0,1,2,10}})))), + ?match(true, eval(T4, any:create(orber_tc:alias(notify_test_studies:id(), + "alias", + notify_test_studies:tc()), + #notify_test_studies + {uni1 = #notify_test_uni1{label= 1, value=10}, + gpa = 90, tests = [], + monthly_attendance = {0,1,2,10}}))), + %% Accept events with a default union discriminator set to the value 2. + {ok,T5} = ?match({ok, _}, create_filter("default $._d and $.defvalue == 2")), + ?match(true, eval(T5, any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 100, value=2}))), + %% label not default. + ?match(false, eval(T5, any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 2, value=2}))), + %% Default does not exist (nor the component defvalue) + ?match(false, eval(T5, any:create(notify_test_uni2:tc(), + #notify_test_uni2{label= 100, value=2}))), + %% Both wrong + ?match(false, eval(T5, any:create(notify_test_uni2:tc(), + #notify_test_uni2{label= 2, value=2}))), + + {ok,T6} = ?match({ok, _}, create_filter("default $._d and $.(-8) == 2")), + ?match(true, eval(T6, any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 100, value=2}))), + %% label not default. + ?match(false, eval(T6, any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 2, value=2}))), + %% Default does not exist (nor the component defvalue) + ?match(false, eval(T6, any:create(notify_test_uni2:tc(), + #notify_test_uni2{label= 100, value=2}))), + %% Both wrong + ?match(false, eval(T6, any:create(notify_test_uni2:tc(), + #notify_test_uni2{label= 2, value=2}))), + %% the same as the above, but we try to access a label that is not default + {ok,T7} = ?match({ok, _}, create_filter("default $._d and $.(2) == 2")), + ?match({error, _}, eval(T7, any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 100, value=2}))), + + %% Must be a default-union with its 'defvalue' set to 2. + {ok,T8} = ?match({ok, _}, create_filter("default $._d and $.('defvalue') == 2")), + ?match(true, eval(T8, any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 100, value=2}))), + %% label not default. + ?match(false, eval(T8, any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 2, value=2}))), + %% Default does not exist (nor the component defvalue) + ?match(false, eval(T8, any:create(notify_test_uni2:tc(), + #notify_test_uni2{label= 100, value=2}))), + %% Both wrong + ?match(false, eval(T8, any:create(notify_test_uni2:tc(), + #notify_test_uni2{label= 2, value=2}))), + + %% Must be a default-union with its value set to 2. + {ok,T9} = ?match({ok, _}, create_filter("default $._d and $.(+100) == 2")), + ?match(true, eval(T9, any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 100, value=2}))), + %% label not default. + ?match(false, eval(T9, any:create(notify_test_uni1:tc(), + #notify_test_uni1{label= 2, value=2}))), + %% Default does not exist (nor the component defvalue) + ?match(false, eval(T9, any:create(notify_test_uni2:tc(), + #notify_test_uni2{label= 100, value=2}))), + %% Both wrong + ?match(false, eval(T9, any:create(notify_test_uni2:tc(), + #notify_test_uni2{label= 2, value=2}))), + + %% So far, we have only tested to access the union itself. No will use more + %% complex union members. + %% T10 and T11 is "equal" + {ok,T10} = ?match({ok, _}, create_filter("$.M < 54")), + {ok,T11} = ?match({ok, _}, create_filter("$.(5) < 54")), + ?match(false, eval(T10, any:create(notify_test_K:tc(), + #notify_test_K{label= 5, value=54}))), + ?match(false, eval(T11, any:create(notify_test_K:tc(), + #notify_test_K{label= 5, value=54}))), + ?match(true, eval(T10, any:create(notify_test_K:tc(), + #notify_test_K{label= 5, value=50}))), + ?match(true, eval(T11, any:create(notify_test_K:tc(), + #notify_test_K{label= 5, value=50}))), + ?match({error,_}, eval(T10, any:create(notify_test_K:tc(), + #notify_test_K{label= -1, value=50}))), + ?match({error,_}, eval(T11, any:create(notify_test_K:tc(), + #notify_test_K{label= -1, value=50}))), + + %% T12 and T13 is "equal" + {ok,T12} = ?match({ok, _}, create_filter("$.L.C < 128")), + {ok,T13} = ?match({ok, _}, create_filter("$.(3).2 < 128")), + ?match(true, eval(T12, any:create(notify_test_K:tc(), + #notify_test_K{label= 3, value= + #notify_test_X{'A' = 1, + 'B' = "string", + 'C' = 120}}))), + ?match(true, eval(T13, any:create(notify_test_K:tc(), + #notify_test_K{label= 3, value= + #notify_test_X{'A' = 1, + 'B' = "string", + 'C' = 120}}))), + ?match(false, eval(T12, any:create(notify_test_K:tc(), + #notify_test_K{label= 3, value= + #notify_test_X{'A' = 1, + 'B' = "string", + 'C' = 200}}))), + ?match(false, eval(T13, any:create(notify_test_K:tc(), + #notify_test_K{label= 3, value= + #notify_test_X{'A' = 1, + 'B' = "string", + 'C' = 200}}))), + + %% Test if 'putty' is a substring of K + {ok,T15} = ?match({ok, _}, create_filter("'putty' ~ $.(2)")), + {ok,T16} = ?match({ok, _}, create_filter("'putty' ~ $.K")), + ?match(true, eval(T15, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "isputtyok"}))), + ?match(true, eval(T16, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "isputtyok"}))), + ?match(false, eval(T15, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "notputtok"}))), + ?match(false, eval(T16, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "notputtok"}))), + + {ok,_T17} = ?match({ok, _}, create_filter("'putty' ~ $.(3).1")), + {ok,_T18} = ?match({ok, _}, create_filter("'putty' ~ $.L.B")), + ?match(true, eval(T12, any:create(notify_test_K:tc(), + #notify_test_K{label= 3, value= + #notify_test_X{'A' = 1, + 'B' = "isputtyok", + 'C' = 120}}))), + ?match(true, eval(T13, any:create(notify_test_K:tc(), + #notify_test_K{label= 3, value= + #notify_test_X{'A' = 1, + 'B' = "isputtyok", + 'C' = 120}}))), + ?match(false, eval(T12, any:create(notify_test_K:tc(), + #notify_test_K{label= 3, value= + #notify_test_X{'A' = 1, + 'B' = "notputtok", + 'C' = 200}}))), + ?match(false, eval(T13, any:create(notify_test_K:tc(), + #notify_test_K{label= 3, value= + #notify_test_X{'A' = 1, + 'B' = "notputtok", + 'C' = 200}}))), + + %% Please observe that the switch 0 and 2 is defined to be equivalent. + {ok,T19} = ?match({ok, _}, create_filter("$._d == 2 and $.(0) != 'hoob'")), + {ok,T20} = ?match({ok, _}, create_filter("$._d == 2 and $.(2) != 'hoob'")), + ?match(true, eval(T19, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "nothoob"}))), + ?match(true, eval(T20, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "nothoob"}))), + ?match(false, eval(T19, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "hoob"}))), + ?match(false, eval(T20, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "hoob"}))), + + ?match(false, eval(T19, any:create(notify_test_K:tc(), + #notify_test_K{label= 5, value= 55}))), + ?match(false, eval(T20, any:create(notify_test_K:tc(), + #notify_test_K{label= 5, value= 55}))), + + ?match(false, eval(T19, any:create(notify_test_K:tc(), + #notify_test_K{label= 100, value= "nothoob"}))), + ?match(false, eval(T20, any:create(notify_test_K:tc(), + #notify_test_K{label= 100, value= "nothoob"}))), + + {ok,T21} = ?match({ok, _}, create_filter("exist $.K")), + {ok,T22} = ?match({ok, _}, create_filter("exist $.(0) or exist $.(2)")), + ?match(true, eval(T21, any:create(notify_test_K:tc(), + #notify_test_K{label= 0, value= "hoob"}))), + ?match(true, eval(T22, any:create(notify_test_K:tc(), + #notify_test_K{label= 0, value= "hoob"}))), + ?match(true, eval(T21, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "hoob"}))), + ?match(true, eval(T22, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "hoob"}))), + ?match(false, eval(T21, any:create(notify_test_K:tc(), + #notify_test_K{label= 5, value= 55}))), + ?match(false, eval(T22, any:create(notify_test_K:tc(), + #notify_test_K{label= 5, value= 55}))), + + + %% Please observe that the switch 0 and 2 is defined to be equivalent. + {ok,T23} = ?match({ok, _}, create_filter("exist $.(2)")), + {ok,T24} = ?match({ok, _}, create_filter("exist $.(0)")), + ?match(true, eval(T23, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "hoob"}))), + ?match(false, eval(T24, any:create(notify_test_K:tc(), + #notify_test_K{label= 2, value= "hoob"}))), + ?match(false, eval(T23, any:create(notify_test_K:tc(), + #notify_test_K{label= 0, value= "hoob"}))), + ?match(true, eval(T24, any:create(notify_test_K:tc(), + #notify_test_K{label= 0, value= "hoob"}))), + ?match(false, eval(T23, any:create(notify_test_K:tc(), + #notify_test_K{label= 5, value= 55}))), + ?match(false, eval(T24, any:create(notify_test_K:tc(), + #notify_test_K{label= 5, value= 55}))), + + ok. + +%%----------------------------------------------------------------- +%% Variables grammar tests +%%----------------------------------------------------------------- +variable_api(doc) -> ["CosNotification variables grammar tests", ""]; +variable_api(suite) -> []; +variable_api(_Config) -> + %% Accept all "CommunicationsAlarm" events + {ok,T0} = ?match({ok, _}, create_filter("$type_name == 'CommunicationsAlarm'")), + + ?match(true, eval(T0, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName",[],[], + any:create(orber_tc:null(), null)))), + ?match(false, eval(T0, ?not_CreateSE("DomainName","CommunicationsOK", + "EventName", [],[], + any:create(orber_tc:null(), null)))), + ?match(true, eval(T0, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName", [],[], + any:create(orber_tc:alias("IFRId", "type_name", + orber_tc:string(0)), + "CommunicationsOK")))), + + ?match(true, eval(T0, any:create(orber_tc:alias("IFRId", "type_name", + orber_tc:string(0)), + "CommunicationsAlarm"))), + ?match(false, eval(T0, any:create(orber_tc:alias("IFRId", "type_name", + orber_tc:string(0)), + "CommunicationsOK"))), + + + %% Accept all "CommunicationsAlarm" events but no "lost_packet" messages. + {ok,T1} = ?match({ok, _}, create_filter("$type_name == 'CommunicationsAlarm' and not ($event_name == 'lost_packet')")), + + ?match(true, eval(T1, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName",[],[], + any:create(orber_tc:null(), null)))), + ?match(false, eval(T1, ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", [],[], + any:create(orber_tc:null(), null)))), + ?match(true, + eval(T1, any:create(orber_tc:sequence('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="type_name", + value=any:create(orber_tc:string(0), "CommunicationsAlarm")}, + #'CosNotification_Property'{name="event_name", + value=any:create(orber_tc:string(0), "EventName")}]))), + ?match(false, + eval(T1, any:create(orber_tc:sequence('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="type_name", + value=any:create(orber_tc:string(0), "CommunicationsAlarm")}, + #'CosNotification_Property'{name="event_name", + value=any:create(orber_tc:string(0), "lost_packet")}]))), + + + %% Accept "CommunicationsAlarm" events with priorities ranging from 1 to 5. + {ok,T2} = ?match({ok, _}, create_filter("$type_name == 'CommunicationsAlarm' and $priority >= 1 and $priority <= 5")), + ?match(true, eval(T2, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 2)}], + [], any:create(orber_tc:null(), null)))), + ?match(false, eval(T2, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 20)}], + [], any:create(orber_tc:null(), null)))), + + %% Select "MOVIE" events featuring at least 3 of the Marx Brothers. + {ok,T3} = ?match({ok, _}, create_filter("$type_name == 'MOVIE' and (('groucho' in $starlist) + ('chico' in $starlist) + ('harpo' in $starlist) + ('zeppo' in $starlist) + ('gummo' in $starlist)) > 2")), + ?match(true, eval(T3, ?not_CreateSE("DomainName","MOVIE", + "EventName", + [#'CosNotification_Property'{name="starlist", + value=any:create(orber_tc:sequence(orber_tc:string(0),0), + ["groucho", "harpo", "sam", "gummo"])}], + [], any:create(orber_tc:null(), null)))), + ?match(false, eval(T3, ?not_CreateSE("DomainName","MOVIE", + "EventName", + [#'CosNotification_Property'{name="starlist", + value=any:create(orber_tc:sequence(orber_tc:string(0),0), + ["frodo", "bilbo", "sam", "gummo"])}], + [], any:create(orber_tc:null(), null)))), + %% Accept students that took all 3 tests and had an average score of at least 80%. + {ok,T4} = ?match({ok, _}, create_filter("$test._length == 3 and ($test[0].score + $test[1].score + $test[2].score)/3 >=80")), + ?match(true, eval(T4, ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property'{name="test", + value=any:create(orber_tc:array(notify_test_data:tc(),0), + {#notify_test_data{score=75}, + #notify_test_data{score=80}, + #notify_test_data{score=85}})}], + any:create(orber_tc:null(), null)))), + ?match(false, eval(T4, ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property'{name="test", + value=any:create(orber_tc:array(notify_test_data:tc(),0), + {#notify_test_data{score=75}, + #notify_test_data{score=80}, + #notify_test_data{score=80}})}], + any:create(orber_tc:null(), null)))), + ?match(false, eval(T4, ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property'{name="test", + value=any:create(orber_tc:array(notify_test_data:tc(),0), + {#notify_test_data{score=75}, + #notify_test_data{score=85}})}], + any:create(orber_tc:null(), null)))), + %% Select processes that exceed a certain usage threshold. + {ok,T5} = ?match({ok, _}, create_filter("$memsize / 5.5 + $cputime * 1275.0 + $filesize * 1.25 > 500000.0")), + ?match(true, eval(T5, ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property'{name="memsize", + value=any:create(orber_tc:float(), 5.5)}, + #'CosNotification_Property'{name="cputime", + value=any:create(orber_tc:float(), 0.00078431137)}, + #'CosNotification_Property'{name="filesize", + value=any:create(orber_tc:float(), 500000)}], + any:create(orber_tc:null(), null)))), + ?match(false, eval(T5, ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property'{name="memsize", + value=any:create(orber_tc:float(), 5.5)}, + #'CosNotification_Property'{name="cputime", + value=any:create(orber_tc:float(), 0.00078431137)}, + #'CosNotification_Property'{name="filesize", + value=any:create(orber_tc:float(), 500)}], + any:create(orber_tc:null(), null)))), + ?match({error, _}, eval(T5, ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property'{name="memsize", + value=any:create(orber_tc:float(), 5.5)}, + #'CosNotification_Property'{name="filesize", + value=any:create(orber_tc:float(), 500)}], + any:create(orber_tc:null(), null)))), + + ?match(true, eval(T5, ?not_CreateSE("DomainName","TypeName", + "EventName", [], [], + any:create(orber_tc:sequence('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="memsize", + value=any:create(orber_tc:float(), 5.5)}, + #'CosNotification_Property'{name="cputime", + value=any:create(orber_tc:float(), 0.00078431137)}, + #'CosNotification_Property'{name="filesize", + value=any:create(orber_tc:float(), 500000)}])))), + ?match(false, eval(T5, ?not_CreateSE("DomainName","TypeName", + "EventName", [], [], + any:create(orber_tc:sequence('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="memsize", + value=any:create(orber_tc:float(), 5.5)}, + #'CosNotification_Property'{name="cputime", + value=any:create(orber_tc:float(), 0.00078431137)}, + #'CosNotification_Property'{name="filesize", + value=any:create(orber_tc:float(), 500)}])))), + ?match({error, _}, eval(T5, ?not_CreateSE("DomainName","TypeName", + "EventName", [], [], + any:create(orber_tc:sequence('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="memsize", + value=any:create(orber_tc:float(), 5.5)}, + #'CosNotification_Property'{name="filesize", + value=any:create(orber_tc:float(), 500)}])))), + + ?match(true, eval(T5, any:create(orber_tc:sequence('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="memsize", + value=any:create(orber_tc:float(), 5.5)}, + #'CosNotification_Property'{name="cputime", + value=any:create(orber_tc:float(), 0.00078431137)}, + #'CosNotification_Property'{name="filesize", + value=any:create(orber_tc:float(), 500000)}]))), + ?match(false, eval(T5, any:create(orber_tc:sequence('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="memsize", + value=any:create(orber_tc:float(), 5.5)}, + #'CosNotification_Property'{name="cputime", + value=any:create(orber_tc:float(), 0.00078431137)}, + #'CosNotification_Property'{name="filesize", + value=any:create(orber_tc:float(), 500)}]))), + ?match({error, _}, eval(T5, any:create(orber_tc:sequence('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="memsize", + value=any:create(orber_tc:float(), 5.5)}, + #'CosNotification_Property'{name="filesize", + value=any:create(orber_tc:float(), 500)}]))), + + %% Accept events where a threshold has the unscoped type name 'data'. + {ok,T6} = ?match({ok, _}, create_filter("exist $threshold._type_id and $threshold._type_id == 'data'")), + ?match(true, eval(T6, any:create(orber_tc:alias(notify_test_data:id(), + "threshold", + notify_test_data:tc()), + #notify_test_data{score = 10, name = "Erlang"}))), + + + + ?match(true, eval(T6, ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property' + {name="threshold", + value=any:create(notify_test_data:tc(), + #notify_test_data + {score = 10, + name = "Erlang"})}], + any:create(orber_tc:null(), null)))), + + + ?match(true, eval(T6, ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property' + {name="NotThreshold", + value=any:create(notify_test_data:tc(), + #notify_test_data + {score = 10, + name = "Erlang"})}], + any:create(orber_tc:alias(notify_test_data:id(), + "threshold", + notify_test_data:tc()), + #notify_test_data{score = 10, name = "Erlang"})))), + + + + %% Accept events with a serviceUser property of the correct standard type. + {ok,T7} = ?match({ok, _}, create_filter("$violation(TestData)._repos_id == 'IDL:notify_test/data:1.0'")), + ?match(true, eval(T7, ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property' + {name="violation", + value=any:create(orber_tc:array('CosNotification_Property':tc(),0), + [#'CosNotification_Property' + {name="TestData", + value=any:create(notify_test_data:tc(), + #notify_test_data + {score=100, + name="perfect score"})}])}], + any:create(orber_tc:null(), null)))), + + {ok,T8} = ?match({ok, _}, create_filter("$type_name == 'CommunicationsAlarm' and $event_name == 'lost_packet' and $priority < 2")), + %% All correct + Event1 = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + %% Priority to high + Event2 = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 2)}], + [], any:create(orber_tc:null(), null)), + %% Misspell event_name, i.e., lost_packets instead of lost_packet + Event3 = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packets", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + %% Another type_name + Event4 = ?not_CreateSE("DomainName","TemperatureAlarm", + "lost_packets", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + + ?match(true, eval(T8, Event1)), + ?match(false, eval(T8, Event2)), + ?match(false, eval(T8, Event3)), + ?match(false, eval(T8, Event4)), + + {ok,T9} = ?match({ok, _}, create_filter("$gpa < 80 or $tests(midterm) > $tests(final) or $monthly_attendance[3] < 10")), + + %% midterm > final yields true, the others false + Event5 = ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property' + {name="tests", + value=any:create(orber_tc:array('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="midterm", + value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property'{name="final", + value=any:create(orber_tc:short(), 60)}])}, + #'CosNotification_Property'{name="monthly_attendance", + value=any:create(orber_tc:array(orber_tc:short(), 0), + {0,1,2,10})}, + #'CosNotification_Property'{name="gpa", + value=any:create(orber_tc:short(), 90)}], + any:create(orber_tc:null(), null)), + + %% monthly_attendance[3] < 10 yields true, the others false + Event6 = ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property'{name="tests", + value=any:create(orber_tc:array('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="midterm", + value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property'{name="final", + value=any:create(orber_tc:short(), 80)}])}, + #'CosNotification_Property'{name="monthly_attendance", + value=any:create(orber_tc:array(orber_tc:short(), 0), + {0,1,2,9})}, + #'CosNotification_Property'{name="gpa", + value=any:create(orber_tc:short(), 90)}], + any:create(orber_tc:null(), null)), + + %% gpa < 80 true, rest false. + Event7 = ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property'{name="tests", + value=any:create(orber_tc:array('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="midterm", + value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property'{name="final", + value=any:create(orber_tc:short(), 80)}])}, + #'CosNotification_Property'{name="monthly_attendance", + value=any:create(orber_tc:array(orber_tc:short(), 0), + {0,1,2,10})}, + #'CosNotification_Property'{name="gpa", + value=any:create(orber_tc:short(), 70)}], + any:create(orber_tc:null(), null)), + + %% All false + Event8 = ?not_CreateSE("DomainName","TypeName", + "EventName", [], + [#'CosNotification_Property'{name="tests", + value=any:create(orber_tc:array('CosNotification_Property':tc(),0), + [#'CosNotification_Property'{name="midterm", + value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property'{name="final", + value=any:create(orber_tc:short(), 80)}])}, + #'CosNotification_Property'{name="monthly_attendance", + value=any:create(orber_tc:array(orber_tc:short(), 0), + {0,1,2,10})}, + #'CosNotification_Property'{name="gpa", + value=any:create(orber_tc:short(), 80)}], + any:create(orber_tc:null(), null)), + + ?match(true, eval(T9, Event5)), + ?match(true, eval(T9, Event6)), + ?match(true, eval(T9, Event7)), + ?match(false, eval(T9, Event8)), + ok. + +%%----------------------------------------------------------------- +%% Misc grammar tests +%%----------------------------------------------------------------- +positional_api(doc) -> ["CosNotification positional notation grammar tests", ""]; +positional_api(suite) -> []; +positional_api(_Config) -> + {ok,T1} = ?match({ok, _}, create_filter("$.3 < 80 or $.1(midterm) > $.1(final) or $.2[3] < 10")), + + %% midterm > final yields true, the others false + Event1 = any:create(notify_test_studies:tc(), #notify_test_studies + {gpa = 90, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 60)}], + monthly_attendance = {0,1,2,10}}), + %% monthly_attendance[3] < 10 yields true, the others false + Event2 = any:create(notify_test_studies:tc(), #notify_test_studies + {gpa = 90, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 80)}], + monthly_attendance = {0,1,2,9}}), + %% gpa < 80 true, rest false. + Event3 = any:create(notify_test_studies:tc(), #notify_test_studies + {gpa = 70, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 80)}], + monthly_attendance = {0,1,2,10}}), + %% All false + Event4 = any:create(notify_test_studies:tc(), #notify_test_studies + {gpa = 80, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 80)}], + monthly_attendance = {0,1,2,10}}), + + ?match(true, eval(T1, Event1)), + ?match(true, eval(T1, Event2)), + ?match(true, eval(T1, Event3)), + ?match(false, eval(T1, Event4)), + + {ok,T2} = ?match({ok, _}, create_filter("$.0.0.0.1 == 'CommunicationsAlarm'")), + + Event5 = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", [], [], + any:create(orber_tc:null(), null)), + + ?match(true, eval(T2, Event5)), + + ok. + +%%----------------------------------------------------------------- +%% Components grammar tests +%%----------------------------------------------------------------- +components_api(doc) -> ["CosNotification components grammar tests", ""]; +components_api(suite) -> []; +components_api(_Config) -> + {ok,T1} = ?match({ok, _}, create_filter("$ == 2")), + ?match(true, eval(T1, ?not_CreateSE("DomainName","TypeName","EventName", + [],[], any:create(orber_tc:short(), 2)))), + ?match(true, eval(T1, any:create(orber_tc:short(), 2))), + ?match(false, eval(T1, ?not_CreateSE("DomainName","TypeName","EventName", + [],[], any:create(orber_tc:short(), 3)))), + ?match(false, eval(T1, any:create(orber_tc:short(), 3))), + + %% Select "MOVIE" events featuring at least 3 of the Marx Brothers. + {ok,T2} = ?match({ok, _}, create_filter("$type_name == 'MOVIE' and (('groucho' in $.starlist) + ('chico' in $.starlist) + ('harpo' in $.starlist) + ('zeppo' in $.starlist) + ('gummo' in $.starlist)) > 2")), + ?match(true, eval(T2, ?not_CreateSE("DomainName","MOVIE", "EventName", [], [], + any:create(orber_tc:alias("IFRId","starlist",tk_any), + any:create(orber_tc:sequence(orber_tc:string(0),0), + ["groucho", "harpo", "sam", "gummo"]))))), + ?match(false, eval(T2, ?not_CreateSE("DomainName","MOVIE", "EventName", [], [], + any:create(orber_tc:alias("IFRId","starlist",tk_any), + any:create(orber_tc:sequence(orber_tc:string(0),0), + ["frodo", "bilbo", "sam", "gummo"]))))), + + %% Accept only recent events (e.g., generated within the last 15 minutes or so). + {ok,_T3} = ?match({ok, _}, create_filter("$origination_timestamp.high + 2 < $curtime.high")), + + + %% Accept students that took all 3 tests and had an average score of at least 80%. + {ok,T4} = ?match({ok, _}, create_filter("$.test._length == 3 and ($.test[0].score + $.test[1].score + $.test[2].score)/3 >=80")), + ?match(true, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName", [], [], + any:create(orber_tc:alias("IFRId","test",tk_any), + any:create(orber_tc:array(notify_test_data:tc(),0), + {#notify_test_data{score=75}, + #notify_test_data{score=80}, + #notify_test_data{score=85}}))))), + ?match(false, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName", [], [], + any:create(orber_tc:alias("IFRId","test",tk_any), + any:create(orber_tc:array(notify_test_data:tc(),0), + {#notify_test_data{score=75}, + #notify_test_data{score=80}, + #notify_test_data{score=80}}))))), + ?match(false, eval(T4, ?not_CreateSE("DomainName","TypeName", "EventName", [], [], + any:create(orber_tc:alias("IFRId","test",tk_any), + any:create(orber_tc:array(notify_test_data:tc(),0), + {#notify_test_data{score=75}, + #notify_test_data{score=80}}))))), + + %% Select processes that exceed a certain usage threshold. + {ok,T5} = ?match({ok, _}, create_filter("$.memsize / 5.5 + $.cputime * 1275.0 + $.filesize * 1.25 > 500000.0")), + ?match(true, eval(T5, ?not_CreateSE("DomainName","TypeName", "EventName", [], [], + any:create(notify_test_computer:tc(), + #notify_test_computer + {memsize=5.5, + cputime = 0.00078431137, + filesize = 500000})))), + ?match(false, eval(T5, ?not_CreateSE("DomainName","TypeName", "EventName", [], [], + any:create(notify_test_computer:tc(), + #notify_test_computer + {memsize=5.5, + cputime = 0.00078431137, + filesize = 500})))), + ?match({error,_}, eval(T5, ?not_CreateSE("DomainName","TypeName", "EventName", [], [], + any:create(notify_test_computer:tc(), + #notify_test_computer + {memsize=5.5, + cputime = 0.00078431137})))), + + %% Accept only Notification Service structured events. + {ok,T6} = ?match({ok, _}, create_filter("$._repos_id == 'IDL:omg.org/CosNotification/StructuredEvent:1.0'")), + ?match(true, eval(T6, ?not_CreateSE("DomainName","CommunicationsAlarm", + "EventName", + [], [], any:create(orber_tc:null(), null)))), + + + + %% Accept only those events that have a specified security "rights list". + {ok,T7} = ?match({ok, _}, create_filter("exist $.header.variable_header(required_rights)")), + ?match(false, eval(T7, ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)))), + ?match(true, eval(T7, ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", + [#'CosNotification_Property'{name="required_rights", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)))), + + + {ok,T8} = ?match({ok, _}, create_filter("$.header.fixed_header.event_type.type_name == 'CommunicationsAlarm' and $.header.fixed_header.event_name == 'lost_packet' and $.header.variable_header(priority) < 2")), + %% All correct + Event1 = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + %% Priority to high + Event2 = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 2)}], + [], any:create(orber_tc:null(), null)), + %% Misspell event_name, i.e., lost_packets instead of lost_packet + Event3 = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packets", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + %% Another type_name + Event4 = ?not_CreateSE("DomainName","TemperatureAlarm", + "lost_packets", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + + ?match(true, eval(T8, Event1)), + ?match(false, eval(T8, Event2)), + ?match(false, eval(T8, Event3)), + ?match(false, eval(T8, Event4)), + + + {ok,T9} = ?match({ok, _}, create_filter("$.gpa < 80 or $.tests(midterm) > $.tests(final) or $.monthly_attendance[3] < 10")), + + %% midterm > final yields true, the others false + Event5 = ?not_CreateSE("DomainName","TypeName", + "EventName", [], [], + any:create(notify_test_studies:tc(), #notify_test_studies + {gpa = 90, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 60)}], + monthly_attendance = {0,1,2,10}})), + %% monthly_attendance[3] < 10 yields true, the others false + Event6 = ?not_CreateSE("DomainName","TypeName", + "EventName", [], [], + any:create(notify_test_studies:tc(), #notify_test_studies + {gpa = 90, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 80)}], + monthly_attendance = {0,1,2,9}})), + %% gpa < 80 true, rest false. + Event7 = ?not_CreateSE("DomainName","TypeName", + "EventName", [], [], + any:create(notify_test_studies:tc(), #notify_test_studies + {gpa = 70, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 80)}], + monthly_attendance = {0,1,2,10}})), + %% All false + Event8 = ?not_CreateSE("DomainName","TypeName", + "EventName", [], [], + any:create(notify_test_studies:tc(), #notify_test_studies + {gpa = 80, + tests = [#'CosNotification_Property' + {name="midterm", value=any:create(orber_tc:short(), 70)}, + #'CosNotification_Property' + {name="final", value=any:create(orber_tc:short(), 80)}], + monthly_attendance = {0,1,2,10}})), + + ?match(true, eval(T9, Event5)), + ?match(true, eval(T9, Event6)), + ?match(true, eval(T9, Event7)), + ?match(false, eval(T9, Event8)), + ok. + + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- + +%%-------------------- End of Module ------------------------------ diff --git a/lib/cosNotification/test/notification_SUITE.erl b/lib/cosNotification/test/notification_SUITE.erl new file mode 100644 index 0000000000..e2c560e4de --- /dev/null +++ b/lib/cosNotification/test/notification_SUITE.erl @@ -0,0 +1,2185 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%-------------------------------------------------------------------- +%% File : notification_SUITE.erl +%% Purpose : +%%-------------------------------------------------------------------- + +-module(notification_SUITE). + +%%--------------- INCLUDES ----------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/include/ifr_types.hrl"). +%% cosEvent files. +-include_lib("cosEvent/include/CosEventChannelAdmin.hrl"). +%% Application files +-include_lib("cosNotification/include/CosNotification.hrl"). +-include_lib("cosNotification/include/CosNotifyChannelAdmin.hrl"). +-include_lib("cosNotification/include/CosNotifyComm.hrl"). +-include_lib("cosNotification/include/CosNotifyFilter.hrl"). + +-include_lib("cosNotification/src/CosNotification_Definitions.hrl"). + +-include("idl_output/notify_test.hrl"). + +-include("test_server.hrl"). + +%%--------------- DEFINES ------------------------------------ +-define(default_timeout, ?t:minutes(20)). +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(defaultQoS, + [#'CosNotification_Property'{name='CosNotification':'MaximumBatchSize'(), + value=any:create(orber_tc:long(), 100)}, + #'CosNotification_Property'{name='CosNotification':'PacingInterval'(), + value=any:create(orber_tc:unsigned_long_long(), + 20000000)}, + #'CosNotification_Property'{name='CosNotification':'OrderPolicy'(), + value=any:create(orber_tc:short(), + 'CosNotification':'AnyOrder'())}, + #'CosNotification_Property'{name='CosNotification':'EventReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'BestEffort'())}, + #'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'BestEffort'())}, + #'CosNotification_Property'{name='CosNotification':'DiscardPolicy'(), + value=any:create(orber_tc:short(), + 'CosNotification':'AnyOrder'())}, + #'CosNotification_Property'{name='CosNotification':'StartTimeSupported'(), + value=any:create(orber_tc:boolean(), false)}, + #'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(), + value=any:create(orber_tc:boolean(), false)}, + #'CosNotification_Property'{name='CosNotification':'Priority'(), + value=any:create(orber_tc:short(), + 'CosNotification':'DefaultPriority'())}]). +-define(defaultQoS2, + [#'CosNotification_Property'{name='CosNotification':'MaximumBatchSize'(), + value=any:create(orber_tc:long(), 1)}, + #'CosNotification_Property'{name='CosNotification':'PacingInterval'(), + value=any:create(orber_tc:unsigned_long_long(), + 0)}, + #'CosNotification_Property'{name='CosNotification':'OrderPolicy'(), + value=any:create(orber_tc:short(), + 'CosNotification':'AnyOrder'())}, + #'CosNotification_Property'{name='CosNotification':'EventReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'BestEffort'())}, + #'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'BestEffort'())}, + #'CosNotification_Property'{name='CosNotification':'DiscardPolicy'(), + value=any:create(orber_tc:short(), + 'CosNotification':'AnyOrder'())}, + #'CosNotification_Property'{name='CosNotification':'StartTimeSupported'(), + value=any:create(orber_tc:boolean(), false)}, + #'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(), + value=any:create(orber_tc:boolean(), false)}, + #'CosNotification_Property'{name='CosNotification':'Priority'(), + value=any:create(orber_tc:short(), + 'CosNotification':'DefaultPriority'())}]). +-define(defaultAdm, + [#'CosNotification_Property'{name='CosNotification':'MaxQueueLength'(), + value=any:create(orber_tc:long(), 100)}, + #'CosNotification_Property'{name='CosNotification':'MaxConsumers'(), + value=any:create(orber_tc:long(), 100)}, + #'CosNotification_Property'{name='CosNotification':'MaxSuppliers'(), + value=any:create(orber_tc:long(), 100)}]). + +-define(FAC_OPT, []). + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, qos_api/1, adm_api/1, + cosevent_api/1, filter_adm_api/1, events_api/1, events2_api/1, + event_qos_api/1, filter_api/1, mapping_filter_api/1, subscription_api/1, + init_per_testcase/2, fin_per_testcase/2, persistent_max_events_api/1, + persistent_timeout_events_api/1, persistent_recover_events_api/1, + app_test/1]). + +-export([terminated/1]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for the cosNotification interfaces", ""]; +all(suite) -> {req, + [mnesia, orber], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [persistent_max_events_api, persistent_timeout_events_api, + persistent_recover_events_api, mapping_filter_api, filter_api, filter_adm_api, + event_qos_api, qos_api, adm_api, cosevent_api, subscription_api, + events_api, events2_api, app_test]. + + + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ok = corba:orb_init([{flags, 16#02}, {orber_debug_level, 10}]), + orber:jump_start(), + cosNotificationApp:install_event(), + cosNotificationApp:install(), + 'oe_notify_test_server':'oe_register'(), + cosNotificationApp:start(), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + cosNotificationApp:stop(), + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + 'oe_notify_test_server':'oe_unregister'(), + cosNotificationApp:uninstall(), + cosNotificationApp:uninstall_event(), + orber:jump_stop(), + Config. + + +%%----------------------------------------------------------------- +%% Tests app file +%%----------------------------------------------------------------- +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ok=test_server:app_test(cosNotification), + ok. + + +%%----------------------------------------------------------------- +%% Persistent events max limit +%%----------------------------------------------------------------- +persistent_max_events_api(doc) -> ["CosNotification QoS EventReliability Persistent", + ""]; +persistent_max_events_api(suite) -> []; +persistent_max_events_api(_Config) -> + QoSPersistent = + [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'Persistent'())}], + QoSEventPersistent = + [#'CosNotification_Property'{name='CosNotification':'EventReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'Persistent'())}], + application:set_env(cosNotification, notify, ?MODULE), + application:set_env(cosNotification, max_events, 2), + application:set_env(cosNotification, timeout_events, 300000), + application:set_env(cosNotification, interval_events, 10000), + %% Initialize the application. + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS2, ?defaultAdm)), + ?match({_,key,_,_,_,_}, Ch), + + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventPersistent)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)), + + %% Create the Admin objects + {AdminSupplier, _ASID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'AND_OP')), + {AdminConsumer, _ACID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'AND_OP')), + + %% Create Proxies and clients + {SequenceProxyPushSupplier,_ID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'SEQUENCE_EVENT')), + PushSeqC=?match({_,key,_,_,_,_}, 'notify_test_SeqPushC':oe_create(['PUSH_SEQUENCE',SequenceProxyPushSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':connect_sequence_push_consumer(SequenceProxyPushSupplier, PushSeqC)), + + {SequenceProxyPushConsumer,_ID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'SEQUENCE_EVENT')), + PushSeqS=?match({_,key,_,_,_,_}, 'notify_test_SeqPushS':oe_create(['PUSH_SEQUENCE',SequenceProxyPushConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':connect_sequence_push_supplier(SequenceProxyPushConsumer, PushSeqS)), + + %% Create a couple of Events to test with. + Event = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + + ?match(ok, 'notify_test_SeqPushC':doAction(PushSeqC, {action, action})), + + %% Push and check the state. + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])), + ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + ?match(false, corba_object:non_existent(SequenceProxyPushSupplier)), + + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])), + ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + ?match(false, corba_object:non_existent(SequenceProxyPushSupplier)), + %% Now we've reached the limit. This call will terminate the proxy. + %% We cannot check for data at this point since the broken connection + %% will result in that the client terminates. + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])), + timer:sleep(5000), + ?match(true, corba_object:non_existent(SequenceProxyPushSupplier)), + ?match(true, corba_object:non_existent(PushSeqC)), + + + catch corba:dispose(SequenceProxyPushConsumer), + catch corba:dispose(SequenceProxyPushSupplier), + catch corba:dispose(AdminConsumer), + catch corba:dispose(AdminSupplier), + catch corba:dispose(Ch), + catch cosNotificationApp:stop_factory(Fac), + catch corba:dispose(PushSeqS), + catch corba:dispose(PushSeqC), + application:set_env(cosNotification, notify, undefined), + application:set_env(cosNotification, max_events, undefined), + application:set_env(cosNotification, timeout_events, undefined), + application:set_env(cosNotification, interval_events, undefined), + ok. + +terminated(Items) -> + io:format("Proxy terminated due to: ~p~n", [Items]). + +%%----------------------------------------------------------------- +%% Persistent events timeout +%%----------------------------------------------------------------- +persistent_timeout_events_api(doc) -> + ["CosNotification QoS EventReliability Persistent", + ""]; +persistent_timeout_events_api(suite) -> []; +persistent_timeout_events_api(_Config) -> + QoSPersistent = + [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'Persistent'())}], + QoSEventPersistent = + [#'CosNotification_Property'{name='CosNotification':'EventReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'Persistent'())}], + application:set_env(cosNotification, notify, ?MODULE), + application:set_env(cosNotification, max_events, 1000), + application:set_env(cosNotification, timeout_events, 4000), + application:set_env(cosNotification, interval_events, 1000), + %% Initialize the application. + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS2, ?defaultAdm)), + ?match({_,key,_,_,_,_}, Ch), + + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventPersistent)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)), + + %% Create the Admin objects + {AdminSupplier, _ASID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'AND_OP')), + {AdminConsumer, _ACID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'AND_OP')), + + %% Create Proxies and clients + {SequenceProxyPushSupplier,_ID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'SEQUENCE_EVENT')), + PushSeqC=?match({_,key,_,_,_,_}, 'notify_test_SeqPushC':oe_create(['PUSH_SEQUENCE',SequenceProxyPushSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':connect_sequence_push_consumer(SequenceProxyPushSupplier, PushSeqC)), + + {SequenceProxyPushConsumer,_ID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'SEQUENCE_EVENT')), + PushSeqS=?match({_,key,_,_,_,_}, 'notify_test_SeqPushS':oe_create(['PUSH_SEQUENCE',SequenceProxyPushConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':connect_sequence_push_supplier(SequenceProxyPushConsumer, PushSeqS)), + + %% Create a couple of Events to test with. + Event = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + + ?match(ok, 'notify_test_SeqPushC':doAction(PushSeqC, {action, action})), + + %% Push and check the state. + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])), + ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + ?match(false, corba_object:non_existent(SequenceProxyPushSupplier)), + + %% Now we've reached the limit. This call will terminate the proxy. + %% We cannot check for data at this point since the broken connection + %% will result in that the client terminates. + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])), + timer:sleep(10000), + ?match(true, corba_object:non_existent(SequenceProxyPushSupplier)), + ?match(true, corba_object:non_existent(PushSeqC)), + + + catch corba:dispose(SequenceProxyPushConsumer), + catch corba:dispose(SequenceProxyPushSupplier), + catch corba:dispose(AdminConsumer), + catch corba:dispose(AdminSupplier), + catch corba:dispose(Ch), + catch cosNotificationApp:stop_factory(Fac), + catch corba:dispose(PushSeqS), + catch corba:dispose(PushSeqC), + application:set_env(cosNotification, notify, undefined), + application:set_env(cosNotification, max_events, undefined), + application:set_env(cosNotification, timeout_events, undefined), + application:set_env(cosNotification, interval_events, undefined), + ok. + +%%----------------------------------------------------------------- +%% Persistent events max limit +%%----------------------------------------------------------------- +persistent_recover_events_api(doc) -> + ["CosNotification QoS EventReliability Persistent", + ""]; +persistent_recover_events_api(suite) -> []; +persistent_recover_events_api(_Config) -> + QoSPersistent = + [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'Persistent'())}], + QoSEventPersistent = + [#'CosNotification_Property'{name='CosNotification':'EventReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'Persistent'())}], + application:set_env(cosNotification, notify, ?MODULE), + application:set_env(cosNotification, max_events, 1000), + application:set_env(cosNotification, timeout_events, 100000), + application:set_env(cosNotification, interval_events, 1000), + %% Initialize the application. + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS2, ?defaultAdm)), + ?match({_,key,_,_,_,_}, Ch), + + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventPersistent)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)), + + %% Create the Admin objects + {AdminSupplier, _ASID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'AND_OP')), + {AdminConsumer, _ACID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'AND_OP')), + + %% Create Proxies and clients + {SequenceProxyPushSupplier,_ID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'SEQUENCE_EVENT')), + PushSeqC=?match({_,key,_,_,_,_}, 'notify_test_SeqPushC':oe_create(['PUSH_SEQUENCE',SequenceProxyPushSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':connect_sequence_push_consumer(SequenceProxyPushSupplier, PushSeqC)), + + {SequenceProxyPushConsumer,_ID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'SEQUENCE_EVENT')), + PushSeqS=?match({_,key,_,_,_,_}, 'notify_test_SeqPushS':oe_create(['PUSH_SEQUENCE',SequenceProxyPushConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':connect_sequence_push_supplier(SequenceProxyPushConsumer, PushSeqS)), + + %% Create a couple of Events to test with. + Event = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + + ?match(ok, 'notify_test_SeqPushC':doAction(PushSeqC, {action, action})), + + %% Push and check the state. + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])), + ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + ?match(false, corba_object:non_existent(SequenceProxyPushSupplier)), + %% Allow the proxy to try a few times and then change the client behavior + timer:sleep(4000), + ?match(ok, 'notify_test_SeqPushC':doAction(PushSeqC, {action, undefined})), + %% Wait some time so that the proxy timeout has kicked in. + timer:sleep(4000), + + %% Now the communication should work again. + ?match([Event], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + ?match(false, corba_object:non_existent(SequenceProxyPushSupplier)), + + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, [Event])), + timer:sleep(4000), + ?match([Event], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + catch corba:dispose(SequenceProxyPushConsumer), + catch corba:dispose(SequenceProxyPushSupplier), + catch corba:dispose(AdminConsumer), + catch corba:dispose(AdminSupplier), + catch corba:dispose(Ch), + catch cosNotificationApp:stop_factory(Fac), + catch corba:dispose(PushSeqS), + catch corba:dispose(PushSeqC), + application:set_env(cosNotification, notify, undefined), + application:set_env(cosNotification, max_events, undefined), + application:set_env(cosNotification, timeout_events, undefined), + application:set_env(cosNotification, interval_events, undefined), + ok. + + +%%----------------------------------------------------------------- +%% CosNotifyFilter::Filter API tests +%%----------------------------------------------------------------- +mapping_filter_api(doc) -> ["CosNotifyFilter::MappingFilter API tests.", ""]; +mapping_filter_api(suite) -> []; +mapping_filter_api(_Config) -> + FiFac = 'CosNotifyFilter_FilterFactory':oe_create(), + ?match({_,key,_,_,_,_}, FiFac), + + Filter = 'CosNotifyFilter_FilterFactory':create_mapping_filter(FiFac, + "EXTENDED_TCL", + any:create(orber_tc:short(), 10)), + ?match({_,key,_,_,_,_}, Filter), + + ?match("EXTENDED_TCL", 'CosNotifyFilter_MappingFilter':'_get_constraint_grammar'(Filter)), + + %% Test before we add any constarints. + ?match([], 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)), + ?match({'EXCEPTION', {'CosNotifyFilter_ConstraintNotFound', _, 1}}, + 'CosNotifyFilter_MappingFilter':get_mapping_constraints(Filter, [1])), + ?match(ok, 'CosNotifyFilter_MappingFilter':remove_all_mapping_constraints(Filter)), + + %% Try adding an incorrect constraint_expr + ?match({'EXCEPTION',{'CosNotifyFilter_InvalidConstraint',_,_}}, + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "name", + type_name = "type"}], + constraint_expr = "2==2 and 3<"}, + result_to_set = any:create(orber_tc:short(), 10)}])), + %% Try adding two correct constraint_expr + ?line[{_,_,CID1,_},{_,_,CID2,_}]= + ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}, {'CosNotifyFilter_MappingConstraintInfo',_,_,_}], + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "name", + type_name = "type"}], + constraint_expr = "2==2 and 3<4"}, + result_to_set = any:create(orber_tc:short(), 10)}, + #'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "name2", + type_name = "type2"}], + constraint_expr = "$.test._length == 3 and ($.test[0].score + $.test[1].score + $.test[2].score)/3 >=80"}, + result_to_set = any:create(orber_tc:short(), 10)}])), + + ?match([{'CosNotifyFilter_MappingConstraintInfo',_,CID2,_}, {'CosNotifyFilter_MappingConstraintInfo',_,CID1,_}], + 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)), + ?match([{'CosNotifyFilter_MappingConstraintInfo',_,CID1,_}], + 'CosNotifyFilter_MappingFilter':get_mapping_constraints(Filter, [CID1])), + ?match(ok, 'CosNotifyFilter_MappingFilter':remove_all_mapping_constraints(Filter)), + ?match([], 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)), + + %% Try adding a constraint_expr with using invalid value, i.e., not short. + ?match({'EXCEPTION',{'CosNotifyFilter_InvalidValue',_,_,_}}, + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "name", + type_name = "type"}], + constraint_expr = "2==2 and 3<8"}, + result_to_set = any:create(orber_tc:long(), 10)}])), + + %% Try adding one correct and one incorrect constraint_expr + ?match({'EXCEPTION',{'CosNotifyFilter_InvalidConstraint',_,_}}, + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "name", + type_name = "type"}], + constraint_expr = "2==2 and 3<"}, + result_to_set = any:create(orber_tc:short(), 10)}, + #'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "name2", + type_name = "type2"}], + constraint_expr = "$.test._length == 3 and ($.test[0].score + $.test[1].score + $.test[2].score)/3 >=80"}, + result_to_set = any:create(orber_tc:short(), 10)}])), + + %% Following testcases test different domain_name and type_name, e.g., + %% wildcards etc. + [{_,ConInfoData,CID3,_}] = + ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}], + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "domain", + type_name = ""}, + #'CosNotification_EventType' + {domain_name = "*", + type_name = "type"}], + constraint_expr = "2==2 and 3<4"}, + result_to_set = any:create(orber_tc:short(), 10)}])), + + %% Try removing a constraint + ?match(ok, 'CosNotifyFilter_MappingFilter':modify_mapping_constraints(Filter,[CID3],[])), + ?match([], 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)), + + %% Add e new constraint + [{_,_,CID4,_}] = + ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}], + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "domain1", + type_name = ""}, + #'CosNotification_EventType' + {domain_name = "domain2", + type_name = "*"}], + constraint_expr = "2==2 and 3<4"}, + result_to_set = any:create(orber_tc:short(), 10)}])), + + %% Try to update the constraint associated with CID4 to equal CID3. + ?match(ok, 'CosNotifyFilter_MappingFilter':modify_mapping_constraints(Filter,[], + [#'CosNotifyFilter_MappingConstraintInfo' + {constraint_expression= + #'CosNotifyFilter_ConstraintExp' + {event_types =[#'CosNotification_EventType' + {domain_name = "domain", + type_name = ""}, + #'CosNotification_EventType' + {domain_name = "*", + type_name = "type"}], + constraint_expr = "2==2 and 3<4"}, + constraint_id=CID4, + value = any:create(orber_tc:short(), 10)}])), + + ?match([{_,ConInfoData,CID4,_}], 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)), + + ?match({'EXCEPTION', {'CosNotifyFilter_ConstraintNotFound', _, CID3}}, + 'CosNotifyFilter_MappingFilter':get_mapping_constraints(Filter, [CID3])), + ?match(ok, 'CosNotifyFilter_MappingFilter':remove_all_mapping_constraints(Filter)), + ?match([], 'CosNotifyFilter_MappingFilter':get_all_mapping_constraints(Filter)), + + ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}], + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "", + type_name = "type1"}, + #'CosNotification_EventType' + {domain_name = "*", + type_name = "type2"}], + constraint_expr = "2==2 and 3<4"}, + result_to_set = any:create(orber_tc:short(), 10)}])), + + ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}], + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "domain1", + type_name = "type1"}, + #'CosNotification_EventType' + {domain_name = "domain2", + type_name = "type2"}], + constraint_expr = "2==2 and 3<4"}, + result_to_set = any:create(orber_tc:short(), 10)}])), + + ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}], + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "dom*", + type_name = "type1"}, + #'CosNotification_EventType' + {domain_name = "domain2", + type_name = "typ*"}], + constraint_expr = "2==2 and 3<4"}, + result_to_set = any:create(orber_tc:short(), 10)}])), + + ?match([{'CosNotifyFilter_MappingConstraintInfo',_,_,_}], + 'CosNotifyFilter_MappingFilter':add_mapping_constraints(Filter, + [#'CosNotifyFilter_MappingConstraintPair' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = [#'CosNotification_EventType' + {domain_name = "dom*1", + type_name = "type1"}, + #'CosNotification_EventType' + {domain_name = "domain2", + type_name = "typ*2"}], + constraint_expr = "2==2 and 3<4"}, + result_to_set = any:create(orber_tc:short(), 10)}])), + + catch corba:dispose(FiFac), + catch corba:dispose(Filter), + ok. + + +%%----------------------------------------------------------------- +%% CosNotifyFilter::Filter API tests +%%----------------------------------------------------------------- +filter_api(doc) -> ["CosNotifyFilter::Filter API tests.", ""]; +filter_api(suite) -> []; +filter_api(_Config) -> + Fac = cosNotificationApp:start_global_factory(?FAC_OPT), + ?match({_,key,_,_,_,_}, Fac), + {Ch, _Id1} = 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm), + AC= 'CosNotifyChannelAdmin_EventChannel':for_consumers(Ch), + + FiFac = 'CosNotifyFilter_FilterFactory':oe_create(), + ?match({_,key,_,_,_,_}, FiFac), + + Filter = 'CosNotifyFilter_FilterFactory':create_filter(FiFac,"EXTENDED_TCL"), + ?match({_,key,_,_,_,_}, Filter), + + ?match("EXTENDED_TCL", 'CosNotifyFilter_Filter':'_get_constraint_grammar'(Filter)), + + %% Test Callback management. + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, + 'CosNotifyFilter_Filter':attach_callback(Filter, Ch)), + ?match([], 'CosNotifyFilter_Filter':get_callbacks(Filter)), + ?match({'EXCEPTION',{'CosNotifyFilter_CallbackNotFound',_}}, + 'CosNotifyFilter_Filter':detach_callback(Filter, 0)), + ID='CosNotifyFilter_Filter':attach_callback(Filter, AC), + ?match([ID], 'CosNotifyFilter_Filter':get_callbacks(Filter)), + ?match(ok, 'CosNotifyFilter_Filter':detach_callback(Filter, ID)), + ?match([], 'CosNotifyFilter_Filter':get_callbacks(Filter)), + + %% This callback is just attached so we can test that we can call notify_subscribe. + _ID2='CosNotifyFilter_Filter':attach_callback(Filter, AC), + + %% Test before we add any constarints. + ?match([], 'CosNotifyFilter_Filter':get_all_constraints(Filter)), + ?match({'EXCEPTION', {'CosNotifyFilter_ConstraintNotFound', _, 1}}, + 'CosNotifyFilter_Filter':get_constraints(Filter, [1])), + ?match(ok, 'CosNotifyFilter_Filter':remove_all_constraints(Filter)), + + %% Try adding an incorrect constraint_expr + ?match({'EXCEPTION',{'CosNotifyFilter_InvalidConstraint',_,_}}, + 'CosNotifyFilter_Filter':add_constraints(Filter, + [#'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "name", + type_name = "type"}], + constraint_expr = "2==2 and 3<"}])), + %% Try adding two correct constraint_expr + ?line[{_,_,CID1},{_,_,CID2}]= + ?match([{'CosNotifyFilter_ConstraintInfo',_,_}, {'CosNotifyFilter_ConstraintInfo',_,_}], + 'CosNotifyFilter_Filter':add_constraints(Filter, + [#'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "name", + type_name = "type"}], + constraint_expr = "2==2 and 3<4"}, + #'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "name2", + type_name = "type2"}], + constraint_expr = "$.test._length == 3 and ($.test[0].score + $.test[1].score + $.test[2].score)/3 >=80"}])), + + ?match([{'CosNotifyFilter_ConstraintInfo',_,CID2}, {'CosNotifyFilter_ConstraintInfo',_,CID1}], + 'CosNotifyFilter_Filter':get_all_constraints(Filter)), + ?match([{'CosNotifyFilter_ConstraintInfo',_,CID1}], + 'CosNotifyFilter_Filter':get_constraints(Filter, [CID1])), + ?match(ok, 'CosNotifyFilter_Filter':remove_all_constraints(Filter)), + ?match([], 'CosNotifyFilter_Filter':get_all_constraints(Filter)), + + %% Try adding one correct and one incorrect constraint_expr + ?match({'EXCEPTION',{'CosNotifyFilter_InvalidConstraint',_,_}}, + 'CosNotifyFilter_Filter':add_constraints(Filter, + [#'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "name", + type_name = "type"}], + constraint_expr = "2==2 and 3<"}, + #'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "name2", + type_name = "type2"}], + constraint_expr = "$.test._length == 3 and ($.test[0].score + $.test[1].score + $.test[2].score)/3 >=80"}])), + + %% Following testcases test different domain_name and type_name, e.g., + %% wildcards etc. + [{_,ConInfoData,CID3}] = + ?match([{'CosNotifyFilter_ConstraintInfo',_,_}], + 'CosNotifyFilter_Filter':add_constraints(Filter, + [#'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "domain", + type_name = ""}, + #'CosNotification_EventType'{ + domain_name = "*", + type_name = "type"}], + constraint_expr = "2==2 and 3<4"}])), + + %% Try removing a constraint + ?match(ok, 'CosNotifyFilter_Filter':modify_constraints(Filter,[CID3],[])), + ?match([], 'CosNotifyFilter_Filter':get_all_constraints(Filter)), + + %% Add e new constraint + [{_,_,CID4}] = + ?match([{'CosNotifyFilter_ConstraintInfo',_,_}], + 'CosNotifyFilter_Filter':add_constraints(Filter, + [#'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "domain1", + type_name = ""}, + #'CosNotification_EventType'{ + domain_name = "domain2", + type_name = "*"}], + constraint_expr = "2==2 and 3<4"}])), + + %% Try to update the constraint associated with CID4 to equal CID3. + ?match(ok, 'CosNotifyFilter_Filter':modify_constraints(Filter,[], + [#'CosNotifyFilter_ConstraintInfo'{constraint_expression= + #'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "domain", + type_name = ""}, + #'CosNotification_EventType'{ + domain_name = "*", + type_name = "type"}], + constraint_expr = "2==2 and 3<4"}, + constraint_id=CID4}])), + + ?match([{_,ConInfoData,CID4}], 'CosNotifyFilter_Filter':get_all_constraints(Filter)), + + ?match({'EXCEPTION', {'CosNotifyFilter_ConstraintNotFound', _, CID3}}, + 'CosNotifyFilter_Filter':get_constraints(Filter, [CID3])), + ?match(ok, 'CosNotifyFilter_Filter':remove_all_constraints(Filter)), + ?match([], 'CosNotifyFilter_Filter':get_all_constraints(Filter)), + + ?match([{'CosNotifyFilter_ConstraintInfo',_,_}], + 'CosNotifyFilter_Filter':add_constraints(Filter, + [#'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "", + type_name = "type1"}, + #'CosNotification_EventType'{ + domain_name = "*", + type_name = "type2"}], + constraint_expr = "2==2 and 3<4"}])), + + ?match([{'CosNotifyFilter_ConstraintInfo',_,_}], + 'CosNotifyFilter_Filter':add_constraints(Filter, + [#'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "domain1", + type_name = "type1"}, + #'CosNotification_EventType'{ + domain_name = "domain2", + type_name = "type2"}], + constraint_expr = "2==2 and 3<4"}])), + + ?match([{'CosNotifyFilter_ConstraintInfo',_,_}], + 'CosNotifyFilter_Filter':add_constraints(Filter, + [#'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "dom*", + type_name = "type1"}, + #'CosNotification_EventType'{ + domain_name = "domain2", + type_name = "typ*"}], + constraint_expr = "2==2 and 3<4"}])), + + ?match([{'CosNotifyFilter_ConstraintInfo',_,_}], + 'CosNotifyFilter_Filter':add_constraints(Filter, + [#'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "dom*1", + type_name = "type1"}, + #'CosNotification_EventType'{ + domain_name = "domain2", + type_name = "typ*2"}], + constraint_expr = "2==2 and 3<4"}])), + + catch corba:dispose(FiFac), + catch corba:dispose(Filter), + catch corba:dispose(AC), + catch corba:dispose(Ch), + catch corba:dispose(Fac), + ok. + +%%----------------------------------------------------------------- +%% Subscription handling API tests +%%----------------------------------------------------------------- +subscription_api(doc) -> ["CosNotification subscription handling", ""]; +subscription_api(suite) -> []; +subscription_api(_Config) -> + %% Initialize the application. + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)), + ?match({_,key,_,_,_,_}, Ch), + + %% Create the Admin objects + {AdminSupplier, _ASID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'OR_OP')), + {AdminConsumer, _ACID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'OR_OP')), + + %% Create Suppliers Proxies + {StructuredProxyPullSupplier,_}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'STRUCTURED_EVENT')), + {StructuredProxyPushSupplier,_}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'STRUCTURED_EVENT')), + + %% Now we must create a Client for each proxy and connect them. + PushStrC=?match({_,key,_,_,_,_}, 'notify_test_StrPushC':oe_create(['PUSH_STRUCTURED',StructuredProxyPushSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':connect_structured_push_consumer(StructuredProxyPushSupplier, PushStrC)), + PullStrC=?match({_,key,_,_,_,_}, 'notify_test_StrPullC':oe_create(['PULL_STRUCTURED',StructuredProxyPullSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':connect_structured_pull_consumer(StructuredProxyPullSupplier, PullStrC)), + + %% Create Consumers Proxies + {StructuredProxyPullConsumer,_}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_pull_consumer(AdminSupplier, 'STRUCTURED_EVENT')), + {StructuredProxyPushConsumer,_}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'STRUCTURED_EVENT')), + + %% Now we must create a Client for each proxy and connect them. + PushStrS=?match({_,key,_,_,_,_}, 'notify_test_StrPushS':oe_create(['PUSH_STRUCTURED',StructuredProxyPushConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':connect_structured_push_supplier(StructuredProxyPushConsumer, PushStrS)), + + PullStrS=?match({_,key,_,_,_,_}, 'notify_test_StrPullS':oe_create(['PULL_STRUCTURED',StructuredProxyPullConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':connect_structured_pull_supplier(StructuredProxyPullConsumer, PullStrS)), + + ES1=[#'CosNotification_EventType'{domain_name = "name1", type_name = "type1"}, + #'CosNotification_EventType'{domain_name = "name2", type_name = "type2"}], + ES2=[#'CosNotification_EventType'{domain_name = "name3", type_name = "type3"}, + #'CosNotification_EventType'{domain_name = "name4", type_name = "type4"}], + + %% Initially it should have no associated types. Test that and set that + %% all updates should be forwarded to client. + ?match([], 'CosNotifyChannelAdmin_StructuredProxyPushConsumer': + obtain_subscription_types(StructuredProxyPushConsumer, + 'ALL_NOW_UPDATES_ON')), + ?match([], 'CosNotifyChannelAdmin_StructuredProxyPullConsumer': + obtain_subscription_types(StructuredProxyPullConsumer, + 'ALL_NOW_UPDATES_ON')), + + %% Update the offered types. + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer': + offer_change(StructuredProxyPushConsumer, ES1, [])), + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer': + offer_change(StructuredProxyPullConsumer, ES1, [])), + + %% To be sure, wait a couple of seconds. + timer:sleep(5000), + ?match([{'CosNotification_EventType',_,_}, + {'CosNotification_EventType',_,_}], + 'notify_test_StrPushC':doAction(PushStrS, return_data)), + ?match([{'CosNotification_EventType',_,_}, + {'CosNotification_EventType',_,_}], + 'notify_test_StrPullC':doAction(PullStrS, return_data)), + + %% Update the offered types. Remove ES1 and add ES2. + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer': + offer_change(StructuredProxyPushConsumer, ES2, ES1)), + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer': + offer_change(StructuredProxyPullConsumer, ES2, ES1)), + + %% To be sure, wait a couple of seconds. + timer:sleep(5000), + ?match([{'CosNotification_EventType',_,_}, + {'CosNotification_EventType',_,_}], + 'notify_test_StrPushC':doAction(PushStrS, return_data)), + ?match([{'CosNotification_EventType',_,_}, + {'CosNotification_EventType',_,_}], + 'notify_test_StrPullC':doAction(PullStrS, return_data)), + + %% Now, the objects should only contain 'ES2'. Test it. + ?match([{'CosNotification_EventType',_,_}, + {'CosNotification_EventType',_,_}], + 'CosNotifyChannelAdmin_StructuredProxyPushConsumer': + obtain_subscription_types(StructuredProxyPushConsumer, + 'ALL_NOW_UPDATES_ON')), + ?match([{'CosNotification_EventType',_,_}, + {'CosNotification_EventType',_,_}], + 'CosNotifyChannelAdmin_StructuredProxyPullConsumer': + obtain_subscription_types(StructuredProxyPullConsumer, + 'ALL_NOW_UPDATES_ON')), + + %% Now we will use wildcards, empty strings and test if they really + %% are ignored if so requested. + ES3=[#'CosNotification_EventType'{domain_name = "name1", type_name = "*"}, + #'CosNotification_EventType'{domain_name = "*", type_name = "type2"}], + ES4=[#'CosNotification_EventType'{domain_name = "name1", type_name = "*"}, + #'CosNotification_EventType'{domain_name = "name2", type_name = ""}], + ES5=[#'CosNotification_EventType'{domain_name = "na*", type_name = "type1"}], + ES6=[#'CosNotification_EventType'{domain_name = "n*1", type_name = "type1"}], + ES7=[#'CosNotification_EventType'{domain_name = "*1", type_name = "type1"}], + ES8=[#'CosNotification_EventType'{domain_name = "n*m*1", type_name = "type1"}], + ES9=[#'CosNotification_EventType'{domain_name = "n**1", type_name = "type1"}], + ES10=[#'CosNotification_EventType'{domain_name = "nam*1", type_name = "type1"}], + + Event1 = ?not_CreateSE("name1","type1", + "event_name", + [#'CosNotification_Property'{name="property_name", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + Event2 = ?not_CreateSE("name2","type1", + "event_name", + [#'CosNotification_Property'{name="property_name", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + Event3 = ?not_CreateSE("mame1","type1", + "event_name", + [#'CosNotification_Property'{name="property_name", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + Event4 = ?not_CreateSE("naame1","type1", + "event_name", + [#'CosNotification_Property'{name="property_name", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + Event5 = ?not_CreateSE("nname1","type1", + "event_name", + [#'CosNotification_Property'{name="property_name", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + Event6 = ?not_CreateSE("name12","type1", + "event_name", + [#'CosNotification_Property'{name="property_name", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier': + subscription_change(StructuredProxyPullSupplier, ES3, [])), + + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)), + + ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier': + subscription_change(StructuredProxyPullSupplier, ES4, ES3)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)), + ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier': + subscription_change(StructuredProxyPullSupplier, ES5, ES4)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)), + ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier': + subscription_change(StructuredProxyPullSupplier, ES6, ES5)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)), + ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier': + subscription_change(StructuredProxyPullSupplier, ES7, ES6)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)), + ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier': + subscription_change(StructuredProxyPullSupplier, ES8, ES7)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)), + ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier': + subscription_change(StructuredProxyPullSupplier, ES9, ES8)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)), + ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event2)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event3)), + + timer:sleep(5000), + ?match({_NilStrEvent,false}, 'notify_test_StrPullC':doAction(PullStrC, try_pull_str)), + + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier': + subscription_change(StructuredProxyPullSupplier, ES10, ES9)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event1)), + ?match(Event1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event4)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event5)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event6)), + + timer:sleep(5000), + ?match({_NilStrEvent,false}, 'notify_test_StrPullC':doAction(PullStrC, try_pull_str)), + + + catch corba:dispose(StructuredProxyPushConsumer), + catch corba:dispose(StructuredProxyPullConsumer), + catch corba:dispose(StructuredProxyPushSupplier), + catch corba:dispose(StructuredProxyPullSupplier), + catch corba:dispose(AdminConsumer), + catch corba:dispose(AdminSupplier), + catch corba:dispose(Ch), + catch cosNotificationApp:stop_factory(Fac), + + timer:sleep(5000), + ?match(true, corba_object:non_existent(PullStrS)), + ?match(true, corba_object:non_existent(PushStrS)), + ?match(true, corba_object:non_existent(PullStrC)), + ?match(true, corba_object:non_existent(PushStrC)), + + ok. + +%%----------------------------------------------------------------- +%% Filter admin API tests +%%----------------------------------------------------------------- +filter_adm_api(doc) -> ["CosNotification filter admin tests", ""]; +filter_adm_api(suite) -> []; +filter_adm_api(_Config) -> + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)), + ?match({_,key,_,_,_,_}, Ch), + + FiFac = 'CosNotifyFilter_FilterFactory':oe_create(), + ?match({_,key,_,_,_,_}, FiFac), + + Filter = 'CosNotifyFilter_FilterFactory':create_filter(FiFac,"EXTENDED_TCL"), + ?match({_,key,_,_,_,_}, Filter), + + AC=?match({_,key,_,_,_,_}, + 'CosNotifyChannelAdmin_EventChannel':for_consumers(Ch)), + filter_tests('CosNotifyChannelAdmin_ConsumerAdmin', AC, Filter, Ch), + + AS=?match({_,key,_,_,_,_}, + 'CosNotifyChannelAdmin_EventChannel':for_suppliers(Ch)), + filter_tests('CosNotifyChannelAdmin_SupplierAdmin', AS, Filter, Ch), + + PushS=?match({_,key,_,_,_,_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_push_supplier(AC)), + filter_tests('CosNotifyChannelAdmin_ProxyPushSupplier', PushS, Filter, Ch), + + PullS=?match({_,key,_,_,_,_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_pull_supplier(AC)), + filter_tests('CosNotifyChannelAdmin_ProxyPullSupplier', PullS, Filter, Ch), + + PushC=?match({_,key,_,_,_,_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_push_consumer(AS)), + filter_tests('CosNotifyChannelAdmin_ProxyPushConsumer', PushC, Filter, Ch), + + PullC=?match({_,key,_,_,_,_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_pull_consumer(AS)), + filter_tests('CosNotifyChannelAdmin_ProxyPullConsumer', PullC, Filter, Ch), + + catch corba:dispose(FiFac), + catch corba:dispose(Filter), + catch corba:dispose(PushS), + catch corba:dispose(PullS), + catch corba:dispose(PushC), + catch corba:dispose(PullC), + catch corba:dispose(AC), + catch corba:dispose(AS), + catch corba:dispose(Ch), + catch cosNotificationApp:stop_factory(Fac), + ok. + +filter_tests(Mod, Obj, Filter, Ch) -> + io:format("############ TESTING MODULE ~p FILTER ############~n", [Mod]), + %% No filter added. + ?match([], Mod:get_all_filters(Obj)), + ?match(ok, Mod:remove_all_filters(Obj)), + ?match({'EXCEPTION',{'CosNotifyFilter_FilterNotFound',_}}, + Mod:get_filter(Obj, 0)), + %% Try add a Filter which is not a filter. + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, Mod:add_filter(Obj, Ch)), + %% Try to remove a single filter. + ?match({'EXCEPTION',{'CosNotifyFilter_FilterNotFound',_}}, + Mod:remove_filter(Obj, 0)), + ID = Mod:add_filter(Obj, Filter), + ?match([ID], Mod:get_all_filters(Obj)), + ?match(Filter, Mod:get_filter(Obj, ID)), + ?match(ok, Mod:remove_filter(Obj, ID)), + ?match([], Mod:get_all_filters(Obj)), + ID2 = Mod:add_filter(Obj, Filter), + ?match([ID2], Mod:get_all_filters(Obj)), + ?match(ok, Mod:remove_all_filters(Obj)), + ?match([], Mod:get_all_filters(Obj)), + ok. + +%%----------------------------------------------------------------- +%% Creating different event pushing and pulling API tests +%%----------------------------------------------------------------- +events_api(doc) -> ["CosNotification event pushing and pulling tests", ""]; +events_api(suite) -> []; +events_api(_Config) -> + %% Initialize the application. + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + {Ch, Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)), + ?match({_,key,_,_,_,_}, Ch), + events_api_helper(Fac, Ch, Id1). + +events2_api(doc) -> ["CosNotification event pushing and pulling tests II", ""]; +events2_api(suite) -> []; +events2_api(_Config) -> + %% Initialize the application. + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + {Ch, Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS2, ?defaultAdm)), + ?match({_,key,_,_,_,_}, Ch), + events_api_helper(Fac, Ch, Id1). + +events_api_helper(Fac, Ch, _Id1) -> + %% Now we will set up a test environment, with the following structure: + %% + %% Channel + %% / \ + %% Supplier Adm Consumer Adm + %% / \ + %% 1 proxy of each possible type + %% To each proxy we will connect a test client + %% The events will flow in ===>> direction. + %% + %% For the supplier Admins this include: + %% - ProxyPushConsumer + %% - SequenceProxyPushConsumer + %% - StructuredProxyPushConsumer + %% - ProxyPullConsumer + %% - SequenceProxyPullConsumer + %% - StructuredProxyPullConsumer + %% + %% For the consumer Admins this include: + %% - ProxyPushSupplier + %% - SequenceProxyPushSupplier + %% - StructuredProxyPushSupplier + %% - ProxyPullSupplier + %% - SequenceProxyPullSupplier + %% - StructuredProxyPullSupplier + %% + %% + %% We will not use any Filters to begin with, just want to make sure we can + %% deliver events from all start- to end-points. + + %% Create the Admin objects + {AdminSupplier, _ASID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'AND_OP')), + {AdminConsumer, _ACID}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'AND_OP')), + + %% Create Suppliers Proxies + {ProxyPullSupplier,_ID1}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'ANY_EVENT')), + {StructuredProxyPullSupplier,_ID2}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'STRUCTURED_EVENT')), + {SequenceProxyPullSupplier,_ID3}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'SEQUENCE_EVENT')), + + {ProxyPushSupplier,_I4D}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'ANY_EVENT')), + {StructuredProxyPushSupplier,_ID5}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'STRUCTURED_EVENT')), + {SequenceProxyPushSupplier,_ID6}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(AdminConsumer, 'SEQUENCE_EVENT')), + + %% Now we must create a Client for each proxy and connect them. + PushAnyC=?match({_,key,_,_,_,_}, 'notify_test_AnyPushC':oe_create(['PUSH_ANY', ProxyPushSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_ProxyPushSupplier':connect_any_push_consumer(ProxyPushSupplier, PushAnyC)), + + PushStrC=?match({_,key,_,_,_,_}, 'notify_test_StrPushC':oe_create(['PUSH_STRUCTURED',StructuredProxyPushSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushSupplier':connect_structured_push_consumer(StructuredProxyPushSupplier, PushStrC)), + + PushSeqC=?match({_,key,_,_,_,_}, 'notify_test_SeqPushC':oe_create(['PUSH_SEQUENCE',SequenceProxyPushSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushSupplier':connect_sequence_push_consumer(SequenceProxyPushSupplier, PushSeqC)), + + PullAnyC=?match({_,key,_,_,_,_}, 'notify_test_AnyPullC':oe_create(['PULL_ANY', ProxyPullSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_ProxyPullSupplier':connect_any_pull_consumer(ProxyPullSupplier, PullAnyC)), + + PullStrC=?match({_,key,_,_,_,_}, 'notify_test_StrPullC':oe_create(['PULL_STRUCTURED',StructuredProxyPullSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullSupplier':connect_structured_pull_consumer(StructuredProxyPullSupplier, PullStrC)), + + PullSeqC=?match({_,key,_,_,_,_}, 'notify_test_SeqPullC':oe_create(['PULL_SEQUENCE',SequenceProxyPullSupplier], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPullSupplier':connect_sequence_pull_consumer(SequenceProxyPullSupplier, PullSeqC)), + + + %% Create Consumers Proxies + {ProxyPullConsumer,_ID7}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_pull_consumer(AdminSupplier, 'ANY_EVENT')), + {StructuredProxyPullConsumer,_ID8}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_pull_consumer(AdminSupplier, 'STRUCTURED_EVENT')), + {SequenceProxyPullConsumer,_ID9}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_pull_consumer(AdminSupplier, 'SEQUENCE_EVENT')), + + {ProxyPushConsumer,_ID10}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'ANY_EVENT')), + {StructuredProxyPushConsumer,_ID11}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'STRUCTURED_EVENT')), + {SequenceProxyPushConsumer,_ID12}=?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'SEQUENCE_EVENT')), + + %% Now we must create a Client for each proxy and connect them. + PushAnyS=?match({_,key,_,_,_,_}, 'notify_test_AnyPushS':oe_create(['PUSH_ANY', ProxyPushConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_ProxyPushConsumer':connect_any_push_supplier(ProxyPushConsumer, PushAnyS)), + + PushStrS=?match({_,key,_,_,_,_}, 'notify_test_StrPushS':oe_create(['PUSH_STRUCTURED',StructuredProxyPushConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':connect_structured_push_supplier(StructuredProxyPushConsumer, PushStrS)), + + PushSeqS=?match({_,key,_,_,_,_}, 'notify_test_SeqPushS':oe_create(['PUSH_SEQUENCE',SequenceProxyPushConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPushConsumer':connect_sequence_push_supplier(SequenceProxyPushConsumer, PushSeqS)), + + PullAnyS=?match({_,key,_,_,_,_}, 'notify_test_AnyPullS':oe_create(['PULL_ANY', ProxyPullConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_ProxyPullConsumer':connect_any_pull_supplier(ProxyPullConsumer, PullAnyS)), + + PullStrS=?match({_,key,_,_,_,_}, 'notify_test_StrPullS':oe_create(['PULL_STRUCTURED',StructuredProxyPullConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPullConsumer':connect_structured_pull_supplier(StructuredProxyPullConsumer, PullStrS)), + + PullSeqS=?match({_,key,_,_,_,_}, 'notify_test_SeqPullS':oe_create(['PULL_SEQUENCE',SequenceProxyPullConsumer], + [{local_typecheck, false}])), + ?match(ok, 'CosNotifyChannelAdmin_SequenceProxyPullConsumer':connect_sequence_pull_supplier(SequenceProxyPullConsumer, PullSeqS)), + + + %% Create a couple of Events to test with. + Event = ?not_CreateSE("DomainName","CommunicationsAlarm", + "lost_packet", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 1)}], + [], any:create(orber_tc:null(), null)), + + Event2 = ?not_CreateSE("DomainName","TemperatureAlarm", + "over_heated", + [#'CosNotification_Property'{name="priority", + value=any:create(orber_tc:short(), 10)}], + [], any:create(orber_tc:null(), null)), + + + AnyEvent = any:create(orber_tc:long(), 100), + + StrEvent = ?not_CreateSE("","%ANY","",[],[],AnyEvent), + NilAnyEvent = any:create(orber_tc:null(), null), + NilStrEvent = ?not_CreateSE("","","",[],[],NilAnyEvent), + + ConvertedStr = any:create('CosNotification_StructuredEvent':tc(), Event), + + io:format("###################### PUSH STRUCTURED ########################"), + + %% Test with pushing a structured event. + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, Event)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + + %% Check if the Clients have received and stored the events. + ?match([{any,_,Event}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([Event], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([Event], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + %% Instruct the Clients to pull the events and check if they match. + ?match({any,_,Event}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(Event, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([Event], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})), + + io:format("###################### PUSH SEQUENCE ########################"), + + %% Create an Event Sequence and push it. + EventSeq = [Event, Event2], + + %% Test with pushing a event sequence. + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, EventSeq)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + + %% Instruct the Clients to pull the events and check if they match. + ?match({any,_,Event}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(Event, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([Event,Event2], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,2})), + ?match({any,_,Event2}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(Event2, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + + %% Check if the Push Clients have received and stored the events. + ?match([{any,_,Event}, {any,_,Event2}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([Event, Event2], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([Event, Event2], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + io:format("###################### PUSH ANY ########################"), + + %% Test with pushing an any event. + ?match(ok,'CosEventChannelAdmin_ProxyPushConsumer':push(ProxyPushConsumer, AnyEvent)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + + %% Check if the Clients have received and stored the events. + ?match([AnyEvent], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([StrEvent], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([StrEvent], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + %% Instruct the Clients to pull the events and check if they match. + ?match(AnyEvent, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(StrEvent, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([StrEvent], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,10})), + + + + io:format("###################### PUSH CONVERTED ANY #############"), + + %% Test with pushing a structured event. + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, StrEvent)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + + %% Check if the Clients have received and stored the events. + ?match([AnyEvent], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([StrEvent], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([StrEvent], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + %% Instruct the Clients to pull the events and check if they match. + ?match(AnyEvent, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(StrEvent, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([StrEvent], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})), + + + io:format("###################### PUSH CONVERTED STRUCTURED ########"), + + %% Test with pushing an any event. + ?match(ok,'CosEventChannelAdmin_ProxyPushConsumer':push(ProxyPushConsumer, ConvertedStr)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + + %% Check if the Clients have received and stored the events. + ?match([ConvertedStr], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([Event], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([Event], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + %% Instruct the Clients to pull the events and check if they match. + ?match(ConvertedStr, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(Event, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([Event], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,10})), + + + io:format("###################### TRY PULL ########################"), + + %% Now we will push an any event after a delay. This means that try_pull-functions, + %% since it's not blocking, will return, [], NilAny or NilStructured events and + %% the Boolean false. + spawn(notify_test_impl, delay, [ProxyPushConsumer, AnyEvent, 20000, + 'CosEventChannelAdmin_ProxyPushConsumer',push]), + ?match([], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + %% Instruct the Clients to pull the events and check if they match. + ?match({NilAnyEvent,false}, 'notify_test_AnyPullC':doAction(PullAnyC, try_pull_any)), + ?match({NilStrEvent,false}, 'notify_test_StrPullC':doAction(PullStrC, try_pull_str)), + ?match({[],false}, 'notify_test_SeqPullC':doAction(PullSeqC, {try_pull_seq,10})), + + + %% Instruct the Clients to pull the events and check if they match. + %% Pull is blocking so in the print-out we should see that nothing + %% is returned until the pushed event reaches the end proxies. + ?match(AnyEvent, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(StrEvent, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([StrEvent], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})), + + %% To make sure there are no other circumstanses which lead to a delay we + %% hold for some time. + timer:sleep(5000), + %% Check if the Clients have received and stored the events. + ?match([AnyEvent], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([StrEvent], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([StrEvent], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + %% Test with pushing a event sequence but only pull sequences of length 1. + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, EventSeq)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + %% Pull 1 event at a time. + ?match([Event], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})), + ?match([Event2], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})), + + %% Following cases already tested; done for clean up. + ?match({any,_,Event}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(Event, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match({any,_,Event2}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(Event2, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([{any,_,Event}, {any,_,Event2}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([Event, Event2], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([Event, Event2], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + %% clean up done + + + io:format("###################### PROXY PULLER ########################"), + + %% Now we will just add Events to a cleint and wait for the Notification service + %% to pull the events and forward them to the consumer clients. + ?match(ok, 'notify_test_SeqPushC':doAction(PullAnyS, {set_data, [AnyEvent]})), + + + %% Instruct the Clients to pull the events and check if they match. + %% Pull is blocking so in the print-out we should see that nothing + %% is returned until the pushed event reaches the end proxies. + ?match(AnyEvent, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(StrEvent, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([StrEvent], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,10})), + + %% To make sure there are no other circumstanses which lead to a delay we + %% hold for some time. + timer:sleep(5000), + %% Check if the Clients have received and stored the events. + ?match([AnyEvent], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([StrEvent], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([StrEvent], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + io:format("###################### SUSPENDED CONNECTION ################"), + + + %% Suspend the connections + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushSupplier':suspend_connection(SequenceProxyPushSupplier)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushSupplier':suspend_connection(StructuredProxyPushSupplier)), + + %% Test with pushing a event sequence. + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushConsumer':push_structured_events(SequenceProxyPushConsumer, EventSeq)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + + %% Instruct the Clients to pull the events and check if they match. + ?match({any,_,Event}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(Event, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([Event,Event2], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,2})), + ?match({any,_,Event2}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(Event2, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + + %% Check if the Any Client have received and stored the events. + ?match([{any,_,Event}, {any,_,Event2}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + + %% Check if the other Clients have received any events. Error if have. + ?match([], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + ?match(ok,'CosNotifyChannelAdmin_SequenceProxyPushSupplier':resume_connection(SequenceProxyPushSupplier)), + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushSupplier':resume_connection(StructuredProxyPushSupplier)), + + %% To be sure the test case don't fail due to time-race, sleep. + timer:sleep(5000), + + ?match([Event, Event2], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([Event, Event2], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + + io:format("###################### FILTER EVENTS #######################"), + + %% Now we will add filters and see if the system behaves correctly. + FiFac = 'CosNotifyFilter_FilterFactory':oe_create(), + Filter = 'CosNotifyFilter_FilterFactory':create_filter(FiFac,"EXTENDED_TCL"), + %% Add constraints to the Filter + ?line[{_,_,CID1},{_,_,CID2}]= + ?match([{'CosNotifyFilter_ConstraintInfo',_,_}, {'CosNotifyFilter_ConstraintInfo',_,_}], + 'CosNotifyFilter_Filter':add_constraints(Filter, + [#'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "Spare*", + type_name = "MOVIE"}], + constraint_expr = "$type_name == 'MOVIE' and (('groucho' in $starlist) + ('chico' in $starlist) + ('harpo' in $starlist) + ('zeppo' in $starlist) + ('gummo' in $starlist)) > 2"}, + #'CosNotifyFilter_ConstraintExp'{event_types = + [#'CosNotification_EventType'{ + domain_name = "*", + type_name = "TestResults"}], + constraint_expr = "$test._length == 3 and ($test[0].score + $test[1].score + $test[2].score)/3 >=80"}])), + + ?match([{'CosNotifyFilter_ConstraintInfo',_,CID2}, {'CosNotifyFilter_ConstraintInfo',_,CID1}], + 'CosNotifyFilter_Filter':get_all_constraints(Filter)), + ?match([{'CosNotifyFilter_ConstraintInfo',_,CID1}], + 'CosNotifyFilter_Filter':get_constraints(Filter, [CID1])), + + %% Associate the Filter with different objects. + %% Since we use the same filter for both objects the events will never reach the admin. + _FilterID = 'CosNotifyChannelAdmin_ConsumerAdmin':add_filter(AdminConsumer, Filter), + + _FilterID2 = 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':add_filter(StructuredProxyPushConsumer, Filter), + event_filtering(FiFac, Filter, AdminConsumer, StructuredProxyPushConsumer, PushAnyC, + PushStrC, PushSeqC, PullAnyC, PullStrC, PullSeqC), + %% Remove the proxy filter so we can check if the events are filtered correctly by the admin. + ?match(ok, 'CosNotifyChannelAdmin_StructuredProxyPushConsumer':remove_all_filters(StructuredProxyPushConsumer)), + event_filtering(FiFac, Filter, AdminConsumer, StructuredProxyPushConsumer, PushAnyC, + PushStrC, PushSeqC, PullAnyC, PullStrC, PullSeqC), + + + catch corba:dispose(Filter), + catch corba:dispose(FiFac), + catch corba:dispose(SequenceProxyPushConsumer), + catch corba:dispose(StructuredProxyPushConsumer), + catch corba:dispose(ProxyPushConsumer), + catch corba:dispose(SequenceProxyPullConsumer), + catch corba:dispose(StructuredProxyPullConsumer), + catch corba:dispose(ProxyPullConsumer), + catch corba:dispose(SequenceProxyPushSupplier), + catch corba:dispose(StructuredProxyPushSupplier), + catch corba:dispose(ProxyPushSupplier), + catch corba:dispose(SequenceProxyPullSupplier), + catch corba:dispose(StructuredProxyPullSupplier), + catch corba:dispose(ProxyPullSupplier), + catch corba:dispose(AdminConsumer), + catch corba:dispose(AdminSupplier), + catch corba:dispose(Ch), + catch cosNotificationApp:stop_factory(Fac), + %% The Clients should have terminated by now. Check if it is so. + timer:sleep(5000), + ?match(true, corba_object:non_existent(PullSeqS)), + ?match(true, corba_object:non_existent(PullStrS)), + ?match(true, corba_object:non_existent(PullAnyS)), + ?match(true, corba_object:non_existent(PushSeqS)), + ?match(true, corba_object:non_existent(PushStrS)), + ?match(true, corba_object:non_existent(PushAnyS)), + ?match(true, corba_object:non_existent(PullSeqC)), + ?match(true, corba_object:non_existent(PullStrC)), + ?match(true, corba_object:non_existent(PullAnyC)), + ?match(true, corba_object:non_existent(PushSeqC)), + ?match(true, corba_object:non_existent(PushStrC)), + ?match(true, corba_object:non_existent(PushAnyC)), + ok. + +event_filtering(_FiFac, _Filter, _AdminConsumer, StructuredProxyPushConsumer, PushAnyC, PushStrC, PushSeqC, PullAnyC, PullStrC, PullSeqC) -> + NilAnyEvent = any:create(orber_tc:null(), null), + NilStrEvent = ?not_CreateSE("","","",[],[],NilAnyEvent), + + TrueEvent1 = ?not_CreateSE("SpareTime","MOVIE", + "EventName", + [#'CosNotification_Property'{name="starlist", + value=any:create(orber_tc:sequence(orber_tc:string(0),0), + ["groucho", "harpo", "sam", "gummo"])}], + [], any:create(orber_tc:null(), null)), + TrueEvent2 = ?not_CreateSE("Studies","TestResults", + "EventName", [], + [#'CosNotification_Property'{name="test", + value=any:create(orber_tc:array(notify_test_data:tc(),3), + {#notify_test_data{score=75, + name="name"}, + #notify_test_data{score=80, + name="name"}, + #notify_test_data{score=85, + name="name"}})}], + any:create(orber_tc:null(), null)), + + FalseEvent1 = ?not_CreateSE("SpareTime","MOVIE", + "EventName", + [#'CosNotification_Property'{name="starlist", + value=any:create(orber_tc:sequence(orber_tc:string(0),0), + ["frodo", "bilbo", "sam", "gummo"])}], + [], any:create(orber_tc:null(), null)), + FalseEvent2 = ?not_CreateSE("Studies","TestResults", + "EventName", [], + [#'CosNotification_Property'{name="test", + value=any:create(orber_tc:array(notify_test_data:tc(),3), + {#notify_test_data{score=75, + name="name"}, + #notify_test_data{score=80, + name="name"}, + #notify_test_data{score=80, + name="name"}})}], + any:create(orber_tc:null(), null)), + %% Test with pushing the first structured event that should not be filtered away. + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, TrueEvent1)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + + %% Check if the Clients have received and stored the events. + ?match([{any,_,TrueEvent1}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([TrueEvent1], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([TrueEvent1], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + %% Instruct the Clients to pull the events and check if they match. + ?match({any,_,TrueEvent1}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(TrueEvent1, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([TrueEvent1], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})), + + %% Test with pushing the second structured event that should not be filtered away. + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, TrueEvent2)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + + %% Check if the Clients have received and stored the events. + ?match([{any,_,TrueEvent2}], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([TrueEvent2], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([TrueEvent2], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + %% Instruct the Clients to pull the events and check if they match. + ?match({any,_,TrueEvent2}, 'notify_test_AnyPullC':doAction(PullAnyC, pull_any)), + ?match(TrueEvent2, 'notify_test_StrPullC':doAction(PullStrC, pull_str)), + ?match([TrueEvent2], 'notify_test_SeqPullC':doAction(PullSeqC, {pull_seq,1})), + + %% Test with pushing the first structured event that should be filtered away. + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, FalseEvent1)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + + %% Check if the Clients have received and stored the events. + ?match([], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + %% Instruct the Clients to pull the events and check if they match. + ?match({NilAnyEvent,false}, 'notify_test_AnyPullC':doAction(PullAnyC, try_pull_any)), + ?match({NilStrEvent,false}, 'notify_test_StrPullC':doAction(PullStrC, try_pull_str)), + ?match({[],false}, 'notify_test_SeqPullC':doAction(PullSeqC, {try_pull_seq,10})), + + %% Test with pushing the second structured event that should be filtered away. + ?match(ok,'CosNotifyChannelAdmin_StructuredProxyPushConsumer':push_structured_event(StructuredProxyPushConsumer, FalseEvent2)), + + %% Wait for a while so we are sure that all events have been delivered as far + %% as the Notification service can automatically. + timer:sleep(5000), + + %% Check if the Clients have received and stored the events. + ?match([], 'notify_test_AnyPushC':doAction(PushAnyC, return_data)), + ?match([], 'notify_test_StrPushC':doAction(PushStrC, return_data)), + ?match([], 'notify_test_SeqPushC':doAction(PushSeqC, return_data)), + + %% Instruct the Clients to pull the events and check if they match. + ?match({NilAnyEvent,false}, 'notify_test_AnyPullC':doAction(PullAnyC, try_pull_any)), + ?match({NilStrEvent,false}, 'notify_test_StrPullC':doAction(PullStrC, try_pull_str)), + ?match({[],false}, 'notify_test_SeqPullC':doAction(PullSeqC, {try_pull_seq,10})). + + + +%%----------------------------------------------------------------- +%% Creating different cosEvent API tests +%%----------------------------------------------------------------- +cosevent_api(doc) -> ["CosNotification Objects tested with CosEvent API", ""]; +cosevent_api(suite) -> []; +cosevent_api(_Config) -> + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)), + ?match({_,key,_,_,_,_}, Ch), + AC=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_EventChannel':for_consumers(Ch)), + AS=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_EventChannel':for_suppliers(Ch)), + + PushS=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_ConsumerAdmin':obtain_push_supplier(AC)), + PullS=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_ConsumerAdmin':obtain_pull_supplier(AC)), + + PushC=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_SupplierAdmin':obtain_push_consumer(AS)), + PullC=?match({_,key,_,_,_,_}, + 'CosEventChannelAdmin_SupplierAdmin':obtain_pull_consumer(AS)), + + PushAnyC=?match({_,key,_,_,_,_}, + 'notify_test_AnyPushC':oe_create(['PUSH_ANY', PushC], + [{local_typecheck, false}])), + PushStrC=?match({_,key,_,_,_,_}, + 'notify_test_StrPushC':oe_create(['PUSH_STRUCTURED',false], + [{local_typecheck, false}])), + PushSeqC=?match({_,key,_,_,_,_}, + 'notify_test_SeqPushC':oe_create(['PUSH_SEQUENCE',false], + [{local_typecheck, false}])), + + PullAnyC=?match({_,key,_,_,_,_}, + 'notify_test_AnyPullC':oe_create(['PULL_ANY', PullC], + [{local_typecheck, false}])), + PullStrC=?match({_,key,_,_,_,_}, + 'notify_test_StrPullC':oe_create(['PULL_STRUCTURED',false], + [{local_typecheck, false}])), + PullSeqC=?match({_,key,_,_,_,_}, + 'notify_test_SeqPullC':oe_create(['PULL_SEQUENCE',false], + [{local_typecheck, false}])), + + PushAnyS=?match({_,key,_,_,_,_}, + 'notify_test_AnyPushS':oe_create(['PUSH_ANY', PushC], + [{local_typecheck, false}])), + PushStrS=?match({_,key,_,_,_,_}, + 'notify_test_StrPushS':oe_create(['PUSH_STRUCTURED',false], + [{local_typecheck, false}])), + PushSeqS=?match({_,key,_,_,_,_}, + 'notify_test_SeqPushS':oe_create(['PUSH_SEQUENCE',false], + [{local_typecheck, false}])), + + PullAnyS=?match({_,key,_,_,_,_}, + 'notify_test_AnyPullS':oe_create(['PULL_ANY', PullS], + [{local_typecheck, false}])), + PullStrS=?match({_,key,_,_,_,_}, + 'notify_test_StrPullS':oe_create(['PULL_STRUCTURED',false], + [{local_typecheck, false}])), + PullSeqS=?match({_,key,_,_,_,_}, + 'notify_test_SeqPullS':oe_create(['PULL_SEQUENCE',false], + [{local_typecheck, false}])), + + %% In the OMG specification Proxies do not inherrit from CosEvent. Must use + %% Notify interface. + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, + 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PullC, PushStrS)), + + ?match(ok, + 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PushS, PushAnyC)), + ?match(ok, + 'CosEventChannelAdmin_ProxyPullSupplier':connect_pull_consumer(PullS, PullAnyC)), + + ?match(ok, + 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PushC, PushAnyS)), + ?match(ok, + 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PullC, PullAnyS)), + + ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}}, + 'CosEventChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PullC, PullAnyS)), + + ?match({'EXCEPTION',{'CosEventChannelAdmin_AlreadyConnected',_}}, + 'CosNotifyChannelAdmin_ProxyPullConsumer':connect_pull_supplier(PullC, PullAnyS)), + + ?match(true, corba_object:is_a(PushS, "IDL:omg.org/CosNotifyChannelAdmin/ProxyPushSupplier:1.0")), + ?match(true, corba_object:is_a(PushS, "IDL:omg.org/CosEventChannelAdmin/ProxyPushSupplier:1.0")), + + catch corba:dispose(PushStrC), + catch corba:dispose(PushSeqC), + catch corba:dispose(PullStrC), + catch corba:dispose(PullSeqC), + catch corba:dispose(PushStrS), + catch corba:dispose(PushSeqS), + catch corba:dispose(PullStrS), + catch corba:dispose(PullSeqS), + catch corba:dispose(PushS), + catch corba:dispose(PullS), + catch corba:dispose(PushC), + catch corba:dispose(PullC), + catch corba:dispose(AC), + catch corba:dispose(AS), + catch corba:dispose(Ch), + catch cosNotificationApp:stop_factory(Fac), + + %% The Clients should have terminated by now. Check if it is so. + timer:sleep(5000), + ?match(true, corba_object:non_existent(PullAnyS)), + ?match(true, corba_object:non_existent(PushAnyS)), + ?match(true, corba_object:non_existent(PullAnyC)), + ?match(true, corba_object:non_existent(PushAnyC)), + + + ok. + +%%----------------------------------------------------------------- +%% AdminPropertiesAdmin API tests +%%----------------------------------------------------------------- +adm_api(doc) -> ["CosNotification AdminPropertiesAdmin tests", ""]; +adm_api(suite) -> []; +adm_api(_Config) -> + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + + %% We need a few AdminProp:s to "play" with. + MQ0 = [#'CosNotification_Property'{name='CosNotification':'MaxQueueLength'(), + value=any:create(orber_tc:long(), 0)}], + MC0 = [#'CosNotification_Property'{name='CosNotification':'MaxConsumers'(), + value=any:create(orber_tc:long(), 0)}], + MS0 = [#'CosNotification_Property'{name='CosNotification':'MaxSuppliers'(), + value=any:create(orber_tc:long(), 0)}], + MQError1 = [#'CosNotification_Property'{name='CosNotification':'MaxQueueLength'(), + value=any:create(orber_tc:'float'(), 1.5)}], + MQError2 = [#'CosNotification_Property'{name='CosNotification':'MaxQueueLength'(), + value=any:create(orber_tc:long(), -1)}], + + {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)), + ?match({_,key,_,_,_,_}, Ch), + + %% Set new admin + ?match(ok, 'CosNotification_AdminPropertiesAdmin':set_admin(Ch, MQ0)), + %% It should be a list of three items. If we support more admin:s this + %% must be updated. + ?match([_,_,_], 'CosNotification_AdminPropertiesAdmin':get_admin(Ch)), + + %% Try to set admin with an uncorrect value, i.e., not integer >= 0. + ?match({'EXCEPTION',{'CosNotification_UnsupportedAdmin',_,_}}, + 'CosNotification_AdminPropertiesAdmin':set_admin(Ch, MQError1)), + ?match({'EXCEPTION',{'CosNotification_UnsupportedAdmin',_,_}}, + 'CosNotification_AdminPropertiesAdmin':set_admin(Ch, MQError2)), + + %% Try setting the other two admins and chech if the value is correct. + ?match(ok, 'CosNotification_AdminPropertiesAdmin':set_admin(Ch, MC0)), + ?match([_,_,_], 'CosNotification_AdminPropertiesAdmin':get_admin(Ch)), + + ?match(ok, 'CosNotification_AdminPropertiesAdmin':set_admin(Ch, MS0)), + ?match([_,_,_], 'CosNotification_AdminPropertiesAdmin':get_admin(Ch)), + + catch corba:dispose(Ch), + catch cosNotificationApp:stop_factory(Fac), + ok. + + +%%----------------------------------------------------------------- +%% QoSAdm API tests +%%----------------------------------------------------------------- +qos_api(doc) -> ["CosNotification QoSAdmin tests", ""]; +qos_api(suite) -> []; +qos_api(_Config) -> + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + + {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)), + ?match({_,key,_,_,_,_}, Ch), + + + QoSPersistent = [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'Persistent'())}], + QoSBestEffort = [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'BestEffort'())}], + + QoSEventPersistent = [#'CosNotification_Property'{name='CosNotification':'EventReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'Persistent'())}], + QoSEventBestEffort = [#'CosNotification_Property'{name='CosNotification':'EventReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'BestEffort'())}], + + QoSOKMaxBatchSize = [#'CosNotification_Property'{name='CosNotification':'MaximumBatchSize'(), + value=any:create(orber_tc:long(), 200)}], + QoSToHighMaxBatchSize = [#'CosNotification_Property'{name='CosNotification':'MaximumBatchSize'(), + value=any:create(orber_tc:long(), 100000000)}], + + QoSToLowMaxBatchSize = [#'CosNotification_Property'{name='CosNotification':'MaximumBatchSize'(), + value=any:create(orber_tc:long(), -1)}], + + QoSOKStopTimeSupp = [#'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(), + value=any:create(orber_tc:boolean(), true)}], + QoSWrongStopTimeSupp = [#'CosNotification_Property'{name="StopTimeSupp", + value=any:create(orber_tc:boolean(), true)}], + + QoSOKStartTimeSupp = [#'CosNotification_Property'{name='CosNotification':'StartTimeSupported'(), + value=any:create(orber_tc:boolean(), true)}], + QoSWrongStartTimeSupp = [#'CosNotification_Property'{name="StartTimeSupp", + value=any:create(orber_tc:boolean(), true)}], + QoSOKTimout = [#'CosNotification_Property'{name='CosNotification':'Timeout'(), + value=any:create(orber_tc:unsigned_long_long(), 100)}], + + + %% The most complex QoS to set is ConnectionReliability, and the reason for this + %% is that we cannot set the Channel to offer best effort while its children + %% offer persistent. A child may only offer Persistent if its parent do, which + %% is why we must check the following: + %% + %% # Persistent Change to Best Effort + %% _____ + %% | | (1) -> Check if children BE + %% |Chann| (2) ok <- + %% ----- + %% | + %% _____ + %% | | (3) -> Check if children BE + %% |Admin| (4) Check if parent Pers. <- + %% ----- + %% | + %% _____ + %% | | (5) -> ok + %% |Proxy| (6) Check if parent Pers. <- + %% ----- + %% NOTE: a parent always exists but we may change the QoS before creating any + %% childrens. The cases (2) and (5) is always ok, i.e., no need to confirm + %% with parent or children. + + %% We only have a channel. At the moment we can set ConnectionReliability + %% without asking anyone. + Q1='CosNotification_QoSAdmin':get_qos(Ch), + ?match({ok, _}, 'CosNotification_QoSAdmin':validate_qos(Ch, QoSBestEffort)), + + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)), + %% Match if no problems occur if we try to set QoS as is. + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)), + + %% Check validate. + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventPersistent)), + ?match({ok, _}, 'CosNotification_QoSAdmin':validate_qos(Ch, QoSOKTimout)), + ?match({ok, _}, 'CosNotification_QoSAdmin':validate_qos(Ch, QoSEventBestEffort)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventBestEffort)), + ?match({ok, _}, 'CosNotification_QoSAdmin':validate_qos(Ch, QoSOKTimout)), + + Q2='CosNotification_QoSAdmin':get_qos(Ch), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSBestEffort)), + ?match(Q1, 'CosNotification_QoSAdmin':get_qos(Ch)), + + %% Now we add an Admin object. An Admin object cannot switch ConnectionReliability + %% to BestEffort without checking with its children or Persistent without + %% confirming this with its Parent. At the moment, however, we only have a parent. + {CAdm, Id2} = 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch, 'AND_OP'), + ?match(Q1,'CosNotification_QoSAdmin':get_qos(CAdm)), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(CAdm, QoSPersistent)), + ?match(Q1, 'CosNotification_QoSAdmin':get_qos(CAdm)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(CAdm, QoSBestEffort)), + ?match(Q1, 'CosNotification_QoSAdmin':get_qos(CAdm)), + + %% Check if we can extract the Admin from the channel correctly. + ?match([0,Id2],'CosNotifyChannelAdmin_EventChannel':get_all_consumeradmins(Ch)), + ?match(CAdm,'CosNotifyChannelAdmin_EventChannel':get_consumeradmin(Ch, Id2)), + ?match(Ch, 'CosNotifyChannelAdmin_ConsumerAdmin':'_get_MyChannel'(CAdm)), + ?match(Id2, 'CosNotifyChannelAdmin_ConsumerAdmin':'_get_MyID'(CAdm)), + + %% Change the channel to provide Persistent service. Now we can set the + %% Admin service to Persistent to. (4) + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(CAdm, QoSPersistent)), + ?match(Q2, 'CosNotification_QoSAdmin':get_qos(CAdm)), + + %% Since the Admin object now provide Persistent the Channel cannot switch + %% to BestEffort. (1) + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(Ch, QoSBestEffort)), + %% Should still match Persistent. + ?match(Q2, 'CosNotification_QoSAdmin':get_qos(Ch)), + {PSup, _Id3} = 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(CAdm, 'ANY_EVENT'), + ?match(Q2, 'CosNotification_QoSAdmin':get_qos(CAdm)), + ?match('PUSH_ANY', 'CosNotifyChannelAdmin_ProxyPushConsumer':'_get_MyType'(PSup)), + ?match(CAdm, 'CosNotifyChannelAdmin_ProxyPushConsumer':'_get_MyAdmin'(PSup)), + ?match(Q2, 'CosNotification_QoSAdmin':get_qos(PSup)), + + %% At this point they all offer persistent connection, which means we have + %% to start with the proxy if we want to change to Best Effort. Hence, + %% the following two cases will fail. + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(Ch, QoSBestEffort)), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(CAdm, QoSBestEffort)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, QoSBestEffort)), + %% Still not possible to change channel to Best Effort. + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(Ch, QoSBestEffort)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(CAdm, QoSBestEffort)), + %% Now we change the channel to Best Effort. + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSBestEffort)), + + %% Test if really are Best Effort + ?match(Q1, 'CosNotification_QoSAdmin':get_qos(Ch)), + ?match(Q1, 'CosNotification_QoSAdmin':get_qos(CAdm)), + ?match(Q1, 'CosNotification_QoSAdmin':get_qos(PSup)), + + %% Testing MaximumBatchSize (The highest value is defined in + %% CosNotification_Common.erl + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSOKMaxBatchSize)), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(Ch, QoSToHighMaxBatchSize)), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(Ch, QoSToLowMaxBatchSize)), + + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSOKStartTimeSupp)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSOKStopTimeSupp)), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(Ch, QoSWrongStartTimeSupp)), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(Ch, QoSWrongStopTimeSupp)), + + catch corba:dispose(CAdm), + catch corba:dispose(PSup), + catch corba:dispose(Ch), + cosNotificationApp:stop_factory(Fac), + ok. + +%%----------------------------------------------------------------- +%% QoSAdm API tests +%%----------------------------------------------------------------- +event_qos_api(doc) -> ["CosNotification QoSAdmin tests", ""]; +event_qos_api(suite) -> []; +event_qos_api(_Config) -> + Fac = (catch cosNotificationApp:start_global_factory(?FAC_OPT)), + ?match({_,key,_,_,_,_}, Fac), + + %% Create some objects to test with. We start with default settings. + {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, ?defaultQoS, ?defaultAdm)), + {CAdm, _Id2} = 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch, 'AND_OP'), + {PSup, _Id3} = 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_push_supplier(CAdm, 'ANY_EVENT'), + + %% Try setting an unsupported QoS. + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name="Unsupported QoS", + value=any:create(orber_tc:short(), 1)}])), + %% Try setting min and max priority. + ?match({ok, _}, 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_Priority, + value=any:create(orber_tc:short(), + ?not_LowestPriority)}, + #'CosNotification_Property'{name=?not_Priority, + value=any:create(orber_tc:short(), + ?not_HighestPriority)}])), + %% Try setting priority values which are 1 to high and 1 to low respectively. + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_Priority, + value=any:create(orber_tc:short(), + ?not_LowestPriority-1)}, + #'CosNotification_Property'{name=?not_Priority, + value=any:create(orber_tc:short(), + ?not_HighestPriority+1)}])), + %% Try setting start- and stop-time (false default). Note the value associated + %% with this property is not really a short but that is not what we are testing + %% here so... + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_StartTime, + value=any:create(orber_tc:short(), 0)}])), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_StopTime, + value=any:create(orber_tc:short(), 0)}])), + %% Allow StopTime + ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, [#'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(), + value=any:create(orber_tc:boolean(), true)}])), + ?match({ok,_}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_StopTime, + value=any:create(orber_tc:short(), 0)}])), + %% Allow StartTime + ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, [#'CosNotification_Property'{name='CosNotification':'StartTimeSupported'(), + value=any:create(orber_tc:boolean(), true)}])), + ?match({ok,_}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_StopTime, + value=any:create(orber_tc:short(), 0)}, + #'CosNotification_Property'{name=?not_StartTime, + value=any:create(orber_tc:short(), 0)}])), + + %% We must reset StopTime since we cannot guarantee that an event will be delivered + %% if risk beeing discarded due to a delay. + ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, [#'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(), + value=any:create(orber_tc:boolean(), false)}])), + %% Does it accept Best Effort EventReliability? Must always be true. + ?match({ok,_}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_EventReliability, + value=any:create(orber_tc:short(), ?not_BestEffort)}])), + %% Default is Best Effort; test if we can set Persistent EventReliability. + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_EventReliability, + value=any:create(orber_tc:short(), ?not_Persistent)}])), + + %% Set Persistent + QoSPersistent = [#'CosNotification_Property'{name='CosNotification':'ConnectionReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'Persistent'())}], + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(CAdm, QoSPersistent)), + ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, QoSPersistent)), + + %% Does it accept Best Effort EventReliability? Must always be true. + ?match({ok, _}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_EventReliability, + value=any:create(orber_tc:short(), ?not_BestEffort)}])), + %% Test if we can use Persistent EventReliability. + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_EventReliability, + value=any:create(orber_tc:short(), ?not_Persistent)}])), + QoSEventPersistent = [#'CosNotification_Property'{name='CosNotification':'EventReliability'(), + value=any:create(orber_tc:short(), + 'CosNotification':'Persistent'())}], + ?match(ok, 'CosNotification_QoSAdmin':set_qos(Ch, QoSEventPersistent)), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(CAdm, QoSEventPersistent)), + ?match({'EXCEPTION',{'CosNotification_UnsupportedQoS',_,_}}, + 'CosNotification_QoSAdmin':set_qos(PSup, QoSEventPersistent)), + + ?match(ok, 'CosNotification_QoSAdmin':set_qos(PSup, [#'CosNotification_Property'{name='CosNotification':'StopTimeSupported'(), + value=any:create(orber_tc:boolean(), true)}])), + ?match({ok,_}, + 'CosNotifyChannelAdmin_ProxyConsumer': + validate_event_qos(PSup, + [#'CosNotification_Property'{name=?not_StopTime, + value=any:create(orber_tc:short(), 0)}, + #'CosNotification_Property'{name=?not_StartTime, + value=any:create(orber_tc:short(), 0)}])), + catch corba:dispose(CAdm), + catch corba:dispose(PSup), + catch corba:dispose(Ch), + cosNotificationApp:stop_factory(Fac), + ok. + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- + +%%-------------------- End of Module ------------------------------ diff --git a/lib/cosNotification/test/notify_test_impl.erl b/lib/cosNotification/test/notify_test_impl.erl new file mode 100644 index 0000000000..483610befd --- /dev/null +++ b/lib/cosNotification/test/notify_test_impl.erl @@ -0,0 +1,299 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : notify_test_impl.erl +%%---------------------------------------------------------------------- + +-module(notify_test_impl). + +-include_lib("orber/include/corba.hrl"). +-include("idl_output/notify_test.hrl"). + +%%--------------- specified functions ------------------------ +-export([stop_normal/2, + stop_brutal/2, + print/2, + doAction/3, + delay/5, + %% Exports from CosNotifyComm::StructuredPushConsumer + push_structured_event/3, disconnect_structured_push_consumer/2, + %% Exports from "CosNotifyComm::SequencePushConsumer" + push_structured_events/3, disconnect_sequence_push_consumer/2, + %% Exports from CosEventComm::PushConsumer + push/3, disconnect_push_consumer/2, + %% Exports from CosNotifyComm::NotifyPublish + disconnect_sequence_pull_consumer/2, + %% Exports from CosNotifyComm::StructuredPullConsumer + disconnect_structured_pull_consumer/2, + %% Exports from CosEventComm::PullConsumer + disconnect_pull_consumer/2, + %% Exports from CosNotifyComm::SequencePushSupplier + disconnect_sequence_push_supplier/2, + %% Exports from CosNotifyComm::StructuredPushSupplier + disconnect_structured_push_supplier/2, + %% Exports from CosEventComm::PushSupplier + disconnect_push_supplier/2, + %% Exports from CosNotifyComm::SequencePullSupplier + pull_structured_events/3, + try_pull_structured_events/3, + disconnect_sequence_pull_supplier/2, + %% Exports from CosNotifyComm::StructuredPullSupplier + pull_structured_event/2, + try_pull_structured_event/2, + disconnect_structured_pull_supplier/2, + %% Exports from CosEventComm::PullSupplier + pull/2, + try_pull/2, + disconnect_pull_supplier/2, + %% Exports from CosNotifyComm::SequencePullConsumer + offer_change/4, + %% Exports from CosNotifyComm::NotifySubscribe + subscription_change/4]). + +%%--------------- gen_server specific ------------------------ +-export([init/1, terminate/2]). +-export([handle_call/3, handle_cast/2, handle_info/2, code_change/3]). +%% Data structures +-record(state, {myType, proxy, data, action}). + +%%--------------- LOCAL DATA --------------------------------- + +%%------------------------------------------------------------ +%% function : init, terminate +%%------------------------------------------------------------ +init([MyType, Proxy]) -> + process_flag(trap_exit,true), + {ok, #state{myType=MyType, proxy=Proxy, data=[]}}. + +terminate(Reason, State) -> + io:format("notify_test:terminate(~p ~p)~n",[Reason, State#state.myType]), + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. +handle_call(_,_, State) -> + {noreply, State}. +handle_cast(_, State) -> + {noreply, State}. +handle_info(_Info, State) -> + {noreply, State}. + +%%--------------- SERVER FUNCTIONS --------------------------- + +print(Self, State) -> + io:format("notify_test:print(~p ~p)~n",[Self, State]), + {reply, ok, State}. + +doAction(_Self, State, {set_data, Data}) -> + io:format("notify_test:doAction(add_data) ~p~n",[Data]), + {reply, ok, State#state{data=Data}}; +doAction(_Self, State, {add_data, Data}) -> + io:format("notify_test:doAction(add_data) ~p~n",[Data]), + {reply, ok, State#state{data=State#state.data++Data}}; +doAction(_Self, State, return_data) -> + io:format("notify_test:doAction(return_data)~n",[]), + {reply, State#state.data, State#state{data=[]}}; +doAction(_Self, State, clear_data) -> + io:format("notify_test:doAction(return_data)~n",[]), + {reply, ok, State#state{data=[]}}; +doAction(_Self, State, pull_any) -> + io:format("notify_test:doAction(pull_any)~n",[]), + Event='CosNotifyChannelAdmin_ProxyPullSupplier':pull(State#state.proxy), + {reply, Event, State}; +doAction(_Self, State, {pull_seq, Max}) -> + io:format("notify_test:doAction(pull_sequence)~n",[]), + Event='CosNotifyChannelAdmin_SequenceProxyPullSupplier':pull_structured_events(State#state.proxy, Max), + {reply, Event, State}; +doAction(_Self, State, pull_str) -> + Event='CosNotifyChannelAdmin_StructuredProxyPullSupplier':pull_structured_event(State#state.proxy), + io:format("notify_test:doAction(pull_structured)~n",[]), + {reply, Event, State}; +doAction(_Self, State, try_pull_any) -> + io:format("notify_test:doAction(try_pull_any)~n",[]), + Event='CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(State#state.proxy), + {reply, Event, State}; +doAction(_Self, State, {try_pull_seq, Max}) -> + io:format("notify_test:doAction(try_pull_sequence)~n",[]), + Event='CosNotifyChannelAdmin_SequenceProxyPullSupplier':try_pull_structured_events(State#state.proxy, Max), + {reply, Event, State}; +doAction(_Self, State, try_pull_str) -> + Event='CosNotifyChannelAdmin_StructuredProxyPullSupplier':try_pull_structured_event(State#state.proxy), + io:format("notify_test:doAction(try_pull_structured)~n",[]), + {reply, Event, State}; +doAction(_Self, State, {action, Action}) -> + io:format("notify_test:doAction(~p)~n",[Action]), + {reply, ok, State#state{action = Action}}; + +doAction(_, State, _) -> + {reply, nop, State}. + +stop_normal(_Self, State) -> + {stop, normal, ok, State}. + +stop_brutal(_Self, _State) -> + exit("killed_brutal"). + + + +%%--------------- CosNotifyComm::NotifyPublish -------- +offer_change(_Self, State, Added, Removed) -> + ND=loop(Removed, State#state.data), + ND2=Added++ND, + {reply, ok, State#state{data=ND2}}. + +loop([],Data) -> + Data; +loop([H|T], Data) -> + ND=lists:delete(H,Data), + loop(T, ND). + +%%--------------- CosNotifyComm::NotifySubscribe -------- +subscription_change(_Self, State, Added, Removed) -> + ND=loop(Removed, State#state.data), + ND2=Added++ND, + {reply, ok, State#state{data=ND2}}. + +%%--------------- CosNotifyComm::SequencePushConsumer -------- +push_structured_events(_Self, #state{action = undefined} = State, Event) -> + io:format("notify_test:push_structured_events(~p)~n",[Event]), + {reply, ok, State#state{data=State#state.data++Event}}; +push_structured_events(_Self, #state{action = Action} = State, Event) -> + io:format("notify_test:push_structured_events(~p)~nAction: ~p~n", + [Event, Action]), + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}), + {reply, ok, State#state{data=State#state.data++Event}}. +disconnect_sequence_push_consumer(_Self, State) -> + io:format("disconnect_sequence_push_consumer~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosNotifyComm::StructuredPushConsumer -------- +push_structured_event(_Self, State, Event) -> + io:format("notify_test:push_structured_event(~p)~n",[Event]), + {reply, ok, State#state{data=State#state.data++[Event]}}. +disconnect_structured_push_consumer(_Self, State) -> + io:format("disconnect_structured_push_consumer~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosEventComm::PushConsumer -------- +push(_Self, State, Event) -> + io:format("notify_test:push(~p)~n",[Event]), + {reply, ok, State#state{data=State#state.data++[Event]}}. +disconnect_push_consumer(_Self, State) -> + io:format("disconnect_push_consumer~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosNotifyComm::SequencePullConsumer -------- +disconnect_sequence_pull_consumer(_Self, State) -> + io:format("disconnect_sequence_pull_consumer~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosNotifyComm::StructuredPullConsumer -------- +disconnect_structured_pull_consumer(_Self, State) -> + io:format("disconnect_structured_pull_consumer~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosEventComm::PullConsumer -------- +disconnect_pull_consumer(_Self, State) -> + io:format("disconnect_pull_consumer~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosNotifyComm::SequencePushSupplier -------- +disconnect_sequence_push_supplier(_Self, State) -> + io:format("disconnect_sequence_push_supplier~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosNotifyComm::StructuredPushSupplier -------- +disconnect_structured_push_supplier(_Self, State) -> + io:format("disconnect_structured_push_supplier~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosEventComm::PushSupplier -------- +disconnect_push_supplier(_Self, State) -> + io:format("disconnect_push_supplier~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosNotifyComm::SequencePullSupplier -------- +pull_structured_events(_Self, State, _Max) -> + io:format("notify_test:pullstructured_events()~n",[]), + {reply, ok, State}. +try_pull_structured_events(_Self, State, Max) -> + io:format("notify_test:try_pull_structured_events()~n",[]), + case State#state.data of + [] -> + {reply, {[],false}, State}; + List -> + R = split(List,Max), + {reply, {lists:sublist(List, Max), true}, State#state{data=R}} + end. + +split([],_) -> + []; +split(R,0) -> + R; +split([_H|T],Max) -> + split(T, Max-1). + +disconnect_sequence_pull_supplier(_Self, State) -> + io:format("disconnect_sequence_pull_supplier~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosNotifyComm::StructuredPullSupplier -------- +pull_structured_event(_Self, State) -> + io:format("notify_test:pull_structured_event()~n",[]), + {reply, ok, State}. +try_pull_structured_event(_Self, State) -> + io:format("notify_test:try_pull_structured_event()~n",[]), + case State#state.data of + [] -> + {reply, {[],false}, State}; + [H|T] -> + {reply, {H, true}, State#state{data=T}} + end. +disconnect_structured_pull_supplier(_Self, State) -> + io:format("disconnect_structured_pull_supplier~n",[]), + {stop, normal, ok, State}. + +%%--------------- CosEventComm::PullSupplier -------- +pull(_Self, State) -> + io:format("notify_test:pull()~n",[]), + {reply, 'CosEventComm_PullSupplier':pull(State#state.proxy), State}. +try_pull(_Self, State) -> + io:format("notify_test:try_pull()~n",[]), + case State#state.data of + [] -> + {reply, {[],false}, State}; + [H|T] -> + {reply, {H, true}, State#state{data=T}} + end. +disconnect_pull_supplier(_Self, State) -> + io:format("disconnect_pull_supplier~n",[]), + {stop, normal, ok, State}. + +%%--------------- LOCAL FUNCTIONS ---------------------------- + +delay(Obj, Event, Time, Mod, F) -> + io:format("notify_test:delay(~p) TIME: ~p~n",[Event, now()]), + timer:sleep(Time), + Mod:F(Obj, Event), + io:format("notify_test:delay() DONE: ~p~n",[now()]), + ok. + +%%--------------- END OF MODULE ------------------------------ + diff --git a/lib/cosNotification/test/notify_test_server.cfg b/lib/cosNotification/test/notify_test_server.cfg new file mode 100644 index 0000000000..8621327b57 --- /dev/null +++ b/lib/cosNotification/test/notify_test_server.cfg @@ -0,0 +1,54 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +{this, "notify_test::SeqPushC"}. +{{handle_info, "notify_test::SeqPushC"}, true}. +{{impl, "notify_test::SeqPushC"}, "notify_test_impl"}. +{this, "notify_test::StrPushC"}. +{{handle_info, "notify_test::StrPushC"}, true}. +{{impl, "notify_test::StrPushC"}, "notify_test_impl"}. +{this, "notify_test::AnyPushC"}. +{{handle_info, "notify_test::AnyPushC"}, true}. +{{impl, "notify_test::AnyPushC"}, "notify_test_impl"}. +{this, "notify_test::SeqPullC"}. +{{handle_info, "notify_test::SeqPullC"}, true}. +{{impl, "notify_test::SeqPullC"}, "notify_test_impl"}. +{this, "notify_test::StrPullC"}. +{{handle_info, "notify_test::StrPullC"}, true}. +{{impl, "notify_test::StrPullC"}, "notify_test_impl"}. +{this, "notify_test::AnyPullC"}. +{{handle_info, "notify_test::AnyPullC"}, true}. +{{impl, "notify_test::AnyPullC"}, "notify_test_impl"}. +{this, "notify_test::SeqPushS"}. +{{handle_info, "notify_test::SeqPushS"}, true}. +{{impl, "notify_test::SeqPushS"}, "notify_test_impl"}. +{this, "notify_test::StrPushS"}. +{{handle_info, "notify_test::StrPushS"}, true}. +{{impl, "notify_test::StrPushS"}, "notify_test_impl"}. +{this, "notify_test::AnyPushS"}. +{{handle_info, "notify_test::AnyPushS"}, true}. +{{impl, "notify_test::AnyPushS"}, "notify_test_impl"}. +{this, "notify_test::SeqPullS"}. +{{handle_info, "notify_test::SeqPullS"}, true}. +{{impl, "notify_test::SeqPullS"}, "notify_test_impl"}. +{this, "notify_test::StrPullS"}. +{{handle_info, "notify_test::StrPullS"}, true}. +{{impl, "notify_test::StrPullS"}, "notify_test_impl"}. +{this, "notify_test::AnyPullS"}. +{{handle_info, "notify_test::AnyPullS"}, true}. +{{impl, "notify_test::AnyPullS"}, "notify_test_impl"}. diff --git a/lib/cosNotification/test/notify_test_server.idl b/lib/cosNotification/test/notify_test_server.idl new file mode 100644 index 0000000000..4dc0202890 --- /dev/null +++ b/lib/cosNotification/test/notify_test_server.idl @@ -0,0 +1,113 @@ +// +// %CopyrightBegin% +// +// Copyright Ericsson AB 1999-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// + +#ifndef _NOTIFY_TEST_SERVER_IDL +#define _NOTIFY_TEST_SERVER_IDL + +#include <CosNotification.idl> +#include <CosNotifyComm.idl> + +module notify_test { + + enum action {PULL_SEQ, PULL_STR, PULL_ANY, PUSH_SEQ, PUSH_STR, PUSH_ANY}; + + struct data { + short score; + string name; + }; + + struct computer { + float memsize; + float cputime; + float filesize; + }; + + struct X { + long A; + string B; + short C; + }; + + + union K switch(short) { + case -1: short neg; + case 0: + case 2: string K; + case 3: X L; + case 5: long M; + default: short N; + }; + + union uni1 switch(long) { + case 1: + case 2: long lo; + case 3: short sh; + default: short defvalue; + }; + + union uni2 switch(long) { + case 1: + case 2: long lo; + case 3: short sh; + }; + + typedef any namedAny; + typedef short ShortArray[4]; + struct studies { + uni1 uni1; + CosNotification::PropertySeq tests; + ShortArray monthly_attendance; + short gpa; + }; + + interface funcs { + void print(); + void doAction(in action Act); + }; + + // interface server + interface SeqPushC : funcs, CosNotifyComm::SequencePushConsumer { + }; + interface StrPushC : funcs, CosNotifyComm::StructuredPushConsumer { + }; + interface AnyPushC : funcs, CosEventComm::PushConsumer { + }; + interface SeqPullC : funcs, CosNotifyComm::SequencePullConsumer { + }; + interface StrPullC : funcs, CosNotifyComm::StructuredPullConsumer { + }; + interface AnyPullC : funcs, CosEventComm::PullConsumer { + }; + + interface SeqPushS : funcs, CosNotifyComm::SequencePushSupplier { + }; + interface StrPushS : funcs, CosNotifyComm::StructuredPushSupplier { + }; + interface AnyPushS : funcs, CosEventComm::PushSupplier { + }; + interface SeqPullS : funcs, CosNotifyComm::SequencePullSupplier { + }; + interface StrPullS : funcs, CosNotifyComm::StructuredPullSupplier { + }; + interface AnyPullS : funcs, CosEventComm::PullSupplier { + }; + +}; + +#endif diff --git a/lib/cosProperty/test/Makefile b/lib/cosProperty/test/Makefile new file mode 100644 index 0000000000..ac0f4e298d --- /dev/null +++ b/lib/cosProperty/test/Makefile @@ -0,0 +1,129 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2000-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSPROPERTY_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/cosProperty_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = cosProperty.spec + + +IDL_FILES = + +IDLOUTDIR = idl_output + +MODULES = \ + property_SUITE \ + generated_SUITE + +GEN_MODULES = \ + +GEN_HRL_FILES = \ + +ERL_FILES = $(MODULES:%=%.erl) + +HRL_FILES = + +GEN_FILES = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl) + +GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR)) + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(GEN_TARGET_FILES) \ + $(SUITE_TARGET_FILES) + + +# ---------------------------------------------------- +# PROGRAMS +# ---------------------------------------------------- +LOCAL_CLASSPATH = $(ERL_TOP)lib/cosProperty/priv:$(ERL_TOP)lib/cosProperty/test +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosProperty/ebin \ + -pa $(ERL_TOP)/lib/cosProperty/src \ + -pa $(ERL_TOP)/lib/orber/ebin \ + -pa $(ERL_TOP)/lib/ic/ebin + +ERL_COMPILE_FLAGS += \ + $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/orber/include \ + -pa $(ERL_TOP)/internal_tools/test_server/ebin \ + -pa $(ERL_TOP)/lib/cosProperty/ebin \ + -pa $(ERL_TOP)/lib/cosProperty/test/idl_output \ + -I$(ERL_TOP)/lib/orber/include \ + -I$(ERL_TOP)/lib/cosProperty/src \ + -I$(ERL_TOP)/lib/cosProperty \ + -I$(ERL_TOP)/lib/cosProperty/test/$(IDLOUTDIR) \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + + +tests debug opt: $(TARGET_FILES) + +clean: + rm -f idl_output/* + rm -f $(TARGET_FILES) + rm -f errs core *~ + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +# We don't copy generated intermediate erlang and hrl files + +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ + $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) +# $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) +# $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ +# $(RELSYSDIR)/$(IDLOUTDIR) + diff --git a/lib/cosProperty/test/cosProperty.spec b/lib/cosProperty/test/cosProperty.spec new file mode 100644 index 0000000000..d3e0001eef --- /dev/null +++ b/lib/cosProperty/test/cosProperty.spec @@ -0,0 +1,20 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +{topcase, {dir, "../cosProperty_test"}}. + diff --git a/lib/cosProperty/test/generated_SUITE.erl b/lib/cosProperty/test/generated_SUITE.erl new file mode 100644 index 0000000000..80a7953949 --- /dev/null +++ b/lib/cosProperty/test/generated_SUITE.erl @@ -0,0 +1,571 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : generated_SUITE.erl +%% Purpose : +%%----------------------------------------------------------------- + +-module(generated_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(nomatch(Not, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + Not -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS); + _ -> + AcTuAlReS + end + end()). + + +-define(checktc(_Op), + fun(TC) -> + case orber_tc:check_tc(TC) of + false -> + io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]), + ?line exit(TC); + true -> + true + end + end). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["This suite is for testing IC generated files"]; +all(suite) -> + ['CosPropertyService_ConflictingProperty', 'CosPropertyService_ConstraintNotSupported', + 'CosPropertyService_FixedProperty', 'CosPropertyService_InvalidPropertyName', + 'CosPropertyService_MultipleExceptions', 'CosPropertyService_Properties', + 'CosPropertyService_Property', 'CosPropertyService_PropertyDef', + 'CosPropertyService_PropertyDefs', 'CosPropertyService_PropertyException', + 'CosPropertyService_PropertyExceptions', 'CosPropertyService_PropertyMode', + 'CosPropertyService_PropertyModes', 'CosPropertyService_PropertyNames', + 'CosPropertyService_PropertyNotFound', 'CosPropertyService_PropertyTypes', + 'CosPropertyService_ReadOnlyProperty', 'CosPropertyService_UnsupportedMode', + 'CosPropertyService_UnsupportedProperty', 'CosPropertyService_UnsupportedTypeCode', + 'CosPropertyService_PropertyNamesIterator', 'CosPropertyService_PropertiesIterator', + 'CosPropertyService_PropertySet', 'CosPropertyService_PropertySetDef', + 'CosPropertyService_PropertySetDefFactory', 'CosPropertyService_PropertySetFactory']. + + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + + + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_ConflictingProperty' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_ConflictingProperty'(doc) -> ["CosPropertyService_ConflictingProperty"]; +'CosPropertyService_ConflictingProperty'(suite) -> []; +'CosPropertyService_ConflictingProperty'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_ConflictingProperty':tc())), + ?match("IDL:omg.org/CosPropertyService/ConflictingProperty:1.0", + 'CosPropertyService_ConflictingProperty':id()), + ?match("CosPropertyService_ConflictingProperty", + 'CosPropertyService_ConflictingProperty':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_ConstraintNotSupported' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_ConstraintNotSupported'(doc) -> ["CosPropertyService_ConstraintNotSupported"]; +'CosPropertyService_ConstraintNotSupported'(suite) -> []; +'CosPropertyService_ConstraintNotSupported'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_ConstraintNotSupported':tc())), + ?match("IDL:omg.org/CosPropertyService/ConstraintNotSupported:1.0", + 'CosPropertyService_ConstraintNotSupported':id()), + ?match("CosPropertyService_ConstraintNotSupported", + 'CosPropertyService_ConstraintNotSupported':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_FixedProperty' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_FixedProperty'(doc) -> ["CosPropertyService_FixedProperty"]; +'CosPropertyService_FixedProperty'(suite) -> []; +'CosPropertyService_FixedProperty'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_FixedProperty':tc())), + ?match("IDL:omg.org/CosPropertyService/FixedProperty:1.0", + 'CosPropertyService_FixedProperty':id()), + ?match("CosPropertyService_FixedProperty", + 'CosPropertyService_FixedProperty':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_InvalidPropertyName' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_InvalidPropertyName'(doc) -> ["CosPropertyService_InvalidPropertyName"]; +'CosPropertyService_InvalidPropertyName'(suite) -> []; +'CosPropertyService_InvalidPropertyName'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_InvalidPropertyName':tc())), + ?match("IDL:omg.org/CosPropertyService/InvalidPropertyName:1.0", + 'CosPropertyService_InvalidPropertyName':id()), + ?match("CosPropertyService_InvalidPropertyName", + 'CosPropertyService_InvalidPropertyName':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_MultipleExceptions' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_MultipleExceptions'(doc) -> ["CosPropertyService_MultipleExceptions"]; +'CosPropertyService_MultipleExceptions'(suite) -> []; +'CosPropertyService_MultipleExceptions'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_MultipleExceptions':tc())), + ?match("IDL:omg.org/CosPropertyService/MultipleExceptions:1.0", + 'CosPropertyService_MultipleExceptions':id()), + ?match("CosPropertyService_MultipleExceptions", + 'CosPropertyService_MultipleExceptions':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_Properties' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_Properties'(doc) -> ["CosPropertyService_Properties"]; +'CosPropertyService_Properties'(suite) -> []; +'CosPropertyService_Properties'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_Properties':tc())), + ?match("IDL:omg.org/CosPropertyService/Properties:1.0", + 'CosPropertyService_Properties':id()), + ?match("CosPropertyService_Properties", + 'CosPropertyService_Properties':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_Property' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_Property'(doc) -> ["CosPropertyService_Property"]; +'CosPropertyService_Property'(suite) -> []; +'CosPropertyService_Property'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_Property':tc())), + ?match("IDL:omg.org/CosPropertyService/Property:1.0", + 'CosPropertyService_Property':id()), + ?match("CosPropertyService_Property", + 'CosPropertyService_Property':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertyDef' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertyDef'(doc) -> ["CosPropertyService_PropertyDef"]; +'CosPropertyService_PropertyDef'(suite) -> []; +'CosPropertyService_PropertyDef'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_PropertyDef':tc())), + ?match("IDL:omg.org/CosPropertyService/PropertyDef:1.0", + 'CosPropertyService_PropertyDef':id()), + ?match("CosPropertyService_PropertyDef", + 'CosPropertyService_PropertyDef':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertyDefs' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertyDefs'(doc) -> ["CosPropertyService_PropertyDefs"]; +'CosPropertyService_PropertyDefs'(suite) -> []; +'CosPropertyService_PropertyDefs'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_PropertyDefs':tc())), + ?match("IDL:omg.org/CosPropertyService/PropertyDefs:1.0", + 'CosPropertyService_PropertyDefs':id()), + ?match("CosPropertyService_PropertyDefs", + 'CosPropertyService_PropertyDefs':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertyException' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertyException'(doc) -> ["CosPropertyService_PropertyException"]; +'CosPropertyService_PropertyException'(suite) -> []; +'CosPropertyService_PropertyException'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_PropertyException':tc())), + ?match("IDL:omg.org/CosPropertyService/PropertyException:1.0", + 'CosPropertyService_PropertyException':id()), + ?match("CosPropertyService_PropertyException", + 'CosPropertyService_PropertyException':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertyExceptions' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertyExceptions'(doc) -> ["CosPropertyService_PropertyExceptions"]; +'CosPropertyService_PropertyExceptions'(suite) -> []; +'CosPropertyService_PropertyExceptions'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_PropertyExceptions':tc())), + ?match("IDL:omg.org/CosPropertyService/PropertyExceptions:1.0", + 'CosPropertyService_PropertyExceptions':id()), + ?match("CosPropertyService_PropertyExceptions", + 'CosPropertyService_PropertyExceptions':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertyMode' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertyMode'(doc) -> ["CosPropertyService_PropertyMode"]; +'CosPropertyService_PropertyMode'(suite) -> []; +'CosPropertyService_PropertyMode'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_PropertyMode':tc())), + ?match("IDL:omg.org/CosPropertyService/PropertyMode:1.0", + 'CosPropertyService_PropertyMode':id()), + ?match("CosPropertyService_PropertyMode", + 'CosPropertyService_PropertyMode':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertyModes' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertyModes'(doc) -> ["CosPropertyService_PropertyModes"]; +'CosPropertyService_PropertyModes'(suite) -> []; +'CosPropertyService_PropertyModes'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_PropertyModes':tc())), + ?match("IDL:omg.org/CosPropertyService/PropertyModes:1.0", + 'CosPropertyService_PropertyModes':id()), + ?match("CosPropertyService_PropertyModes", + 'CosPropertyService_PropertyModes':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertyNames' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertyNames'(doc) -> ["CosPropertyService_PropertyNames"]; +'CosPropertyService_PropertyNames'(suite) -> []; +'CosPropertyService_PropertyNames'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_PropertyNames':tc())), + ?match("IDL:omg.org/CosPropertyService/PropertyNames:1.0", + 'CosPropertyService_PropertyNames':id()), + ?match("CosPropertyService_PropertyNames", + 'CosPropertyService_PropertyNames':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertyNotFound' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertyNotFound'(doc) -> ["CosPropertyService_PropertyNotFound"]; +'CosPropertyService_PropertyNotFound'(suite) -> []; +'CosPropertyService_PropertyNotFound'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_PropertyNotFound':tc())), + ?match("IDL:omg.org/CosPropertyService/PropertyNotFound:1.0", + 'CosPropertyService_PropertyNotFound':id()), + ?match("CosPropertyService_PropertyNotFound", + 'CosPropertyService_PropertyNotFound':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertyTypes' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertyTypes'(doc) -> ["CosPropertyService_PropertyTypes"]; +'CosPropertyService_PropertyTypes'(suite) -> []; +'CosPropertyService_PropertyTypes'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_PropertyTypes':tc())), + ?match("IDL:omg.org/CosPropertyService/PropertyTypes:1.0", + 'CosPropertyService_PropertyTypes':id()), + ?match("CosPropertyService_PropertyTypes", + 'CosPropertyService_PropertyTypes':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_ReadOnlyProperty' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_ReadOnlyProperty'(doc) -> ["CosPropertyService_ReadOnlyProperty"]; +'CosPropertyService_ReadOnlyProperty'(suite) -> []; +'CosPropertyService_ReadOnlyProperty'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_ReadOnlyProperty':tc())), + ?match("IDL:omg.org/CosPropertyService/ReadOnlyProperty:1.0", + 'CosPropertyService_ReadOnlyProperty':id()), + ?match("CosPropertyService_ReadOnlyProperty", + 'CosPropertyService_ReadOnlyProperty':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_UnsupportedMode' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_UnsupportedMode'(doc) -> ["CosPropertyService_UnsupportedMode"]; +'CosPropertyService_UnsupportedMode'(suite) -> []; +'CosPropertyService_UnsupportedMode'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_UnsupportedMode':tc())), + ?match("IDL:omg.org/CosPropertyService/UnsupportedMode:1.0", + 'CosPropertyService_UnsupportedMode':id()), + ?match("CosPropertyService_UnsupportedMode", + 'CosPropertyService_UnsupportedMode':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_UnsupportedProperty' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_UnsupportedProperty'(doc) -> ["CosPropertyService_UnsupportedProperty"]; +'CosPropertyService_UnsupportedProperty'(suite) -> []; +'CosPropertyService_UnsupportedProperty'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_UnsupportedProperty':tc())), + ?match("IDL:omg.org/CosPropertyService/UnsupportedProperty:1.0", + 'CosPropertyService_UnsupportedProperty':id()), + ?match("CosPropertyService_UnsupportedProperty", + 'CosPropertyService_UnsupportedProperty':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_UnsupportedTypeCode' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_UnsupportedTypeCode'(doc) -> ["CosPropertyService_UnsupportedTypeCode"]; +'CosPropertyService_UnsupportedTypeCode'(suite) -> []; +'CosPropertyService_UnsupportedTypeCode'(_) -> + ?match(true, orber_tc:check_tc('CosPropertyService_UnsupportedTypeCode':tc())), + ?match("IDL:omg.org/CosPropertyService/UnsupportedTypeCode:1.0", + 'CosPropertyService_UnsupportedTypeCode':id()), + ?match("CosPropertyService_UnsupportedTypeCode", + 'CosPropertyService_UnsupportedTypeCode':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertyNamesIterator' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertyNamesIterator'(doc) -> ["CosPropertyService_PropertyNamesIterator"]; +'CosPropertyService_PropertyNamesIterator'(suite) -> []; +'CosPropertyService_PropertyNamesIterator'(_) -> + ?nomatch(undefined, 'CosPropertyService_PropertyNamesIterator':oe_tc(reset)), + ?nomatch(undefined, 'CosPropertyService_PropertyNamesIterator':oe_tc(next_one)), + ?nomatch(undefined, 'CosPropertyService_PropertyNamesIterator':oe_tc(next_n)), + ?nomatch(undefined, 'CosPropertyService_PropertyNamesIterator':oe_tc(destroy)), + ?match(undefined, 'CosPropertyService_PropertyNamesIterator':oe_tc(undefined)), + ?match([_|_], 'CosPropertyService_PropertyNamesIterator':oe_get_interface()), + ?match("IDL:omg.org/CosPropertyService/PropertyNamesIterator:1.0", + 'CosPropertyService_PropertyNamesIterator':typeID()), + check_tc('CosPropertyService_PropertyNamesIterator':oe_get_interface()), + ?match(true, 'CosPropertyService_PropertyNamesIterator':oe_is_a('CosPropertyService_PropertyNamesIterator':typeID())), + ?match(false, 'CosPropertyService_PropertyNamesIterator':oe_is_a("wrong")), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertiesIterator' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertiesIterator'(doc) -> ["CosPropertyService_PropertiesIterator"]; +'CosPropertyService_PropertiesIterator'(suite) -> []; +'CosPropertyService_PropertiesIterator'(_) -> + ?nomatch(undefined, 'CosPropertyService_PropertiesIterator':oe_tc(reset)), + ?nomatch(undefined, 'CosPropertyService_PropertiesIterator':oe_tc(next_one)), + ?nomatch(undefined, 'CosPropertyService_PropertiesIterator':oe_tc(next_n)), + ?nomatch(undefined, 'CosPropertyService_PropertiesIterator':oe_tc(destroy)), + ?match(undefined, 'CosPropertyService_PropertiesIterator':oe_tc(undefined)), + ?match([_|_], 'CosPropertyService_PropertiesIterator':oe_get_interface()), + ?match("IDL:omg.org/CosPropertyService/PropertiesIterator:1.0", + 'CosPropertyService_PropertiesIterator':typeID()), + check_tc('CosPropertyService_PropertiesIterator':oe_get_interface()), + ?match(true, 'CosPropertyService_PropertiesIterator':oe_is_a('CosPropertyService_PropertiesIterator':typeID())), + ?match(false, 'CosPropertyService_PropertiesIterator':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertySet' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertySet'(doc) -> ["CosPropertyService_PropertySet"]; +'CosPropertyService_PropertySet'(suite) -> []; +'CosPropertyService_PropertySet'(_) -> + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(define_property)), + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(define_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(get_number_of_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(get_all_property_names)), + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(get_property_value)), + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(get_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(get_all_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(delete_property)), + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(delete_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(delete_all_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySet':oe_tc(is_property_defined)), + ?match(undefined, 'CosPropertyService_PropertySet':oe_tc(undefined)), + ?match([_|_], 'CosPropertyService_PropertySet':oe_get_interface()), + ?match("IDL:omg.org/CosPropertyService/PropertySet:1.0", + 'CosPropertyService_PropertySet':typeID()), + check_tc('CosPropertyService_PropertySet':oe_get_interface()), + ?match(true, 'CosPropertyService_PropertySet':oe_is_a('CosPropertyService_PropertySet':typeID())), + ?match(false, 'CosPropertyService_PropertySet':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertySetDef' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertySetDef'(doc) -> ["CosPropertyService_PropertySetDef"]; +'CosPropertyService_PropertySetDef'(suite) -> []; +'CosPropertyService_PropertySetDef'(_) -> + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_allowed_property_types)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_allowed_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(define_property_with_mode)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(define_properties_with_modes)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_property_mode)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_property_modes)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(set_property_mode)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(set_property_modes)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(define_property)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(define_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_number_of_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_all_property_names)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_property_value)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(get_all_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(delete_property)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(delete_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(delete_all_properties)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDef':oe_tc(is_property_defined)), + ?match(undefined, 'CosPropertyService_PropertySetDef':oe_tc(undefined)), + ?match([_|_], 'CosPropertyService_PropertySetDef':oe_get_interface()), + ?match("IDL:omg.org/CosPropertyService/PropertySetDef:1.0", + 'CosPropertyService_PropertySetDef':typeID()), + check_tc('CosPropertyService_PropertySetDef':oe_get_interface()), + ?match(true, 'CosPropertyService_PropertySetDef':oe_is_a('CosPropertyService_PropertySetDef':typeID())), + ?match(true, 'CosPropertyService_PropertySetDef':oe_is_a('CosPropertyService_PropertySet':typeID())), + ?match(false, 'CosPropertyService_PropertySetDef':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertySetDefFactory' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertySetDefFactory'(doc) -> ["CosPropertyService_PropertySetDefFactory"]; +'CosPropertyService_PropertySetDefFactory'(suite) -> []; +'CosPropertyService_PropertySetDefFactory'(_) -> + ?nomatch(undefined, 'CosPropertyService_PropertySetDefFactory':oe_tc(create_propertysetdef)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDefFactory':oe_tc(create_constrained_propertysetdef)), + ?nomatch(undefined, 'CosPropertyService_PropertySetDefFactory':oe_tc(create_initial_propertysetdef)), + ?match(undefined, 'CosPropertyService_PropertySetDefFactory':oe_tc(undefined)), + ?match([_|_], 'CosPropertyService_PropertySetDefFactory':oe_get_interface()), + ?match("IDL:omg.org/CosPropertyService/PropertySetDefFactory:1.0", + 'CosPropertyService_PropertySetDefFactory':typeID()), + check_tc('CosPropertyService_PropertySetDefFactory':oe_get_interface()), + ?match(true, 'CosPropertyService_PropertySetDefFactory':oe_is_a('CosPropertyService_PropertySetDefFactory':typeID())), + ?match(false, 'CosPropertyService_PropertySetDefFactory':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosPropertyService_PropertySetFactory' +%% Description: +%%----------------------------------------------------------------- +'CosPropertyService_PropertySetFactory'(doc) -> ["CosPropertyService_PropertySetFactory"]; +'CosPropertyService_PropertySetFactory'(suite) -> []; +'CosPropertyService_PropertySetFactory'(_) -> + ?nomatch(undefined, 'CosPropertyService_PropertySetFactory':oe_tc(create_propertyset)), + ?nomatch(undefined, 'CosPropertyService_PropertySetFactory':oe_tc(create_constrained_propertyset)), + ?nomatch(undefined, 'CosPropertyService_PropertySetFactory':oe_tc(create_initial_propertyset)), + ?match(undefined, 'CosPropertyService_PropertySetFactory':oe_tc(undefined)), + ?match([_|_], 'CosPropertyService_PropertySetFactory':oe_get_interface()), + ?match("IDL:omg.org/CosPropertyService/PropertySetFactory:1.0", + 'CosPropertyService_PropertySetFactory':typeID()), + check_tc('CosPropertyService_PropertySetFactory':oe_get_interface()), + ?match(true, 'CosPropertyService_PropertySetFactory':oe_is_a('CosPropertyService_PropertySetFactory':typeID())), + ?match(false, 'CosPropertyService_PropertySetFactory':oe_is_a("wrong")), + ok. + + + +%%----------------------------------------------------------------- +%% MISC functions +%%----------------------------------------------------------------- +check_tc([]) -> + ok; +check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) -> + io:format("checked - ~s~n", [Op]), + lists:all(?checktc(Op), [RetType|InParameters]), + lists:all(?checktc(Op), OutParameters), + check_tc(T). + + diff --git a/lib/cosProperty/test/property_SUITE.erl b/lib/cosProperty/test/property_SUITE.erl new file mode 100644 index 0000000000..8fed3128ef --- /dev/null +++ b/lib/cosProperty/test/property_SUITE.erl @@ -0,0 +1,747 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : property_SUITE.erl +%% Description : +%% +%%---------------------------------------------------------------------- +-module(property_SUITE). + + +%%--------------- INCLUDES ----------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include_lib("cosProperty/src/cosProperty.hrl"). +-include_lib("cosProperty/include/CosPropertyService.hrl"). + +-include("test_server.hrl"). + +%%--------------- DEFINES ------------------------------------ +-define(default_timeout, ?t:minutes(20)). +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + exit(AcTuAlReS) + end + end()). + +-define(match_inverse(NotExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + NotExpectedRes -> + io:format("###### ERROR ERROR ######~n ~p~n", + [AcTuAlReS]), + exit(AcTuAlReS); + _ -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS + end + end()). + + +-define(val1, #any{typecode=tk_short, value=1}). +-define(val2, #any{typecode=tk_short, value=2}). +-define(val3, #any{typecode=tk_short, value=3}). +-define(val4, #any{typecode=tk_short, value=4}). +-define(val5, #any{typecode=tk_long, value=5}). +-define(badval, #any{typecode=tk_shirt, value=5}). + +-define(id1, "id1"). +-define(id2, "id2"). +-define(id3, "id3"). +-define(id4, "id4"). +-define(id5, "id5"). +-define(badid, ""). + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +%% Fixed exports +-export([all/1, cases/0, init_all/1, finish_all/1, + init_per_testcase/2, fin_per_testcase/2]). +%% Test cases +-export([create_setdef_api/1, create_set_api/1, define_with_mode_api/1, + define_api/1, names_iterator_api/1, properties_iterator_api/1, + app_test/1]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for the cosProperty interfaces", ""]; +all(suite) -> {req, + [mnesia, orber], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [create_setdef_api, create_set_api, define_with_mode_api, define_api, + names_iterator_api, properties_iterator_api, app_test]. + + + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + orber:jump_start(), + cosProperty:install(), + cosProperty:install_db(), + ?line ?match(ok, application:start(cosProperty)), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + application:stop(cosProperty), + cosProperty:uninstall_db(), + cosProperty:uninstall(), + orber:jump_stop(), + Config. + +%%----------------------------------------------------------------- +%% Tests app file +%%----------------------------------------------------------------- +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ok=test_server:app_test(cosProperty), + ok. + + +%%----------------------------------------------------------------- +%% CosPropertyService_PropertySetDefFactory API tests +%%----------------------------------------------------------------- +create_setdef_api(doc) -> ["CosPropertyService_PropertySetDefFactory API tests.", + ""]; +create_setdef_api(suite) -> []; +create_setdef_api(_Config) -> + + ValidDefs = [#'CosPropertyService_PropertyDef' + {property_name = ?id1, + property_value = ?val1, + property_mode = normal}, + #'CosPropertyService_PropertyDef' + {property_name = ?id2, + property_value = ?val2, + property_mode = normal}], + InvalidDefs = [#'CosPropertyService_PropertyDef' + {property_name = ?id1, + property_value = ?val1, + property_mode = normal}, + #'CosPropertyService_PropertyDef' + {property_name = ?badid, + property_value = ?badval, + property_mode = normal}], + + Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetDefFactory()), + + Obj1 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory': + create_propertysetdef(Fac)), + 'CosPropertyService_PropertySetDef_impl':dump(), + corba:dispose(Obj1), + + + Obj2 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory': + create_constrained_propertysetdef(Fac, [tk_short], ValidDefs)), + 'CosPropertyService_PropertySetDef_impl':dump(), + corba:dispose(Obj2), + + %% Both arguments correct but 'ValidDefs' contain other TC:s than + %% tk_null. + ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetDefFactory': + create_constrained_propertysetdef(Fac, [tk_null], ValidDefs)), + 'CosPropertyService_PropertySetDef_impl':dump(), + + ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetDefFactory': + create_constrained_propertysetdef(Fac, [tk_null], InvalidDefs)), + 'CosPropertyService_PropertySetDef_impl':dump(), + + %% The allowed TC not supported. + ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetDefFactory': + create_constrained_propertysetdef(Fac, [tk_noll], ValidDefs)), + 'CosPropertyService_PropertySetDef_impl':dump(), + + Obj4 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory': + create_initial_propertysetdef(Fac, ValidDefs)), + 'CosPropertyService_PropertySetDef_impl':dump(), + corba:dispose(Obj4), + + ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetDefFactory': + create_initial_propertysetdef(Fac, InvalidDefs)), + + ?match(ok, cosProperty:stop_SetDefFactory(Fac)), + + ok. + + +%%----------------------------------------------------------------- +%% CosPropertyService_PropertySetFactory API tests +%%----------------------------------------------------------------- +create_set_api(doc) -> ["CosPropertyService_PropertySetFactory API tests.", + ""]; +create_set_api(suite) -> []; +create_set_api(_Config) -> + Valid = [#'CosPropertyService_Property' + {property_name = ?id1, + property_value = ?val1}, + #'CosPropertyService_Property' + {property_name = ?id2, + property_value = ?val2}], + Invalid = [#'CosPropertyService_Property' + {property_name = ?id1, + property_value = ?val1}, + #'CosPropertyService_Property' + {property_name = ?badid, + property_value = ?badval}], + + Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetFactory()), + Obj1 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory': + create_propertyset(Fac)), + 'CosPropertyService_PropertySetDef_impl':dump(), + corba:dispose(Obj1), + + + Obj2 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory': + create_constrained_propertyset(Fac, [tk_short], Valid)), + 'CosPropertyService_PropertySetDef_impl':dump(), + corba:dispose(Obj2), + + %% Both arguments correct but 'Valid' contain other TC:s than + %% tk_null. + ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetFactory': + create_constrained_propertyset(Fac, [tk_null], Valid)), + 'CosPropertyService_PropertySetDef_impl':dump(), + + ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetFactory': + create_constrained_propertyset(Fac, [tk_null], Invalid)), + 'CosPropertyService_PropertySetDef_impl':dump(), + + %% The allowed TC not supported. + ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetFactory': + create_constrained_propertyset(Fac, [tk_noll], Valid)), + 'CosPropertyService_PropertySetDef_impl':dump(), + + Obj4 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory': + create_initial_propertyset(Fac, Valid)), + 'CosPropertyService_PropertySetDef_impl':dump(), + corba:dispose(Obj4), + + ?match({'EXCEPTION', _}, 'CosPropertyService_PropertySetFactory': + create_initial_propertyset(Fac, Invalid)), + ?match(ok, cosProperty:stop_SetFactory(Fac)), + ok. + +%%----------------------------------------------------------------- +%% CosPropertyService_PropertySetDef API tests +%%----------------------------------------------------------------- +define_api(doc) -> ["CosPropertyService_PropertySet API tests.", + ""]; +define_api(suite) -> []; +define_api(_Config) -> + ValidDefs = [#'CosPropertyService_Property' + {property_name = ?id1, + property_value = ?val1}, + #'CosPropertyService_Property' + {property_name = ?id2, + property_value = ?val2}, + #'CosPropertyService_Property' + {property_name = ?id3, + property_value = ?val3}], + + Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetFactory()), + + io:format("@@@@ Testing PropertySet returned by the factory operation create_propertyset/1 @@@@", []), + Obj = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory': + create_propertyset(Fac)), + ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj, ?id1, ?val1)), + ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj, ?id1, ?val1)), + + ?match(1, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)), + ?match(ok, 'CosPropertyService_PropertySet': + define_properties(Obj, [#'CosPropertyService_Property'{property_name = ?id2, + property_value = ?val2}, + #'CosPropertyService_Property'{property_name = ?id3, + property_value = ?val3}])), + + ?match(3, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)), + + ?match({true, [_]}, 'CosPropertyService_PropertySet':get_properties(Obj, [?id1])), + ?match({true, [_, _, _]}, 'CosPropertyService_PropertySet':get_properties(Obj, [?id1, ?id2, ?id3])), + ?match({false,[_, _, _]}, 'CosPropertyService_PropertySet':get_properties(Obj, [?id1, "wrong", ?id3])), + + ?match(?val2, 'CosPropertyService_PropertySet':get_property_value(Obj, ?id2)), + ?match(ok, 'CosPropertyService_PropertySet':delete_property(Obj, ?id1)), + + ?match(2, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)), + + ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj, ?id1, ?val1)), + ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj, ?id2, ?val2)), + ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj, ?id3, ?val3)), + + ?match(true, 'CosPropertyService_PropertySet':delete_all_properties(Obj)), + ?match(0, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)), + + ?match(ok, 'CosPropertyService_PropertySet': + define_properties(Obj, [#'CosPropertyService_Property'{property_name = ?id1, + property_value = ?val1}, + #'CosPropertyService_Property'{property_name = ?id2, + property_value = ?val2}, + #'CosPropertyService_Property'{property_name = ?id3, + property_value = ?val3}])), + + ?match(3, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)), + ?match(?val2, 'CosPropertyService_PropertySet':get_property_value(Obj, ?id2)), + + ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}}, + 'CosPropertyService_PropertySet':get_property_value(Obj, "wrongID")), + ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}}, + 'CosPropertyService_PropertySet':get_property_value(Obj, "")), + ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}}, + 'CosPropertyService_PropertySet':is_property_defined(Obj, "")), + ?match(false, 'CosPropertyService_PropertySet':is_property_defined(Obj, "wrongID")), + ?match(true, 'CosPropertyService_PropertySet':is_property_defined(Obj, ?id1)), + + %% This function is not supported by PropertySet. + ?match({'EXCEPTION',{'NO_IMPLEMENT',_,_,_}}, + 'CosPropertyService_PropertySetDef':get_property_modes(Obj, [?id1, ?id2, ?id3])), + + ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}}, + 'CosPropertyService_PropertySet':delete_properties(Obj, [?id1, ?id2, ?id3, "wrongID"])), + ?match(0, 'CosPropertyService_PropertySet':get_number_of_properties(Obj)), + corba:dispose(Obj), + + io:format("@@@@ Testing PropertySet returned by the factory operation create_constrained_propertyset/3 @@@@", []), + Obj2 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory': + create_constrained_propertyset(Fac, [tk_short], ValidDefs)), + + ?match(0, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)), + ?match({'EXCEPTION', {'CosPropertyService_UnsupportedProperty',_}}, + 'CosPropertyService_PropertySet':define_property(Obj2, ?id4, ?val4)), + ?match({'EXCEPTION', {'CosPropertyService_UnsupportedTypeCode',_}}, + 'CosPropertyService_PropertySet':define_property(Obj2, ?id1, ?val5)), + ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj2, ?id1, ?val1)), + ?match(1, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)), + ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}}, + 'CosPropertyService_PropertySet': + define_properties(Obj2, [#'CosPropertyService_Property'{property_name = ?id2, + property_value = ?val2}, + #'CosPropertyService_Property'{property_name = ?id3, + property_value = ?val3}, + #'CosPropertyService_Property'{property_name = "wrongId", + property_value = ?val2}])), + ?match(ok,'CosPropertyService_PropertySet': + define_properties(Obj2, [#'CosPropertyService_Property'{property_name = ?id2, + property_value = ?val2}, + #'CosPropertyService_Property'{property_name = ?id3, + property_value = ?val3}])), + ?match(3, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)), + ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}}, + 'CosPropertyService_PropertySet':get_property_value(Obj2, "wrongID")), + ?match(?val2, 'CosPropertyService_PropertySet':get_property_value(Obj2, ?id2)), + ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}}, + 'CosPropertyService_PropertySet':get_property_value(Obj2, "")), + ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}}, + 'CosPropertyService_PropertySet':is_property_defined(Obj2, "")), + ?match(false, 'CosPropertyService_PropertySet':is_property_defined(Obj2, "wrongID")), + ?match(true, 'CosPropertyService_PropertySet':is_property_defined(Obj2, ?id1)), + + + ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}}, + 'CosPropertyService_PropertySet':delete_property(Obj2, "wrongID")), + ?match(3, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)), + ?match(ok, 'CosPropertyService_PropertySet':delete_property(Obj2, ?id1)), + ?match(2, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)), + + ?match(ok, 'CosPropertyService_PropertySet':delete_properties(Obj2, [?id2])), + ?match(1, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)), + + ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}}, + 'CosPropertyService_PropertySet':delete_properties(Obj2, [?id3, "wrongID"])), + ?match(0, 'CosPropertyService_PropertySet':get_number_of_properties(Obj2)), + corba:dispose(Obj2), + + io:format("@@@@ Testing PropertySet returned by the factory operation create_initial_propertyset/2 @@@@", []), + Obj3 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory': + create_initial_propertyset(Fac, ValidDefs)), + ?match(3, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)), + + ?match(ok, 'CosPropertyService_PropertySet':define_property(Obj3, ?id4, ?val4)), + ?match(4, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)), + + ?match(ok,'CosPropertyService_PropertySet': + define_properties(Obj3, [#'CosPropertyService_Property'{property_name = ?id5, + property_value = ?val5}])), + + ?match(5, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)), + + ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}}, + 'CosPropertyService_PropertySet':get_property_value(Obj3, "wrongID")), + ?match(?val2, 'CosPropertyService_PropertySet':get_property_value(Obj3, ?id2)), + ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}}, + 'CosPropertyService_PropertySet':get_property_value(Obj3, "")), + ?match({'EXCEPTION',{'CosPropertyService_InvalidPropertyName',_}}, + 'CosPropertyService_PropertySet':is_property_defined(Obj3, "")), + ?match(false, 'CosPropertyService_PropertySet':is_property_defined(Obj3, "wrongID")), + ?match(true, 'CosPropertyService_PropertySet':is_property_defined(Obj3, ?id1)), + + ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}}, + 'CosPropertyService_PropertySet':delete_property(Obj3, "wrongId")), + ?match(ok, 'CosPropertyService_PropertySet':delete_property(Obj3, ?id5)), + ?match(4, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)), + + ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}}, + 'CosPropertyService_PropertySet':delete_properties(Obj3, [?id1, ?id2, ?id3, "wrongID"])), + ?match(1, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)), + + ?match(true, 'CosPropertyService_PropertySet':delete_all_properties(Obj3)), + ?match(0, 'CosPropertyService_PropertySet':get_number_of_properties(Obj3)), + + corba:dispose(Obj3), + ?match(ok, cosProperty:stop_SetFactory(Fac)), + + ok. + +%%----------------------------------------------------------------- +%% CosPropertyService_PropertySetDef API tests +%%----------------------------------------------------------------- +define_with_mode_api(doc) -> ["CosPropertyService_PropertySetDef API tests.", + ""]; +define_with_mode_api(suite) -> []; +define_with_mode_api(_Config) -> + ValidDefs = [#'CosPropertyService_PropertyDef' + {property_name = ?id1, + property_value = ?val1, + property_mode = normal}, + #'CosPropertyService_PropertyDef' + {property_name = ?id2, + property_value = ?val2, + property_mode = normal}, + #'CosPropertyService_PropertyDef' + {property_name = ?id3, + property_value = ?val3, + property_mode = normal}], + + Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetDefFactory()), + + io:format("@@@@ Testing PropertySetDef returned by the factory operation create_propertysetdef/1 @@@@", []), + Obj = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory': + create_propertysetdef(Fac)), + + %% Initally no prop's created and no restrictions at all + ?match(0, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj)), + ?match({ok, []}, 'CosPropertyService_PropertySetDef':get_allowed_property_types(Obj)), + ?match({ok, []}, 'CosPropertyService_PropertySetDef':get_allowed_properties(Obj)), + + %% Add two properties. + ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj, ?id4, ?val4, read_only)), + ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj, ?id5, ?val5, normal)), + %% Try to add the same property again (shouldn't add another since using the sam Id). + ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj, ?id5, ?val5, normal)), + + %% Try to add another identical proprty with wrong TC. + ?match({'EXCEPTION',{'CosPropertyService_ConflictingProperty',_}}, + 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj, ?id5, ?val4, normal)), + + + %% Should be two now. + ?match(2, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj)), + + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj, ?id4)), + ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj, ?id5)), + ?match(ok, 'CosPropertyService_PropertySetDef': + define_properties_with_modes(Obj, + [#'CosPropertyService_PropertyDef'{property_name = ?id1, + property_value = ?val1, + property_mode = normal}, + #'CosPropertyService_PropertyDef'{property_name = ?id2, + property_value = ?val2, + property_mode = normal}, + #'CosPropertyService_PropertyDef'{property_name = ?id3, + property_value = ?val3, + property_mode = normal}])), + %% Should be five now. + ?match(5, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj)), + ?match({true, [_,_]}, 'CosPropertyService_PropertySetDef':get_property_modes(Obj, [?id1, ?id3])), + ?match({false, [_,_,_]}, 'CosPropertyService_PropertySetDef':get_property_modes(Obj, [?id1, ?id3, "wrongID"])), + + ?match(ok, 'CosPropertyService_PropertySetDef':set_property_mode(Obj, ?id1, read_only)), + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj, ?id1)), + + ?match({'EXCEPTION',{'CosPropertyService_PropertyNotFound',_}}, + 'CosPropertyService_PropertySetDef':set_property_mode(Obj, "wrongID", read_only)), + + ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}}, + 'CosPropertyService_PropertySetDef': + set_property_modes(Obj, + [#'CosPropertyService_PropertyMode'{property_name = ?id2, + property_mode = read_only}, + #'CosPropertyService_PropertyMode'{property_name = ?id3, + property_mode = read_only}, + #'CosPropertyService_PropertyMode'{property_name = "wrongID", + property_mode = read_only}])), + ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj, ?id2)), + ?match(ok, + 'CosPropertyService_PropertySetDef': + set_property_modes(Obj, + [#'CosPropertyService_PropertyMode'{property_name = ?id2, + property_mode = read_only}, + #'CosPropertyService_PropertyMode'{property_name = ?id3, + property_mode = read_only}])), + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj, ?id2)), + + corba:dispose(Obj), + + + io:format("@@@@ Testing PropertySetDef returned by the factory operation create_constrained_propertysetdef/3 @@@@", []), + Obj2 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory': + create_constrained_propertysetdef(Fac, [tk_short], ValidDefs)), + + %% Initally no prop's created and the restrictions that only Properties eq. to ValidDefs + %% may be handled. + ?match(0, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj2)), + ?match({ok, [tk_short]}, 'CosPropertyService_PropertySetDef':get_allowed_property_types(Obj2)), + %% We cannot be sure in which order it's returned. Hmm, that's not really true but it + %% may change in the future. + ?match({ok, [_,_,_]}, 'CosPropertyService_PropertySetDef':get_allowed_properties(Obj2)), + %% Try to add a Property with and Id not eq. to ?id1, ?id2 or ?id3; must fail. + ?match({'EXCEPTION', {'CosPropertyService_UnsupportedProperty',_}}, + 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj2, ?id4, ?val4, read_only)), + %% To be sure that nothing was updated. + ?match(0, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj2)), + %% Add a valid Property. + ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj2, ?id1, ?val1, normal)), + ?match(1, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj2)), + %% Add a sequence of 1 valid and one invalid Prop's + ?match({'EXCEPTION', {'CosPropertyService_MultipleExceptions',_,_}}, + 'CosPropertyService_PropertySetDef': + define_properties_with_modes(Obj2, + [#'CosPropertyService_PropertyDef'{property_name = ?id2, + property_value = ?val2, + property_mode = normal}, + #'CosPropertyService_PropertyDef'{property_name = "wrongID", + property_value = ?val2, + property_mode = normal}])), + %% One should be added. + ?match(1, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj2)), + ?match(ok, 'CosPropertyService_PropertySetDef': + define_properties_with_modes(Obj2, + [#'CosPropertyService_PropertyDef'{property_name = ?id3, + property_value = ?val3, + property_mode = normal}])), + %% Add a sequence of 1 valid Prop. + ?match(2, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj2)), + ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id1)), + ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id3)), + + + ?match({true, [_,_]}, 'CosPropertyService_PropertySetDef':get_property_modes(Obj2, [?id1, ?id3])), + ?match({false, [_,_,_]}, 'CosPropertyService_PropertySetDef':get_property_modes(Obj2, [?id1, ?id3, "wrongID"])), + + ?match(ok, 'CosPropertyService_PropertySetDef':set_property_mode(Obj2, ?id1, read_only)), + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id1)), + ?match(ok, 'CosPropertyService_PropertySetDef': + set_property_modes(Obj2, + [#'CosPropertyService_PropertyMode'{property_name = ?id1, + property_mode = read_only}, + #'CosPropertyService_PropertyMode'{property_name = ?id3, + property_mode = read_only}])), + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id1)), + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id3)), + ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}}, + 'CosPropertyService_PropertySetDef': + set_property_modes(Obj2, + [#'CosPropertyService_PropertyMode'{property_name = ?id1, + property_mode = normal}, + #'CosPropertyService_PropertyMode'{property_name = ?id3, + property_mode = normal}, + #'CosPropertyService_PropertyMode'{property_name = "wrongID", + property_mode = normal}])), + + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id1)), + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj2, ?id3)), + corba:dispose(Obj2), + + io:format("@@@@ Testing PropertySetDef returned by the factory operation create_initial_propertysetdef/2 @@@@", []), + Obj3 = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetDefFactory': + create_initial_propertysetdef(Fac, ValidDefs)), + + %% Initally the supplied prop's are created and no restrictions. + ?match(3, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj3)), + ?match({ok, []}, 'CosPropertyService_PropertySetDef':get_allowed_property_types(Obj3)), + ?match({ok, []}, 'CosPropertyService_PropertySetDef':get_allowed_properties(Obj3)), + + %% Add a new properties an test if they have been inserted. + ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj3, ?id4, ?val4, read_only)), + ?match(4, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj3)), + ?match(ok, 'CosPropertyService_PropertySetDef':define_property_with_mode(Obj3, ?id5, ?val5, read_only)), + ?match(5, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj3)), + + %% Lookup each Property's mode. + ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id1)), + ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id2)), + ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id3)), + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id4)), + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id5)), + + ?match({true, [_,_,_,_,_]}, + 'CosPropertyService_PropertySetDef':get_property_modes(Obj3, [?id1, ?id2, ?id3, ?id4, ?id5])), + ?match({false, [_,_]}, + 'CosPropertyService_PropertySetDef':get_property_modes(Obj3, [?id1, "wrongID"])), + ?match(ok, 'CosPropertyService_PropertySetDef':set_property_mode(Obj3, ?id4, normal)), + ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id4)), + + ?match(ok, 'CosPropertyService_PropertySetDef': + set_property_modes(Obj3, + [#'CosPropertyService_PropertyMode'{property_name = ?id1, + property_mode = read_only}, + #'CosPropertyService_PropertyMode'{property_name = ?id2, + property_mode = read_only}])), + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id1)), + ?match(read_only, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id2)), + ?match({'EXCEPTION',{'CosPropertyService_MultipleExceptions',_,_}}, + 'CosPropertyService_PropertySetDef': + set_property_modes(Obj3, + [#'CosPropertyService_PropertyMode'{property_name = ?id3, + property_mode = read_only}, + #'CosPropertyService_PropertyMode'{property_name = ?id4, + property_mode = read_only}, + #'CosPropertyService_PropertyMode'{property_name = "wrongID", + property_mode = read_only}])), + + ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id3)), + ?match(normal, 'CosPropertyService_PropertySetDef':get_property_mode(Obj3, ?id4)), + + corba:dispose(Obj3), + + ?match(ok, cosProperty:stop_SetDefFactory(Fac)), + + ok. + + + +%%----------------------------------------------------------------- +%% CosPropertyService_PropertyNamesIterator API tests +%%----------------------------------------------------------------- +names_iterator_api(doc) -> ["CosPropertyService_PropertyNamesIterator API tests.", + ""]; +names_iterator_api(suite) -> []; +names_iterator_api(_Config) -> + Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetFactory()), + Obj = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory': + create_propertyset(Fac)), + ?match(ok, 'CosPropertyService_PropertySet': + define_properties(Obj, [#'CosPropertyService_Property'{property_name = ?id1, + property_value = ?val1}, + #'CosPropertyService_Property'{property_name = ?id2, + property_value = ?val2}, + #'CosPropertyService_Property'{property_name = ?id3, + property_value = ?val3}])), + + ?match(3, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj)), + {_, _,ItObj} = ?match({ok, [], _}, 'CosPropertyService_PropertySetDef':get_all_property_names(Obj, 0)), + ?match({false, [_,_,_]}, 'CosPropertyService_PropertyNamesIterator':next_n(ItObj,3)), + ?match(ok, 'CosPropertyService_PropertyNamesIterator':reset(ItObj)), + ?match({false, [_,_,_]}, 'CosPropertyService_PropertyNamesIterator':next_n(ItObj,4)), + ?match(ok, 'CosPropertyService_PropertyNamesIterator':reset(ItObj)), + ?match({true, [_]}, 'CosPropertyService_PropertyNamesIterator':next_n(ItObj,1)), + ?match({true, _}, 'CosPropertyService_PropertyNamesIterator':next_one(ItObj)), + ?match({true, _}, 'CosPropertyService_PropertyNamesIterator':next_one(ItObj)), + ?match({false, _}, 'CosPropertyService_PropertyNamesIterator':next_one(ItObj)), + ?match(ok, 'CosPropertyService_PropertyNamesIterator':destroy(ItObj)), + + corba:dispose(Obj), + ok. + +%%----------------------------------------------------------------- +%% CosPropertyService_PropertiesIterator API tests +%%----------------------------------------------------------------- +properties_iterator_api(doc) -> ["CosPropertyService_PropertiesIterator API tests.", + ""]; +properties_iterator_api(suite) -> []; +properties_iterator_api(_Config) -> + Fac = ?match({_,pseudo,_,_,_,_}, cosProperty:start_SetFactory()), + Obj = ?match({_,pseudo,_,_,_,_}, 'CosPropertyService_PropertySetFactory': + create_propertyset(Fac)), + + ?match(ok, 'CosPropertyService_PropertySet': + define_properties(Obj, [#'CosPropertyService_Property'{property_name = ?id1, + property_value = ?val1}, + #'CosPropertyService_Property'{property_name = ?id2, + property_value = ?val2}, + #'CosPropertyService_Property'{property_name = ?id3, + property_value = ?val3}])), + + ?match(3, 'CosPropertyService_PropertySetDef':get_number_of_properties(Obj)), + {_, _,ItObj} = ?match({ok, [], _}, + 'CosPropertyService_PropertySetDef':get_all_properties(Obj, 0)), + ?match({false, [_,_,_]}, 'CosPropertyService_PropertiesIterator':next_n(ItObj,3)), + ?match(ok, 'CosPropertyService_PropertiesIterator':reset(ItObj)), + ?match({false, [_,_,_]}, 'CosPropertyService_PropertiesIterator':next_n(ItObj,4)), + ?match(ok, 'CosPropertyService_PropertiesIterator':reset(ItObj)), + ?match({true, [_]}, 'CosPropertyService_PropertiesIterator':next_n(ItObj,1)), + ?match({true, {'CosPropertyService_Property',_,_}}, + 'CosPropertyService_PropertiesIterator':next_one(ItObj)), + ?match({true, {'CosPropertyService_Property',_,_}}, + 'CosPropertyService_PropertiesIterator':next_one(ItObj)), + ?match({false, {'CosPropertyService_Property',_,_}}, + 'CosPropertyService_PropertiesIterator':next_one(ItObj)), + ?match(ok, 'CosPropertyService_PropertiesIterator':destroy(ItObj)), + corba:dispose(Obj), + ok. + + +%%----------------------------------------------------------------- +%% END OF MODULE +%%----------------------------------------------------------------- diff --git a/lib/cosTime/test/Makefile b/lib/cosTime/test/Makefile new file mode 100644 index 0000000000..fde5c4facc --- /dev/null +++ b/lib/cosTime/test/Makefile @@ -0,0 +1,135 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2000-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSTIME_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/cosTime_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = cosTime.spec + + +IDL_FILES = + +IDLOUTDIR = idl_output + +MODULES = \ + time_SUITE \ + generated_SUITE + +GEN_MODULES = \ + +GEN_HRL_FILES = \ + +ERL_FILES = $(MODULES:%=%.erl) + +HRL_FILES = + +GEN_FILES = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl) + +GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR)) + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(GEN_TARGET_FILES) \ + $(SUITE_TARGET_FILES) + + +# ---------------------------------------------------- +# PROGRAMS +# ---------------------------------------------------- +LOCAL_CLASSPATH = $(ERL_TOP)lib/cosTime/priv:$(ERL_TOP)lib/cosTime/test +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosTime/ebin \ + -pa $(ERL_TOP)/lib/cosTime/src \ + -pa $(ERL_TOP)/lib/cosTime/include \ + -pa $(ERL_TOP)/lib/cosNotification/ebin \ + -pa $(ERL_TOP)/lib/orber/ebin \ + -pa $(ERL_TOP)/lib/ic/ebin + +ERL_COMPILE_FLAGS += \ + $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/orber/include \ + -pa $(ERL_TOP)/lib/cosNotification/include \ + -pa $(ERL_TOP)/internal_tools/test_server/ebin \ + -pa $(ERL_TOP)/lib/cosTime/ebin \ + -pa $(ERL_TOP)/lib/cosTime/include \ + -pa $(ERL_TOP)/lib/cosTime/test/idl_output \ + -I$(ERL_TOP)/lib/orber/include \ + -I$(ERL_TOP)/lib/cosNotification/include \ + -I$(ERL_TOP)/lib/cosTime/src \ + -I$(ERL_TOP)/lib/cosTime/include \ + -I$(ERL_TOP)/lib/cosTime \ + -I$(ERL_TOP)/lib/cosTime/test/$(IDLOUTDIR) \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + + +tests debug opt: $(TARGET_FILES) + +clean: + rm -f idl_output/* + rm -f $(TARGET_FILES) + rm -f errs core *~ + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +# We don't copy generated intermediate erlang and hrl files + +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ + $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) +# $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) +# $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ +# $(RELSYSDIR)/$(IDLOUTDIR) + diff --git a/lib/cosTime/test/cosTime.spec b/lib/cosTime/test/cosTime.spec new file mode 100644 index 0000000000..3f50946043 --- /dev/null +++ b/lib/cosTime/test/cosTime.spec @@ -0,0 +1,19 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +{topcase, {dir, "../cosTime_test"}}. diff --git a/lib/cosTime/test/generated_SUITE.erl b/lib/cosTime/test/generated_SUITE.erl new file mode 100644 index 0000000000..3a2153528f --- /dev/null +++ b/lib/cosTime/test/generated_SUITE.erl @@ -0,0 +1,288 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : generated_SUITE.erl +%% Purpose : +%%----------------------------------------------------------------- + +-module(generated_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(nomatch(Not, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + Not -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS); + _ -> + AcTuAlReS + end + end()). + + +-define(checktc(_Op), + fun(TC) -> + case orber_tc:check_tc(TC) of + false -> + io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]), + ?line exit(TC); + true -> + true + end + end). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["This suite is for testing IC generated files"]; +all(suite) -> + ['TimeBase_IntervalT', 'TimeBase_UtcT', 'CosTime_TimeUnavailable', + 'CosTimerEvent_TimerEventT', 'CosTime_TIO', 'CosTime_TimeService', + 'CosTime_UTO', 'CosTimerEvent_TimerEventHandler', + 'CosTimerEvent_TimerEventService']. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'TimeBase_IntervalT' +%% Description: +%%----------------------------------------------------------------- +'TimeBase_IntervalT'(doc) -> ["TimeBase_IntervalT"]; +'TimeBase_IntervalT'(suite) -> []; +'TimeBase_IntervalT'(_) -> + ?match(true, orber_tc:check_tc('TimeBase_IntervalT':tc())), + ?match("IDL:omg.org/TimeBase/IntervalT:1.0", + 'TimeBase_IntervalT':id()), + ?match("TimeBase_IntervalT", + 'TimeBase_IntervalT':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'TimeBase_UtcT' +%% Description: +%%----------------------------------------------------------------- +'TimeBase_UtcT'(doc) -> ["TimeBase_UtcT"]; +'TimeBase_UtcT'(suite) -> []; +'TimeBase_UtcT'(_) -> + ?match(true, orber_tc:check_tc('TimeBase_UtcT':tc())), + ?match("IDL:omg.org/TimeBase/UtcT:1.0", + 'TimeBase_UtcT':id()), + ?match("TimeBase_UtcT", + 'TimeBase_UtcT':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTime_TimeUnavailable' +%% Description: +%%----------------------------------------------------------------- +'CosTime_TimeUnavailable'(doc) -> ["CosTime_TimeUnavailable"]; +'CosTime_TimeUnavailable'(suite) -> []; +'CosTime_TimeUnavailable'(_) -> + ?match(true, orber_tc:check_tc('CosTime_TimeUnavailable':tc())), + ?match("IDL:omg.org/CosTime/TimeUnavailable:1.0", + 'CosTime_TimeUnavailable':id()), + ?match("CosTime_TimeUnavailable", + 'CosTime_TimeUnavailable':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTimerEvent_TimerEventT' +%% Description: +%%----------------------------------------------------------------- +'CosTimerEvent_TimerEventT'(doc) -> ["CosTimerEvent_TimerEventT"]; +'CosTimerEvent_TimerEventT'(suite) -> []; +'CosTimerEvent_TimerEventT'(_) -> + ?match(true, orber_tc:check_tc('CosTimerEvent_TimerEventT':tc())), + ?match("IDL:omg.org/CosTimerEvent/TimerEventT:1.0", + 'CosTimerEvent_TimerEventT':id()), + ?match("CosTimerEvent_TimerEventT", + 'CosTimerEvent_TimerEventT':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTime_TIO' +%% Description: +%%----------------------------------------------------------------- +'CosTime_TIO'(doc) -> ["CosTime_TIO"]; +'CosTime_TIO'(suite) -> []; +'CosTime_TIO'(_) -> + ?nomatch(undefined, 'CosTime_TIO':oe_tc('_get_time_interval')), + ?nomatch(undefined, 'CosTime_TIO':oe_tc(spans)), + ?nomatch(undefined, 'CosTime_TIO':oe_tc(overlaps)), + ?nomatch(undefined, 'CosTime_TIO':oe_tc(time)), + ?match(undefined, 'CosTime_TIO':oe_tc(undefined)), + ?match([_|_], 'CosTime_TIO':oe_get_interface()), + ?match("IDL:omg.org/CosTime/TIO:1.0", 'CosTime_TIO':typeID()), + check_tc('CosTime_TIO':oe_get_interface()), + ?match(true, 'CosTime_TIO':oe_is_a('CosTime_TIO':typeID())), + ?match(false, 'CosTime_TIO':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTime_TimeService' +%% Description: +%%----------------------------------------------------------------- +'CosTime_TimeService'(doc) -> ["CosTime_TimeService"]; +'CosTime_TimeService'(suite) -> []; +'CosTime_TimeService'(_) -> + ?nomatch(undefined, 'CosTime_TimeService':oe_tc(universal_time)), + ?nomatch(undefined, 'CosTime_TimeService':oe_tc(secure_universal_time)), + ?nomatch(undefined, 'CosTime_TimeService':oe_tc(new_universal_time)), + ?nomatch(undefined, 'CosTime_TimeService':oe_tc(uto_from_utc)), + ?nomatch(undefined, 'CosTime_TimeService':oe_tc(new_interval)), + ?match(undefined, 'CosTime_TimeService':oe_tc(undefined)), + ?match([_|_], 'CosTime_TimeService':oe_get_interface()), + ?match("IDL:omg.org/CosTime/TimeService:1.0", + 'CosTime_TimeService':typeID()), + check_tc('CosTime_TimeService':oe_get_interface()), + ?match(true, 'CosTime_TimeService':oe_is_a('CosTime_TimeService':typeID())), + ?match(false, 'CosTime_TimeService':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTime_UTO' +%% Description: +%%----------------------------------------------------------------- +'CosTime_UTO'(doc) -> ["CosTime_UTO"]; +'CosTime_UTO'(suite) -> []; +'CosTime_UTO'(_) -> + ?nomatch(undefined, 'CosTime_UTO':oe_tc('_get_time')), + ?nomatch(undefined, 'CosTime_UTO':oe_tc('_get_inaccuracy')), + ?nomatch(undefined, 'CosTime_UTO':oe_tc('_get_tdf')), + ?nomatch(undefined, 'CosTime_UTO':oe_tc('_get_utc_time')), + ?nomatch(undefined, 'CosTime_UTO':oe_tc(absolute_time)), + ?nomatch(undefined, 'CosTime_UTO':oe_tc(compare_time)), + ?nomatch(undefined, 'CosTime_UTO':oe_tc(time_to_interval)), + ?nomatch(undefined, 'CosTime_UTO':oe_tc(interval)), + ?match(undefined, 'CosTime_UTO':oe_tc(undefined)), + ?match([_|_], 'CosTime_UTO':oe_get_interface()), + ?match("IDL:omg.org/CosTime/UTO:1.0", 'CosTime_UTO':typeID()), + check_tc('CosTime_UTO':oe_get_interface()), + ?match(true, 'CosTime_UTO':oe_is_a('CosTime_UTO':typeID())), + ?match(false, 'CosTime_UTO':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTimerEvent_TimerEventHandler' +%% Description: +%%----------------------------------------------------------------- +'CosTimerEvent_TimerEventHandler'(doc) -> ["CosTimerEvent_TimerEventHandler"]; +'CosTimerEvent_TimerEventHandler'(suite) -> []; +'CosTimerEvent_TimerEventHandler'(_) -> + ?nomatch(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc('_get_status')), + ?nomatch(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc(time_set)), + ?nomatch(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc(set_timer)), + ?nomatch(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc(cancel_timer)), + ?nomatch(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc(set_data)), + ?match(undefined, 'CosTimerEvent_TimerEventHandler':oe_tc(undefined)), + ?match([_|_], 'CosTimerEvent_TimerEventHandler':oe_get_interface()), + ?match("IDL:omg.org/CosTimerEvent/TimerEventHandler:1.0", + 'CosTimerEvent_TimerEventHandler':typeID()), + check_tc('CosTimerEvent_TimerEventHandler':oe_get_interface()), + ?match(true, 'CosTimerEvent_TimerEventHandler':oe_is_a('CosTimerEvent_TimerEventHandler':typeID())), + ?match(false, 'CosTimerEvent_TimerEventHandler':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTimerEvent_TimerEventService' +%% Description: +%%----------------------------------------------------------------- +'CosTimerEvent_TimerEventService'(doc) -> ["CosTimerEvent_TimerEventService"]; +'CosTimerEvent_TimerEventService'(suite) -> []; +'CosTimerEvent_TimerEventService'(_) -> + ?nomatch(undefined, 'CosTimerEvent_TimerEventService':oe_tc(register)), + ?nomatch(undefined, 'CosTimerEvent_TimerEventService':oe_tc(unregister)), + ?nomatch(undefined, 'CosTimerEvent_TimerEventService':oe_tc(event_time)), + ?match(undefined, 'CosTimerEvent_TimerEventService':oe_tc(undefined)), + ?match([_|_], 'CosTimerEvent_TimerEventService':oe_get_interface()), + ?match("IDL:omg.org/CosTimerEvent/TimerEventService:1.0", + 'CosTimerEvent_TimerEventService':typeID()), + check_tc('CosTimerEvent_TimerEventService':oe_get_interface()), + ?match(true, 'CosTimerEvent_TimerEventService':oe_is_a('CosTimerEvent_TimerEventService':typeID())), + ?match(false, 'CosTimerEvent_TimerEventService':oe_is_a("wrong")), + ok. + + + + +%%----------------------------------------------------------------- +%% MISC functions +%%----------------------------------------------------------------- +check_tc([]) -> + ok; +check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) -> + io:format("checked - ~s~n", [Op]), + lists:all(?checktc(Op), [RetType|InParameters]), + lists:all(?checktc(Op), OutParameters), + check_tc(T). + + diff --git a/lib/cosTime/test/time_SUITE.erl b/lib/cosTime/test/time_SUITE.erl new file mode 100644 index 0000000000..bb00395885 --- /dev/null +++ b/lib/cosTime/test/time_SUITE.erl @@ -0,0 +1,295 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : time_SUITE.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module(time_SUITE). + + +%%--------------- INCLUDES ----------------------------------- +-include("../src/cosTimeApp.hrl"). + +-include("test_server.hrl"). + +%%--------------- DEFINES ------------------------------------ +-define(default_timeout, ?t:minutes(20)). +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + exit(AcTuAlReS) + end + end()). + +-define(match_inverse(NotExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + NotExpectedRes -> + io:format("###### ERROR ERROR ######~n ~p~n", + [AcTuAlReS]), + exit(AcTuAlReS); + _ -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS + end + end()). + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, time_api/1, timerevent_api/1, + init_per_testcase/2, fin_per_testcase/2, + app_test/1]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for the cosTime interfaces", ""]; +all(suite) -> {req, + [mnesia, orber], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [time_api, timerevent_api, app_test]. + + + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + orber:install([node()]), + application:start(mnesia), + application:start(orber), + cosNotificationApp:install_event(), + cosNotificationApp:install(), + cosTime:install_time(), + cosTime:install_timerevent(), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + cosTime:uninstall_time(), + cosTime:uninstall_timerevent(), + cosNotificationApp:uninstall(), + cosNotificationApp:uninstall_event(), + application:stop(orber), + application:stop(mnesia), + mnesia:delete_schema([node()]), + Config. + +%%----------------------------------------------------------------- +%% Tests app file +%%----------------------------------------------------------------- +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ok=test_server:app_test(cosTime), + ok. + +%%----------------------------------------------------------------- +%% CosTime API tests +%%----------------------------------------------------------------- +time_api(doc) -> ["CosTime API tests.", ""]; +time_api(suite) -> []; +time_api(_Config) -> + ?line ?match(ok, application:start(cosTime)), + TS=cosTime:start_time_service(0, 500), + Time=calendar:datetime_to_gregorian_seconds({{1582,1,1},{0,0,0}}), + Inaccuracy = 1000, + Tdf =1, + Utc = #'TimeBase_UtcT'{time=Time, inacclo = ?low_TimeT(Inaccuracy), + inacchi = ?high_TimeT(Inaccuracy), tdf = Tdf}, + ?line UTO1='CosTime_TimeService':new_universal_time(TS, Time, Inaccuracy, Tdf), + ?line UTO2='CosTime_TimeService':uto_from_utc(TS, Utc), + ?line ?match(Time, 'CosTime_UTO':'_get_time'(UTO1)), + ?line ?match(Inaccuracy, 'CosTime_UTO':'_get_inaccuracy'(UTO1)), + ?line ?match(Tdf, 'CosTime_UTO':'_get_tdf'(UTO1)), + ?line ?match(Utc, 'CosTime_UTO':'_get_utc_time'(UTO1)), + + ?line ?match(Time, 'CosTime_UTO':'_get_time'(UTO2)), + ?line ?match(Inaccuracy, 'CosTime_UTO':'_get_inaccuracy'(UTO2)), + ?line ?match(Tdf, 'CosTime_UTO':'_get_tdf'(UTO2)), + ?line ?match(Utc, 'CosTime_UTO':'_get_utc_time'(UTO2)), + + TIO1='CosTime_TimeService':new_interval(TS, 2, 5), + _TIO2='CosTime_TimeService':new_interval(TS, 3, 6), + TIO3='CosTime_TimeService':new_interval(TS, 1, 3), + TIO4='CosTime_TimeService':new_interval(TS, 3, 4), + TIO5='CosTime_TimeService':new_interval(TS, 7, 8), + TIO6='CosTime_TimeService':new_interval(TS, 2, 6), + TIO7='CosTime_TimeService':new_interval(TS, 3, 7), + + ?line {_,TIO8} = ?match({'OTContained', _}, 'CosTime_TIO':overlaps(TIO1, TIO6)), + ?line {_,TIO9} = ?match({'OTContainer', _}, 'CosTime_TIO':overlaps(TIO1, TIO1)), + ?line {_,TIO10} = ?match({'OTContainer', _}, 'CosTime_TIO':overlaps(TIO1, TIO4)), + ?line {_,TIO11} = ?match({'OTOverlap', _}, 'CosTime_TIO':overlaps(TIO1, TIO3)), + ?line {_,TIO12} = ?match({'OTOverlap', _}, 'CosTime_TIO':overlaps(TIO1, TIO7)), + ?line {_,TIO13} = ?match({'OTNoOverlap', _}, 'CosTime_TIO':overlaps(TIO1, TIO5)), + + ?line ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO8)), + ?line ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO9)), + ?line ?match({'TimeBase_IntervalT',3,4},'CosTime_TIO':'_get_time_interval'(TIO10)), + ?line ?match({'TimeBase_IntervalT',2,3},'CosTime_TIO':'_get_time_interval'(TIO11)), + ?line ?match({'TimeBase_IntervalT',3,5},'CosTime_TIO':'_get_time_interval'(TIO12)), + ?line ?match({'TimeBase_IntervalT',5,7},'CosTime_TIO':'_get_time_interval'(TIO13)), + + ?line UTO3='CosTime_TimeService':new_universal_time(TS, 4, 2, 0), %% 2-6 + ?line UTO4='CosTime_TimeService':new_universal_time(TS, 2, 1, 0), %% 1-3 + ?line UTO5='CosTime_TimeService':new_universal_time(TS, 3, 0, 0), %% 3-3 + ?line UTO6='CosTime_TimeService':new_universal_time(TS, 9, 1, 0), %% 8-10 + ?line UTO7='CosTime_TimeService':new_universal_time(TS, 4, 3, 0), %% 1-7 + ?line UTO8='CosTime_TimeService':new_universal_time(TS, 5, 2, 0), %% 3-7 + + ?line {_,TIO14} = ?match({'OTContained', _}, 'CosTime_TIO':spans(TIO1, UTO7)), + ?line {_,TIO15} = ?match({'OTContainer', _}, 'CosTime_TIO':spans(TIO1, UTO5)), + ?line {_,TIO16} = ?match({'OTOverlap', _}, 'CosTime_TIO':spans(TIO1, UTO4)), + ?line {_,TIO17} = ?match({'OTOverlap', _}, 'CosTime_TIO':spans(TIO1, UTO8)), + ?line {_,TIO18} = ?match({'OTNoOverlap', _}, 'CosTime_TIO':spans(TIO1, UTO6)), + ?line {_,TIO19} = ?match({'OTContained', _}, 'CosTime_TIO':spans(TIO1, UTO3)), + + ?line ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO14)), + ?line ?match({'TimeBase_IntervalT',3,3},'CosTime_TIO':'_get_time_interval'(TIO15)), + ?line ?match({'TimeBase_IntervalT',2,3},'CosTime_TIO':'_get_time_interval'(TIO16)), + ?line ?match({'TimeBase_IntervalT',3,5},'CosTime_TIO':'_get_time_interval'(TIO17)), + ?line ?match({'TimeBase_IntervalT',5,8},'CosTime_TIO':'_get_time_interval'(TIO18)), + ?line ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO19)), + + + cosTime:stop_time_service(TS), + application:stop(cosTime), + ok. + + +%%----------------------------------------------------------------- +%% CosTimerEvent API tests +%%----------------------------------------------------------------- +timerevent_api(doc) -> ["CosTimerEvent API tests.", ""]; +timerevent_api(suite) -> []; +timerevent_api(_Config) -> + %% Init cosTime apps. + ?line ?match(ok, application:start(cosTime)), + ?line TS=cosTime:start_time_service(0, 500), + ?line TES=cosTime:start_timerevent_service(TS), + + %%----- Initialize the cosNotification application. ----- + ?line cosNotificationApp:start(), + ?line Fac = (catch cosNotificationApp:start_factory([])), + ?line {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, [], [])), + %% Create the Admin objects + ?line {AdminSupplier, _ASID}= ?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'OR_OP')), + ?line {AdminConsumer, _ACID}= ?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'OR_OP')), + + %% Create a push consumer TimerEventService will push events to. + ?line {ProxyPushConsumer,_ID10}= ?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'ANY_EVENT')), + + %% Create a pull suppliers so we can check we actually got the event. + ?line {ProxyPullSupplier,_ID1} = ?match({{_,key,_,_,_,_},_}, + 'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'ANY_EVENT')), + + AnyEvent = any:create(orber_tc:long(), 100), + ?line UTO=?match({_,pseudo,_,_,_,_}, 'CosTime_TimeService':new_universal_time(TS, 10*10000000,1,1)), + ?line EH=?match({_,key,_,_,_,_}, 'CosTimerEvent_TimerEventService':register(TES, ProxyPushConsumer, AnyEvent)), + + ?line ?match('ESTimeCleared','CosTimerEvent_TimerEventHandler':'_get_status'(EH)), + ?line ?match({false,_},'CosTimerEvent_TimerEventHandler':time_set(EH)), + ?line ?match(ok,'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTRelative', UTO)), + ?line ?match({true,_},'CosTimerEvent_TimerEventHandler':time_set(EH)), + ?line ?match('ESTimeSet','CosTimerEvent_TimerEventHandler':'_get_status'(EH)), + + ?line ?match({{any,tk_null,null}, false}, + 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)), + + ?line ?match(AnyEvent, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(ProxyPullSupplier)), + ?line ?match('ESTriggered','CosTimerEvent_TimerEventHandler':'_get_status'(EH)), + + %% It's allowed to send an UTO with time eq. to 0 if the server is TTRelative. + %% When TTAbsolute BAD_PARAM is raised. + ?line UTO2=?match({_,pseudo,_,_,_,_}, 'CosTime_TimeService':new_universal_time(TS, 0,1,1)), + ?line ?match({'EXCEPTION',_},'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTAbsolute', UTO2)), + ?line ?match(ok,'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTRelative', UTO2)), + ?line ?match(AnyEvent, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(ProxyPullSupplier)), + + %% TTPeriodic is defined to be relative, i.e., we can use the tactic as above. + ?line ?match(ok,'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTPeriodic', UTO2)), + + %% Sleep for UTO*2+4 secs. At this point the Timer should have delivered 2 events. + timer:sleep(24000), + %% Cancel the timer so no more events will be delivered. + ?line ?match(true,'CosTimerEvent_TimerEventHandler':cancel_timer(EH)), + + ?line ?match({AnyEvent, true}, 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)), + ?line ?match({AnyEvent, true}, 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)), + ?line ?match({{any,tk_null,null}, false}, + 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)), + + + + %% Clean up. + cosNotificationApp:stop(), + cosTime:stop_timerevent_service(TES), + cosTime:stop_time_service(TS), + application:stop(cosTime), + ok. + + diff --git a/lib/cosTransactions/test/Makefile b/lib/cosTransactions/test/Makefile new file mode 100644 index 0000000000..8b1264d404 --- /dev/null +++ b/lib/cosTransactions/test/Makefile @@ -0,0 +1,150 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1999-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +#ifeq ($(TYPE),debug) +#ERL_COMPILE_FLAGS += -Ddebug -W +#endif + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSTRANSACTIONS_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/cosTransactions_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = cosTransactions.spec + + +IDL_FILES = \ + etrap_test.idl + +IDLOUTDIR = idl_output + +MODULES = \ + transactions_SUITE \ + etrap_test_server_impl \ + etrap_test_lib \ + generated_SUITE + +GEN_MODULES = \ + oe_etrap_test \ + etrap_test_server + +GEN_HRL_FILES = \ + oe_etrap_test.hrl \ + etrap_test_server.hrl + +ERL_FILES = $(MODULES:%=%.erl) + +HRL_FILES = \ + etrap_test_lib.hrl + +GEN_FILES = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl) + +GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR)) + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(GEN_TARGET_FILES) \ + $(SUITE_TARGET_FILES) + + +# ---------------------------------------------------- +# PROGRAMS +# ---------------------------------------------------- +LOCAL_CLASSPATH = $(ERL_TOP)/lib/cosTransactions/priv:$(ERL_TOP)/lib/cosTransactions/test +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosTransactions/ebin\ + -pa $(ERL_TOP)/lib/orber/ebin \ + -pa $(ERL_TOP)/lib/ic/ebin + +ERL_COMPILE_FLAGS += \ + $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/orber/include \ + -pa $(ERL_TOP)/lib/test_server/ebin \ + -pa $(ERL_TOP)/lib/cosTransactions/ebin \ + -pa $(ERL_TOP)/lib/cosTransactions/test/idl_output \ + -I$(ERL_TOP)/lib/orber/include \ + -I$(ERL_TOP)/lib/cosTransactions \ + -I$(ERL_TOP)/lib/cosTransactions/test/$(IDLOUTDIR) \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + + +tests debug opt: $(TARGET_FILES) + +clean: + rm -f idl_output/* + rm -f $(TARGET_FILES) + rm -f errs core *~ + +#debug: +# @${MAKE} TYPE=debug + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + +TGT_TEST = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl) + +$(TGT_TEST): etrap_test.idl + erlc $(ERL_IDL_FLAGS) -o$(IDLOUTDIR) \ + +'{cfgfile,"etrap_test.cfg"}' etrap_test.idl + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +# We don't copy generated intermediate erlang and hrl files + +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ + $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) + $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ + $(RELSYSDIR)/$(IDLOUTDIR) + diff --git a/lib/cosTransactions/test/cosTransactions.spec b/lib/cosTransactions/test/cosTransactions.spec new file mode 100644 index 0000000000..8ad9259964 --- /dev/null +++ b/lib/cosTransactions/test/cosTransactions.spec @@ -0,0 +1,19 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +{topcase, {dir, "../cosTransactions_test"}}. diff --git a/lib/cosTransactions/test/etrap_test.cfg b/lib/cosTransactions/test/etrap_test.cfg new file mode 100644 index 0000000000..4f2b9e125d --- /dev/null +++ b/lib/cosTransactions/test/etrap_test.cfg @@ -0,0 +1,20 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +{this, "etrap_test::server"}. +{{handle_info, "etrap_test::server"}, true}. diff --git a/lib/cosTransactions/test/etrap_test.idl b/lib/cosTransactions/test/etrap_test.idl new file mode 100644 index 0000000000..7573cc1a36 --- /dev/null +++ b/lib/cosTransactions/test/etrap_test.idl @@ -0,0 +1,38 @@ +// +// %CopyrightBegin% +// +// Copyright Ericsson AB 1999-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// + +#ifndef _TEST_IDL +#define _TEST_IDL +#include <../src/CosTransactions.idl> +module etrap_test { + + // interface server + interface server : + CosTransactions::Coordinator, CosTransactions::SubtransactionAwareResource, + CosTransactions::RecoveryCoordinator, CosTransactions::Control { + }; +// interface Server : +// CosTransactions::Coordinator, CosTransactions::SubtransactionAwareResource, +// CosTransactions::RecoveryCoordinator, CosTransactions::Control, +// CosTransactions::Synchronization { +// }; + +}; // End of test Module + +#endif diff --git a/lib/cosTransactions/test/etrap_test_lib.erl b/lib/cosTransactions/test/etrap_test_lib.erl new file mode 100644 index 0000000000..913a94510f --- /dev/null +++ b/lib/cosTransactions/test/etrap_test_lib.erl @@ -0,0 +1,125 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(etrap_test_lib). + +%%--------------- INCLUDES --------------------------------------------- +-include("etrap_test_lib.hrl"). +-include_lib("cosTransactions/src/ETraP_Common.hrl"). + +%%--------------- EXPORTS ---------------------------------------------- +-export([scratch_debug_fun/0, + activate_debug_fun/5, + update_debug_info/1, + deactivate_debug_fun/3, + eval_debug_fun/4, + set_debug_context/4]). + +%%--------------- CONSTANTS/DEFINITIONS -------------------------------- +-define(DEBUG_TAB, etrap_debug). +-record(debug_info, {id, function, type, file, line}). + +%%--------------- DEBUG FUNCTIONS -------------------------------------- +%% Managing conditional debug functions +%% +%% The main idea with the debug_fun's is to allow test programs +%% to control the internal behaviour of CosTransactions. +%% +%% First should calls to ?eval_debug_fun be inserted at well +%% defined places in CosTransaction's code. E.g. in critical situations +%% of startup, transaction commit, backups etc. +%% +%% Then compile CosTransactions with the compiler option 'debug'. +%% +%% In test programs ?activate_debug_fun should be called +%% in order to bind a fun to the debug identifier stated +%% in the call to ?eval_debug_fun. + +scratch_debug_fun() -> + catch ets:delete(?DEBUG_TAB), + ets:new(?DEBUG_TAB, + [set, public, named_table, {keypos, 2}]). + +activate_debug_fun(FunId, Fun, Type, File, Line) -> + io:format("Activiating ~p RETRIES: ~p WAIT: ~p~n", + [FunId, ?tr_max_retries, ?tr_comm_failure_wait]), + Info = #debug_info{id = FunId, + function = Fun, + type = Type, + file = File, + line = Line}, + update_debug_info(Info). + +update_debug_info(Info) -> + case catch ets:insert(?DEBUG_TAB, Info) of + {'EXIT', _} -> + scratch_debug_fun(), + ets:insert(?DEBUG_TAB, Info); + _ -> + ok + end, + ok. + +deactivate_debug_fun(FunId, _File, _Line) -> + catch ets:delete(?DEBUG_TAB, FunId), + ok. + +eval_debug_fun(FunId, Env, File, Line) -> + case catch ets:lookup(?DEBUG_TAB, FunId) of + [] -> + ok; + [Info] -> + Fun = Info#debug_info.function, + case Info#debug_info.type of + transient -> + deactivate_debug_fun(FunId, File, Line); + _-> + ok + end, + io:format("Running debug fun ~p:~p (LINE: ~p)~n", [File, FunId, Line]), + Fun(Env); + {'EXIT', _R} -> + ok + end. + + +set_debug_context([], [], _, _)-> ok; +set_debug_context([], _, _, _)-> + ets:delete(?DEBUG_TAB), + exit("failed transactions_SUITE. Bad configuration."); +set_debug_context(_, [], _, _)-> + ets:delete(?DEBUG_TAB), + exit("failed transactions_SUITE Bad configuration."); +set_debug_context([RHead|RTail], [CHead|CTail], File, Line)-> + write_context(RHead, CHead, File, Line), + set_debug_context(RTail, CTail, File, Line). + +write_context(_Resource, [], _, _)-> ok; +write_context(Resource, [{Func, Fun, Type}|PTail], File, Line)-> + etrap_test_lib:activate_debug_fun({Resource, Func}, + Fun, Type, + File, Line), + write_context(Resource, PTail, File, Line); +write_context(_,_, _, _) -> + ets:delete(?DEBUG_TAB), + exit("failed transactions_SUITE. Bad configuration."). + + +%%--------------- END OF MODULE ---------------------------------------- diff --git a/lib/cosTransactions/test/etrap_test_lib.hrl b/lib/cosTransactions/test/etrap_test_lib.hrl new file mode 100644 index 0000000000..d488bf9d12 --- /dev/null +++ b/lib/cosTransactions/test/etrap_test_lib.hrl @@ -0,0 +1,100 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-ifndef(ETRAP_TEST_LIB_HRL). +-define(ETRAP_TEST_LIB_HRL, true). + +-define(match(ExpectedRes, Expr, Msg), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("~n------ CORRECT RESULT ------~n~p~n~p~n", + [AcTuAlReS, Msg]), + ok; + _ -> + io:format("~n###### ERROR ERROR ######~n~p~n~p~n", + [AcTuAlReS, Msg]), + exit(AcTuAlReS) + end + end()). + +-define(match_inverse(NotExpectedRes, Expr, Msg), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + NotExpectedRes -> + io:format("~n###### ERROR ERROR ######~n ~p~n~p~n", + [AcTuAlReS, Msg]), + exit(AcTuAlReS); + _ -> + io:format("~n------ CORRECT RESULT ------~n~p~n~p~n", + [AcTuAlReS, Msg]), + ok + end + end()). + + +-define(crash_and_recover, fun(_Env)-> exit(crash_and_burn) end). + +-define(crash_no_recovery, fun(Env)-> throw({stop,normal,{Env,state}}) end). + +-define(delay(Time), fun(_Id) -> timer:sleep(Time*1000) end). + +-define(TIMEOUT, 4). +-define(SUP_TEST(Env, Name), + ['etrap_test_server', Env, + [{sup_child, true}, {persistent, true}, + {regname, {global, Name}}]]). + +-define(no_context, [[],[],[], []]). +-define(nop, []). +-define(delay_transient(Tag, Ti), + [{Tag, ?delay(Ti), transient}]). +-define(crash_transient(Tag), + [{Tag, ?crash_and_recover, transient}]). +-define(crash_permanent(Tag), + [{Tag, ?crash_no_recovery, permanent}]). + +%%----------------------------------------------------------- +%% Definition of 'Resource' action. +%% function action reply +%%----------------------------------------------------------- +%% raise #'CosTransactions_HeuristicMixed' {} +-define(rollback_mix, [{rollback, exc, ?tr_mixed}]). +-define(commit_mix, [{commit, exc, ?tr_mixed}]). +-define(prepare_mix, [{prepare, exc, ?tr_mixed}]). +%% raise #'CosTransactions_HeuristicRollback' {} +-define(rollback_rb, [{rollback, exc, ?tr_rollback}]). +-define(commit_rb, [{commit, exc, ?tr_rollback}]). +%% raise #'CosTransactions_HeuristicCommit' {} +-define(rollback_cm, [{rollback, exc, ?tr_commit}]). +-define(commit_cm, [{commit, exc, ?tr_commit}]). +%% delay reply +-define(rollback_delay, [{rollback, delay, ?TIMEOUT*2}]). +-define(commit_delay, [{commit, delay, ?TIMEOUT*2}]). +-define(prepare_delay, [{prepare, delay, ?TIMEOUT*2}]). +%% other reply than default +-define(prepare_commit, [{prepare, reply, 'VoteCommit'}]). +-define(prepare_rollback, [{prepare, stop_reply, 'VoteRollback'}]). + +-endif. + +%%-------------- EOF --------------------------------------------------- diff --git a/lib/cosTransactions/test/etrap_test_server_impl.erl b/lib/cosTransactions/test/etrap_test_server_impl.erl new file mode 100644 index 0000000000..69c823f3ca --- /dev/null +++ b/lib/cosTransactions/test/etrap_test_server_impl.erl @@ -0,0 +1,210 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(etrap_test_server_impl). + +%%--------------- INCLUDES ----------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/include/ifr_types.hrl"). +%% Local +-include_lib("cosTransactions/src/ETraP_Common.hrl"). +-include_lib("cosTransactions/include/CosTransactions.hrl"). +%%--------------- IMPORTS------------------------------------- +%%--------------- EXPORTS------------------------------------- +-export([prepare/2, + rollback/2, + commit/2, + commit_one_phase/2, + forget/2, +% before_completion/2, +% after_completion/3, + commit_subtransaction/3, + rollback_subtransaction/2]). + + +%%--------------- gen_server specific ------------------------ +-export([init/1, terminate/2]). +-export([handle_call/3, handle_cast/2, handle_info/2, code_change/3]). + +%%------------------------------------------------------------ +%% function : init, terminate +%%------------------------------------------------------------ +init(State) -> + process_flag(trap_exit,true), + io:format("etrap_test_server:init ~p~n", [State]), + ?debug_print("STARTING etrap_test_server( ~p )~n", [State]), + {ok, State}. + +terminate(Reason, _State) -> + io:format("etrap_test_server:terminate ~p~n", [Reason]), + ?debug_print("STOPREASON etrap_test_server( ~p )~n", [Reason]), + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. +handle_call(_,_, State) -> + {noreply, State}. +handle_cast(_, State) -> + {noreply, State}. +handle_info(_Info, State) -> + {noreply, State}. + +%%-- Inherit from CosTransactions::SubtransactionAwareResource -- +prepare(_Self, State) -> + case ?is_debug_compiled of + true -> + io:format("etrap_test_server:prepare ~p~n", [State]); + _-> + ok + end, +% ?debug_print("etrap_test_server:prepare ~p~n", [State]), + action(prepare, State, {reply, 'VoteCommit', State}). + +rollback(_Self, State) -> + case ?is_debug_compiled of + true -> + io:format("etrap_test_server:rollback ~p~n", [State]); + _-> + ok + end, +% ?debug_print("etrap_test_server:rollback ~p~n", [State]), + case sync_test(State) of + true -> + action(rollback, State, {reply, ok, State}); + _-> + action(rollback, State, {stop, normal, ok, State}) + end. + +commit(_Self, State) -> + case ?is_debug_compiled of + true -> + io:format("etrap_test_server:commit ~p~n", [State]); + _-> + ok + end, +% ?debug_print("etrap_test_server:commit ~p~n", [State]), + case sync_test(State) of + true -> + action(commit, State, {reply, ok, State}); + _-> + action(commit, State, {stop, normal, ok, State}) + end. + +commit_one_phase(_Self, State) -> + case ?is_debug_compiled of + true -> + io:format("etrap_test_server:commit_one_phase ~p~n", [State]); + _-> + ok + end, +% ?debug_print("etrap_test_server:commit_one_phase ~p~n", [State]), + case sync_test(State) of + true -> + {reply, ok, State}; + _-> + {stop, normal, ok, State} + end. + +forget(_Self, State) -> + case ?is_debug_compiled of + true -> + io:format("etrap_test_server:forget ~p~n", [State]); + _-> + ok + end, +% ?debug_print("etrap_test_server:forget ~p~n", [State]), + case sync_test(State) of + true -> + {reply, ok, State}; + _-> + {stop, normal, ok, State} + end. + +commit_subtransaction(_Self, State, Parent) -> + case ?is_debug_compiled of + true -> + io:format("etrap_test_server:commit_subtransaction( ~p )~n", [Parent]); + _-> + ok + end, +% ?debug_print("etrap_test_server:commit_subtransaction( ~p )~n", [Parent]), + {reply, ok, State}. +rollback_subtransaction(_Self, State) -> + case ?is_debug_compiled of + true -> + io:format("etrap_test_server:rollback_subtransaction()~n", []); + _-> + ok + end, +% ?debug_print("etrap_test_server:rollback_subtransaction()~n", []), + {reply, ok, State}. + +%before_completion(_Self, State) -> +% case ?is_debug_compiled of +% true -> +% io:format("etrap_test_server:before_completion()~n", []); +% _-> +% ok +% end, +%% ?debug_print("etrap_test_server:before_completion()~n", []), +% {reply, ok, State}. +%after_completion(_Self, State, Status) -> +% case ?is_debug_compiled of +% true -> +% io:format("etrap_test_server:after_completion( ~p )~n", [Status]); +% _-> +% ok +% end, +%% ?debug_print("etrap_test_server:after_completion( ~p )~n", [Status]), +% {stop, normal, ok, State}. + +%%--------------- LOCAL FUNCTIONS ---------------------------- +action(Key, State, Default) -> + case catch lists:keysearch(Key, 1, State) of + {value,{Key, stop_reply, R}} -> + case sync_test(State) of + true -> + {reply, R, State}; + _-> + {stop, normal, R, State} + end; + {value,{Key, reply, R}} -> + {reply, R, State}; + {value,{Key, exc, E}} -> + corba:raise(E); + {value,{Key, delay, Time}} -> + timer:sleep(Time*1000), + Default; + {value,{Key,Value}} -> + Value; + _ -> + Default + end. + +sync_test(State) -> + case catch lists:keysearch(sync, 1, State) of + {value,{sync, true}} -> + true; + _ -> + false + end. + + +%%--------------- END OF MODULE ------------------------------ + diff --git a/lib/cosTransactions/test/generated_SUITE.erl b/lib/cosTransactions/test/generated_SUITE.erl new file mode 100644 index 0000000000..cc54eb168e --- /dev/null +++ b/lib/cosTransactions/test/generated_SUITE.erl @@ -0,0 +1,564 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : generated_SUITE.erl +%% Purpose : +%% Created : 27 Jan 2004 +%%----------------------------------------------------------------- + +-module(generated_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(nomatch(Not, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + Not -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS); + _ -> + AcTuAlReS + end + end()). + + +-define(checktc(_Op), + fun(TC) -> + case orber_tc:check_tc(TC) of + false -> + io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]), + ?line exit(TC); + true -> + true + end + end). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["This suite is for testing IC generated files"]; +all(suite) -> + ['CosTransactions_Control', 'CosTransactions_Coordinator', + 'CosTransactions_HeuristicCommit', 'CosTransactions_HeuristicHazard', + 'CosTransactions_HeuristicMixed', 'CosTransactions_HeuristicRollback', + 'CosTransactions_Inactive', 'CosTransactions_InvalidControl', + 'CosTransactions_NoTransaction', 'CosTransactions_NotPrepared', + 'CosTransactions_NotSubtransaction', 'CosTransactions_RecoveryCoordinator', + 'CosTransactions_Resource', 'CosTransactions_SubtransactionAwareResource', + 'CosTransactions_SubtransactionsUnavailable', 'CosTransactions_Terminator', + 'CosTransactions_TransactionFactory', 'CosTransactions_Unavailable', + 'CosTransactions_SynchronizationUnavailable', 'CosTransactions_TransIdentity', + 'CosTransactions_PropagationContext', 'CosTransactions_otid_t', + 'CosTransactions_WrongTransaction', 'ETraP_Server']. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_HeuristicCommit' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_HeuristicCommit'(doc) -> ["CosTransactions_HeuristicCommit"]; +'CosTransactions_HeuristicCommit'(suite) -> []; +'CosTransactions_HeuristicCommit'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_HeuristicCommit':tc())), + ?match("IDL:omg.org/CosTransactions/HeuristicCommit:1.0", + 'CosTransactions_HeuristicCommit':id()), + ?match("CosTransactions_HeuristicCommit", + 'CosTransactions_HeuristicCommit':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_HeuristicHazard' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_HeuristicHazard'(doc) -> ["CosTransactions_HeuristicHazard"]; +'CosTransactions_HeuristicHazard'(suite) -> []; +'CosTransactions_HeuristicHazard'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_HeuristicHazard':tc())), + ?match("IDL:omg.org/CosTransactions/HeuristicHazard:1.0", + 'CosTransactions_HeuristicHazard':id()), + ?match("CosTransactions_HeuristicHazard", + 'CosTransactions_HeuristicHazard':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_HeuristicMixed' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_HeuristicMixed'(doc) -> ["CosTransactions_HeuristicMixed"]; +'CosTransactions_HeuristicMixed'(suite) -> []; +'CosTransactions_HeuristicMixed'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_HeuristicMixed':tc())), + ?match("IDL:omg.org/CosTransactions/HeuristicMixed:1.0", + 'CosTransactions_HeuristicMixed':id()), + ?match("CosTransactions_HeuristicMixed", + 'CosTransactions_HeuristicMixed':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_HeuristicRollback' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_HeuristicRollback'(doc) -> ["CosTransactions_HeuristicRollback"]; +'CosTransactions_HeuristicRollback'(suite) -> []; +'CosTransactions_HeuristicRollback'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_HeuristicRollback':tc())), + ?match("IDL:omg.org/CosTransactions/HeuristicRollback:1.0", + 'CosTransactions_HeuristicRollback':id()), + ?match("CosTransactions_HeuristicRollback", + 'CosTransactions_HeuristicRollback':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_Inactive' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_Inactive'(doc) -> ["CosTransactions_Inactive"]; +'CosTransactions_Inactive'(suite) -> []; +'CosTransactions_Inactive'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_Inactive':tc())), + ?match("IDL:omg.org/CosTransactions/Inactive:1.0", + 'CosTransactions_Inactive':id()), + ?match("CosTransactions_Inactive", + 'CosTransactions_Inactive':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_InvalidControl' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_InvalidControl'(doc) -> ["CosTransactions_InvalidControl"]; +'CosTransactions_InvalidControl'(suite) -> []; +'CosTransactions_InvalidControl'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_InvalidControl':tc())), + ?match("IDL:omg.org/CosTransactions/InvalidControl:1.0", + 'CosTransactions_InvalidControl':id()), + ?match("CosTransactions_InvalidControl", + 'CosTransactions_InvalidControl':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_NoTransaction' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_NoTransaction'(doc) -> ["CosTransactions_NoTransaction"]; +'CosTransactions_NoTransaction'(suite) -> []; +'CosTransactions_NoTransaction'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_NoTransaction':tc())), + ?match("IDL:omg.org/CosTransactions/NoTransaction:1.0", + 'CosTransactions_NoTransaction':id()), + ?match("CosTransactions_NoTransaction", + 'CosTransactions_NoTransaction':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_NotPrepared' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_NotPrepared'(doc) -> ["CosTransactions_NotPrepared"]; +'CosTransactions_NotPrepared'(suite) -> []; +'CosTransactions_NotPrepared'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_NotPrepared':tc())), + ?match("IDL:omg.org/CosTransactions/NotPrepared:1.0", + 'CosTransactions_NotPrepared':id()), + ?match("CosTransactions_NotPrepared", + 'CosTransactions_NotPrepared':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_NotSubtransaction' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_NotSubtransaction'(doc) -> ["CosTransactions_NotSubtransaction"]; +'CosTransactions_NotSubtransaction'(suite) -> []; +'CosTransactions_NotSubtransaction'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_NotSubtransaction':tc())), + ?match("IDL:omg.org/CosTransactions/NotSubtransaction:1.0", + 'CosTransactions_NotSubtransaction':id()), + ?match("CosTransactions_NotSubtransaction", + 'CosTransactions_NotSubtransaction':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_SubtransactionsUnavailable' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_SubtransactionsUnavailable'(doc) -> ["CosTransactions_SubtransactionsUnavailable"]; +'CosTransactions_SubtransactionsUnavailable'(suite) -> []; +'CosTransactions_SubtransactionsUnavailable'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_SubtransactionsUnavailable':tc())), + ?match("IDL:omg.org/CosTransactions/SubtransactionsUnavailable:1.0", + 'CosTransactions_SubtransactionsUnavailable':id()), + ?match("CosTransactions_SubtransactionsUnavailable", + 'CosTransactions_SubtransactionsUnavailable':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_Unavailable' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_Unavailable'(doc) -> ["CosTransactions_Unavailable"]; +'CosTransactions_Unavailable'(suite) -> []; +'CosTransactions_Unavailable'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_Unavailable':tc())), + ?match("IDL:omg.org/CosTransactions/Unavailable:1.0", + 'CosTransactions_Unavailable':id()), + ?match("CosTransactions_Unavailable", + 'CosTransactions_Unavailable':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_SynchronizationUnavailable' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_SynchronizationUnavailable'(doc) -> ["CosTransactions_SynchronizationUnavailable"]; +'CosTransactions_SynchronizationUnavailable'(suite) -> []; +'CosTransactions_SynchronizationUnavailable'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_SynchronizationUnavailable':tc())), + ?match("IDL:omg.org/CosTransactions/SynchronizationUnavailable:1.0", + 'CosTransactions_SynchronizationUnavailable':id()), + ?match("CosTransactions_SynchronizationUnavailable", + 'CosTransactions_SynchronizationUnavailable':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_TransIdentity' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_TransIdentity'(doc) -> ["CosTransactions_TransIdentity"]; +'CosTransactions_TransIdentity'(suite) -> []; +'CosTransactions_TransIdentity'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_TransIdentity':tc())), + ?match("IDL:omg.org/CosTransactions/TransIdentity:1.0", + 'CosTransactions_TransIdentity':id()), + ?match("CosTransactions_TransIdentity", + 'CosTransactions_TransIdentity':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_PropagationContext' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_PropagationContext'(doc) -> ["CosTransactions_PropagationContext"]; +'CosTransactions_PropagationContext'(suite) -> []; +'CosTransactions_PropagationContext'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_PropagationContext':tc())), + ?match("IDL:omg.org/CosTransactions/PropagationContext:1.0", + 'CosTransactions_PropagationContext':id()), + ?match("CosTransactions_PropagationContext", + 'CosTransactions_PropagationContext':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_otid_t' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_otid_t'(doc) -> ["CosTransactions_otid_t"]; +'CosTransactions_otid_t'(suite) -> []; +'CosTransactions_otid_t'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_otid_t':tc())), + ?match("IDL:omg.org/CosTransactions/otid_t:1.0", + 'CosTransactions_otid_t':id()), + ?match("CosTransactions_otid_t", + 'CosTransactions_otid_t':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_WrongTransaction' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_WrongTransaction'(doc) -> ["CosTransactions_WrongTransaction"]; +'CosTransactions_WrongTransaction'(suite) -> []; +'CosTransactions_WrongTransaction'(_) -> + ?match(true, orber_tc:check_tc('CosTransactions_WrongTransaction':tc())), + ?match("IDL:omg.org/CosTransactions/WrongTransaction:1.0", + 'CosTransactions_WrongTransaction':id()), + ?match("CosTransactions_WrongTransaction", + 'CosTransactions_WrongTransaction':name()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_Control' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_Control'(doc) -> ["CosTransactions_Control"]; +'CosTransactions_Control'(suite) -> []; +'CosTransactions_Control'(_) -> + ?nomatch(undefined, 'CosTransactions_Control':oe_tc(get_terminator)), + ?nomatch(undefined, 'CosTransactions_Control':oe_tc(get_coordinator)), + ?match(undefined, 'CosTransactions_Control':oe_tc(undefined)), + ?match([_|_], 'CosTransactions_Control':oe_get_interface()), + ?match("IDL:omg.org/CosTransactions/Control:1.0", + 'CosTransactions_Control':typeID()), + check_tc('CosTransactions_Control':oe_get_interface()), + ?match(true, 'CosTransactions_Control':oe_is_a('CosTransactions_Control':typeID())), + ?match(false, 'CosTransactions_Control':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_Coordinator' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_Coordinator'(doc) -> ["CosTransactions_Coordinator"]; +'CosTransactions_Coordinator'(suite) -> []; +'CosTransactions_Coordinator'(_) -> + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(get_status)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(get_parent_status)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(get_top_level_status)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(is_same_transaction)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(is_related_transaction)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(is_ancestor_transaction)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(is_descendant_transaction)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(is_top_level_transaction)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(hash_transaction)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(hash_top_level_tran)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(register_resource)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(register_subtran_aware)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(rollback_only)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(get_transaction_name)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(create_subtransaction)), + ?nomatch(undefined, 'CosTransactions_Coordinator':oe_tc(get_txcontext)), + ?match(undefined, 'CosTransactions_Coordinator':oe_tc(undefined)), + ?match([_|_], 'CosTransactions_Coordinator':oe_get_interface()), + ?match("IDL:omg.org/CosTransactions/Coordinator:1.0", + 'CosTransactions_Coordinator':typeID()), + check_tc('CosTransactions_Coordinator':oe_get_interface()), + ?match(true, 'CosTransactions_Coordinator':oe_is_a('CosTransactions_Coordinator':typeID())), + ?match(false, 'CosTransactions_Coordinator':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_RecoveryCoordinator' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_RecoveryCoordinator'(doc) -> ["CosTransactions_RecoveryCoordinator"]; +'CosTransactions_RecoveryCoordinator'(suite) -> []; +'CosTransactions_RecoveryCoordinator'(_) -> + ?nomatch(undefined, 'CosTransactions_RecoveryCoordinator':oe_tc(replay_completion)), + ?match(undefined, 'CosTransactions_RecoveryCoordinator':oe_tc(undefined)), + ?match([_|_], 'CosTransactions_RecoveryCoordinator':oe_get_interface()), + ?match("IDL:omg.org/CosTransactions/RecoveryCoordinator:1.0", + 'CosTransactions_RecoveryCoordinator':typeID()), + check_tc('CosTransactions_RecoveryCoordinator':oe_get_interface()), + ?match(true, 'CosTransactions_RecoveryCoordinator':oe_is_a('CosTransactions_RecoveryCoordinator':typeID())), + ?match(false, 'CosTransactions_RecoveryCoordinator':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_Resource' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_Resource'(doc) -> ["CosTransactions_Resource"]; +'CosTransactions_Resource'(suite) -> []; +'CosTransactions_Resource'(_) -> + ?nomatch(undefined, 'CosTransactions_Resource':oe_tc(prepare)), + ?nomatch(undefined, 'CosTransactions_Resource':oe_tc(rollback)), + ?nomatch(undefined, 'CosTransactions_Resource':oe_tc(commit)), + ?nomatch(undefined, 'CosTransactions_Resource':oe_tc(commit_one_phase)), + ?nomatch(undefined, 'CosTransactions_Resource':oe_tc(forget)), + ?match(undefined, 'CosTransactions_Resource':oe_tc(undefined)), + ?match([_|_], 'CosTransactions_Resource':oe_get_interface()), + ?match("IDL:omg.org/CosTransactions/Resource:1.0", + 'CosTransactions_Resource':typeID()), + check_tc('CosTransactions_Resource':oe_get_interface()), + ?match(true, 'CosTransactions_Resource':oe_is_a('CosTransactions_Resource':typeID())), + ?match(false, 'CosTransactions_Resource':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_SubtransactionAwareResource' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_SubtransactionAwareResource'(doc) -> ["CosTransactions_SubtransactionAwareResource"]; +'CosTransactions_SubtransactionAwareResource'(suite) -> []; +'CosTransactions_SubtransactionAwareResource'(_) -> + ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(commit_subtransaction)), + ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(rollback_subtransaction)), + ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(prepare)), + ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(rollback)), + ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(commit)), + ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(commit_one_phase)), + ?nomatch(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(forget)), + ?match(undefined, 'CosTransactions_SubtransactionAwareResource':oe_tc(undefined)), + ?match([_|_], 'CosTransactions_SubtransactionAwareResource':oe_get_interface()), + ?match("IDL:omg.org/CosTransactions/SubtransactionAwareResource:1.0", + 'CosTransactions_SubtransactionAwareResource':typeID()), + check_tc('CosTransactions_SubtransactionAwareResource':oe_get_interface()), + ?match(true, 'CosTransactions_SubtransactionAwareResource':oe_is_a('CosTransactions_SubtransactionAwareResource':typeID())), + ?match(true, 'CosTransactions_SubtransactionAwareResource':oe_is_a('CosTransactions_Resource':typeID())), + ?match(false, 'CosTransactions_SubtransactionAwareResource':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_Terminator' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_Terminator'(doc) -> ["CosTransactions_Terminator"]; +'CosTransactions_Terminator'(suite) -> []; +'CosTransactions_Terminator'(_) -> + ?nomatch(undefined, 'CosTransactions_Terminator':oe_tc(commit)), + ?nomatch(undefined, 'CosTransactions_Terminator':oe_tc(rollback)), + ?match(undefined, 'CosTransactions_Terminator':oe_tc(undefined)), + ?match([_|_], 'CosTransactions_Terminator':oe_get_interface()), + ?match("IDL:omg.org/CosTransactions/Terminator:1.0", + 'CosTransactions_Terminator':typeID()), + check_tc('CosTransactions_Terminator':oe_get_interface()), + ?match(true, 'CosTransactions_Terminator':oe_is_a('CosTransactions_Terminator':typeID())), + ?match(false, 'CosTransactions_Terminator':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosTransactions_TransactionFactory' +%% Description: +%%----------------------------------------------------------------- +'CosTransactions_TransactionFactory'(doc) -> ["CosTransactions_TransactionFactory"]; +'CosTransactions_TransactionFactory'(suite) -> []; +'CosTransactions_TransactionFactory'(_) -> + ?nomatch(undefined, 'CosTransactions_TransactionFactory':oe_tc(create)), + ?nomatch(undefined, 'CosTransactions_TransactionFactory':oe_tc(recreate)), + ?match(undefined, 'CosTransactions_TransactionFactory':oe_tc(undefined)), + ?match([_|_], 'CosTransactions_TransactionFactory':oe_get_interface()), + ?match("IDL:omg.org/CosTransactions/TransactionFactory:1.0", + 'CosTransactions_TransactionFactory':typeID()), + check_tc('CosTransactions_TransactionFactory':oe_get_interface()), + ?match(true, 'CosTransactions_TransactionFactory':oe_is_a('CosTransactions_TransactionFactory':typeID())), + ?match(false, 'CosTransactions_TransactionFactory':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'ETraP_Server' +%% Description: +%%----------------------------------------------------------------- +'ETraP_Server'(doc) -> ["ETraP_Server"]; +'ETraP_Server'(suite) -> []; +'ETraP_Server'(_) -> + ?nomatch(undefined, 'ETraP_Server':oe_tc(get_status)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(get_parent_status)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(get_top_level_status)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(is_same_transaction)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(is_related_transaction)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(is_ancestor_transaction)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(is_descendant_transaction)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(is_top_level_transaction)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(hash_transaction)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(hash_top_level_tran)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(register_resource)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(register_subtran_aware)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(rollback_only)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(get_transaction_name)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(create_subtransaction)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(get_txcontext)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(prepare)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(rollback)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(commit)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(commit_one_phase)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(forget)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(replay_completion)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(get_terminator)), + ?nomatch(undefined, 'ETraP_Server':oe_tc(get_coordinator)), + ?match(undefined, 'ETraP_Server':oe_tc(undefined)), + ?match([_|_], 'ETraP_Server':oe_get_interface()), + ?match("IDL:omg.org/ETraP/Server:1.0", + 'ETraP_Server':typeID()), + check_tc('ETraP_Server':oe_get_interface()), + ?match(true, 'ETraP_Server':oe_is_a('ETraP_Server':typeID())), + ?match(true, 'ETraP_Server':oe_is_a('CosTransactions_Coordinator':typeID())), + ?match(true, 'ETraP_Server':oe_is_a('CosTransactions_Resource':typeID())), + ?match(true, 'ETraP_Server':oe_is_a('CosTransactions_RecoveryCoordinator':typeID())), + ?match(true, 'ETraP_Server':oe_is_a('CosTransactions_Control':typeID())), + ?match(false, 'ETraP_Server':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% MISC functions +%%----------------------------------------------------------------- +check_tc([]) -> + ok; +check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) -> + io:format("checked - ~s~n", [Op]), + lists:all(?checktc(Op), [RetType|InParameters]), + lists:all(?checktc(Op), OutParameters), + check_tc(T). + + diff --git a/lib/cosTransactions/test/transactions_SUITE.erl b/lib/cosTransactions/test/transactions_SUITE.erl new file mode 100644 index 0000000000..8385d5a0fb --- /dev/null +++ b/lib/cosTransactions/test/transactions_SUITE.erl @@ -0,0 +1,395 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(transactions_SUITE). + +%%--------------- INCLUDES ----------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/include/ifr_types.hrl"). + +%% Local +-include_lib("cosTransactions/src/ETraP_Common.hrl"). +-include_lib("cosTransactions/include/CosTransactions.hrl"). +-include("etrap_test_lib.hrl"). + +-include("test_server.hrl"). + +-define(default_timeout, ?t:minutes(20)). + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, resource_api/1, etrap_api/1, + init_per_testcase/2, fin_per_testcase/2, app_test/1]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for the cosTransactions interfaces", ""]; +all(suite) -> {req, + [mnesia, orber], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [etrap_api, resource_api, app_test]. + + + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + 'oe_CosTransactions':'oe_register'(), + 'oe_etrap_test':'oe_register'(), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + 'oe_etrap_test':'oe_unregister'(), + 'oe_CosTransactions':'oe_unregister'(), + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + orber:install([node()]), + application:start(mnesia), + application:start(orber), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + application:stop(orber), + application:stop(mnesia), + mnesia:delete_schema([node()]), + Config. + +%%----------------------------------------------------------------- +%% Tests app file +%%----------------------------------------------------------------- +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ok=test_server:app_test(cosTransactions), + ok. + +%%----------------------------------------------------------------- +%% API tests +%%----------------------------------------------------------------- +etrap_api(doc) -> ["ETraP_Server tests", ""]; +etrap_api(suite) -> []; +etrap_api(_Config) -> + ?line ?match(ok, application:start(cosTransactions), + "Starting the cosTransactions application"), + ?line TrFac = cosTransactions:start_factory(), + %% Start a new transaction: + %% RootCoord + %% / \ + %% SubCoord1 SubCoord2 + Control = 'CosTransactions_TransactionFactory':create(TrFac, 0), + Term = 'CosTransactions_Control':get_terminator(Control), + Coord = 'CosTransactions_Control':get_coordinator(Control), + SubCont1 = 'CosTransactions_Coordinator':create_subtransaction(Coord), + SubCont2 = 'CosTransactions_Coordinator':create_subtransaction(Coord), + SubCoord1 = 'CosTransactions_Control':get_coordinator(SubCont1), + SubCoord2 = 'CosTransactions_Control':get_coordinator(SubCont2), + + + %%------ Test CosTransactions::Coordinator ------ + ?line ?match(true, + 'CosTransactions_Coordinator':is_same_transaction(Coord, Coord), + "'CosTransactions_Coordinator':is_same_transaction"), + ?line ?match(false, + 'CosTransactions_Coordinator':is_same_transaction(Coord, SubCoord1), + "'CosTransactions_Coordinator':is_same_transaction"), + ?line ?match(true, + 'CosTransactions_Coordinator':is_descendant_transaction(Coord, Coord), + "'CosTransactions_Coordinator':is_descendant_transaction"), + ?line ?match(false, + 'CosTransactions_Coordinator':is_descendant_transaction(Coord, SubCoord1), + "'CosTransactions_Coordinator':is_descendant_transaction"), + ?line ?match(true, + 'CosTransactions_Coordinator':is_descendant_transaction(SubCoord1, Coord), + "'CosTransactions_Coordinator':is_descendant_transaction"), + ?line ?match(false, + 'CosTransactions_Coordinator':is_descendant_transaction(SubCoord1, SubCoord2), + "'CosTransactions_Coordinator':is_descendant_transaction"), + ?line ?match(true, + 'CosTransactions_Coordinator':is_top_level_transaction(Coord), + "'CosTransactions_Coordinator':is_top_level_transaction"), + ?line ?match(false, + 'CosTransactions_Coordinator':is_top_level_transaction(SubCoord2), + "'CosTransactions_Coordinator':is_top_level_transaction"), + + RootHash = 'CosTransactions_Coordinator':hash_transaction(Coord), + RepeatHash= 'CosTransactions_Coordinator':hash_transaction(Coord), + RootHash2 = 'CosTransactions_Coordinator':hash_top_level_tran(SubCoord1), + RootHash3 = 'CosTransactions_Coordinator':hash_top_level_tran(Coord), + _SubHash = 'CosTransactions_Coordinator':hash_transaction(SubCoord2), + ?line ?match(RootHash, RepeatHash, + "'CosTransactions_Coordinator':hash_transaction"), + ?line ?match(RootHash, RootHash2, + "'CosTransactions_Coordinator':hash_top_level_tran"), + ?line ?match(RootHash, RootHash3, + "'CosTransactions_Coordinator':hash_top_level_tran"), +% ?line ?match_inverse(RootHash, SubHash, +% "'CosTransactions_Coordinator':hash_transaction"), + + ?line ?match('StatusActive', + 'CosTransactions_Coordinator':get_status(Coord), + "'CosTransactions_Coordinator':get_status"), + ?line ?match('StatusActive', + 'CosTransactions_Coordinator':get_status(SubCoord1), + "'CosTransactions_Coordinator':get_status"), + ?line ?match('StatusActive', + 'CosTransactions_Coordinator':get_parent_status(Coord), + "'CosTransactions_Coordinator':get_parent_status"), + ?line ?match('StatusActive', + 'CosTransactions_Coordinator':get_parent_status(SubCoord1), + "'CosTransactions_Coordinator':get_parent_status"), + ?line ?match('StatusActive', + 'CosTransactions_Coordinator':get_top_level_status(Coord), + "'CosTransactions_Coordinator':get_top_level_status"), + ?line ?match('StatusActive', + 'CosTransactions_Coordinator':get_top_level_status(SubCoord1), + "'CosTransactions_Coordinator':get_top_level_status"), + + %% Create a CosTransactions::Resource to experiments with. + %% Start a new transaction: + %% RootCoord + %% / \ + %% SubCoord1 SubCoord2 + %% / + %% Resource + N1 = 'ETraP_Common':create_name("test"), + O1 = etrap_test_server:oe_create(?nop, {global, N1}), + _RC1 = 'CosTransactions_Coordinator':register_resource(SubCoord1, O1), +% 'CosTransactions_Coordinator':register_synchronization(SubCoord1, O1), + + ?line ?match('VoteCommit', + 'CosTransactions_Resource':prepare(SubCoord1), + "'CosTransactions_Coordinator':prepare"), + %% The Transaction are no longer in 'StatusActive' state. No new + %% "members" allowed. + ?line ?match('StatusPrepared', + 'CosTransactions_Coordinator':get_status(SubCoord1), + "'CosTransactions_Coordinator':get_status"), +% ?line ?match({'EXCEPTION', ?tr_inactive}, +% 'CosTransactions_Coordinator':register_synchronization(SubCoord1, O1), +% "'CosTransactions_Coordinator':register_synchronization"), + ?line ?match({'EXCEPTION', ?tr_inactive}, + 'CosTransactions_Coordinator':register_resource(SubCoord1, O1), + "'CosTransactions_Coordinator':register_resource"), + ?line ?match({'EXCEPTION', ?tr_inactive}, + 'CosTransactions_Coordinator':create_subtransaction(SubCoord1), + "'CosTransactions_Coordinator':create_subtransaction"), + + catch corba:dispose(SubCoord1), + catch corba:dispose(SubCoord2), + catch corba:dispose(SubCont1), + catch corba:dispose(SubCont2), + catch corba:dispose(Term), + catch corba:dispose(Control), + catch corba:dispose(Coord), + catch corba:dispose(O1), + + ?line cosTransactions:stop_factory(TrFac), + ?line application:stop(cosTransactions), + ok. + +%%----------------------------------------------------------------- +%% API tests +%%----------------------------------------------------------------- +resource_api(doc) -> ["cosTransactions API tests", ""]; +resource_api(suite) -> []; +resource_api(_Config) -> + ?line ?match(ok, application:start(cosTransactions), + "Starting the cosTransactions application"), + ?line TrFac = cosTransactions:start_factory([{typecheck, true}]), + + ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}}, + run(TrFac, 0, {?nop, ?nop, ?nop, ?prepare_rollback}), + "TESTCASE #1: Prepare rollback Resource 4"), + ?line ?match({'EXCEPTION', ?tr_mixed}, + run(TrFac, 0, {?nop, ?nop, ?commit_mix, ?nop}), + "TESTCASE #2: Heuristic Mixed exception Resource 3"), + ?line ?match(ok, + run(TrFac, 0, {?nop, ?nop, ?nop, ?nop}), + "TESTCASE #3: Normal completion. No errors."), + ?line ?match(ok, + run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_cm}), + "TESTCASE #4: Heuristic Commit Exception Resource 4"), + ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}}, + run(TrFac, 0, {?nop, ?rollback_rb, ?nop, ?prepare_rollback}), + "TESTCASE #5: Heuristic Rollbac Resource 2, Resource 4 reply 'VoteRollback'"), + ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}}, + run(TrFac, 0, {?nop, ?nop, ?prepare_rollback, ?rollback_rb}), + "TESTCASE #6: Heuristic Rollbac Resource 4, Resource 3 reply 'VoteRollback'"), + ?line ?match(ok, + run(TrFac, 0, {?nop, ?nop, ?commit_delay, ?nop}), + "TESTCASE #7: Resource 3 delay during commit. No timeout."), + ?line ?match(ok, + run(TrFac, 0, {?nop, ?nop, ?prepare_delay, ?nop}), + "TESTCASE #8: Resource 3 delay during prepare. No timeout."), + ?line ?match(ok, + run(TrFac, ?TIMEOUT, {?nop, ?commit_delay, ?nop, ?nop}), + "TESTCASE #9: Resource 3 delay during commit. Timeout."), + ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}}, + run(TrFac, ?TIMEOUT, {?nop, ?prepare_delay, ?nop, ?nop}), + "TESTCASE #10: Resource 3 delay during prepare. Timeout."), + case ?is_debug_compiled of + true -> + %% Testing the Coordinators (root and sub). + ?line ?match(ok, + run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_transient(commit), ?nop]}), + "TESTCASE #11: SubCoord 3 crash transient during commit."), + ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}}, + run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_transient(send_prepare), ?nop]}), + "TESTCASE #12: SubCoord 3 crash transient during send prepare."), + ?line ?match({'EXCEPTION', ?tr_hazard}, + run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_permanent(commit), ?nop]}), + "TESTCASE #13: SubCoord 3 crash permanent during commit."), + ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}}, + run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_permanent(send_prepare), ?nop]}), + "TESTCASE #14: SubCoord 3 crash permanent during prepare."), + ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}}, + run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?crash_transient(send_prepare), ?crash_transient(commit), ?nop]}), + "TESTCASE #15: SubCoord 2 crash transient during prepare. SubCoord 3 crash transient during commit"), + ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}}, + run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?crash_transient(send_prepare), ?nop, ?nop, ?nop]}), + "TESTCASE #16: RootCoord crash transient during send prepare."), + ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}}, + run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?crash_transient(prepare1), ?nop, ?nop]}), + "TESTCASE #17: SubCoord 1 crash transient during prepare1."), + ?line ?match({'EXCEPTION', ?tr_mixed}, + run(TrFac, 0, {?nop, ?prepare_mix, ?nop, ?nop, [?nop, ?nop, ?crash_transient(prepare2), ?nop]}), + "TESTCASE #18: SubCoord 3 crash transient during prepare2. Resource 2 raise Heuristic Mixed during prepare"), + ?line ?match({'EXCEPTION', ?tr_mixed}, + run(TrFac, 0, {?nop, ?commit_mix, ?nop, ?nop, [?nop, ?nop, ?crash_transient(commit2), ?nop]}), + "TESTCASE #19: Resource 2 raise Heurist mixed during commit. SubCoord crash transient commit2"), + ?line ?match({'EXCEPTION', ?tr_mixed}, + run(TrFac, 0, {?nop, ?rollback_cm, ?nop, ?prepare_rollback, [?nop, ?crash_transient(rollback2), ?nop, ?nop]}), + "TESTCASE #20: Resource 2 raise Heuristic Commit during rollback. Resource 4 'VoteRollback'. SubCoord 2 crash transient rollback2."), + ?line ?match({'EXCEPTION', ?tr_mixed}, + run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_mix, [?nop, ?nop, ?crash_transient(send_forget1), ?nop]}), + "TESTCASE #21: Resource 4 raise Heuristic Mixed during commit. SubCoord 2 crash transient send_forget1."), + ?line ?match({'EXCEPTION', ?tr_mixed}, + run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_mix, [?crash_transient(send_forget1), ?nop, ?nop, ?nop]}), + "TESTCASE #22: Resource 4 raise Heuristic Mixed during commit. Root Coord crash transient send_forget1."), + ?line ?match({'EXCEPTION', ?tr_mixed}, + run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_mix, [?crash_transient(send_forget3), ?nop, ?crash_transient(send_forget1), ?nop]}), + "TESTCASE #23: Resource 4 raise Heuristic Mixed during commit. Root Coord crash transient send_forget3. SubCoord 3 crash transient send_forget1."), + ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}}, + run(TrFac, ?TIMEOUT, {?nop, ?nop, ?nop, ?nop, [?delay_transient(root_delay, ?TIMEOUT*2), ?nop, ?nop, ?nop]}), + "TESTCASE #24: Delay RootCoord. Timeout."), + %% Testing the Terminator. + ?line ?match({'EXCEPTION', ?tr_mixed}, + run(TrFac, ?TIMEOUT, {?nop, ?prepare_mix, ?nop, ?nop, [?nop, ?nop, ?nop, ?crash_transient(commit_heuristic1)]}), + "TESTCASE #25: Terminator crash transient after received and logged Heuristic mix."), + ?line ?match(ok, + run(TrFac, ?TIMEOUT, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop, ?nop, ?crash_transient(commit_ok2)]}), + "TESTCASE #26: Terminator crash transient after received and logged 'ok'."); + _ -> + ok + end, + + ?line cosTransactions:stop_factory(TrFac), + ?line application:stop(cosTransactions), + ok. + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- + +run(TrFac, Time, Spec) -> + Control = 'CosTransactions_TransactionFactory':create(TrFac, Time), + Term = 'CosTransactions_Control':get_terminator(Control), + Coord = 'CosTransactions_Control':get_coordinator(Control), + SubCont1 = 'CosTransactions_Coordinator':create_subtransaction(Coord), + SubCont2 = 'CosTransactions_Coordinator':create_subtransaction(Coord), + SubCoord1 = 'CosTransactions_Control':get_coordinator(SubCont1), + SubCoord2 = 'CosTransactions_Control':get_coordinator(SubCont2), + %% Start resources/participants. + {O1, O2, O3, O4, Ctx} = start_resources(Spec), + + %% Get generated names to use for debugging. + CoordN = 'CosTransactions_Coordinator':get_transaction_name(Coord), + SubC1N = 'CosTransactions_Coordinator':get_transaction_name(SubCoord1), + SubC2N = 'CosTransactions_Coordinator':get_transaction_name(SubCoord2), + + ?set_debug_context([CoordN, SubC1N, SubC2N, Term], Ctx), + + %% Register the resources as participants. + _RC1 = 'CosTransactions_Coordinator':register_resource(SubCoord1, O1), + _RC2 = 'CosTransactions_Coordinator':register_resource(SubCoord1, O2), + _RC3 = 'CosTransactions_Coordinator':register_resource(SubCoord2, O3), + _RC4 = 'CosTransactions_Coordinator':register_resource(SubCoord2, O4), + + 'CosTransactions_Coordinator':register_subtran_aware(SubCoord1, O4), +% 'CosTransactions_Coordinator':register_synchronization(SubCoord1, O2), + +% Reply = (catch 'CosTransactions_Terminator':commit(Term, true)), + Reply = (catch 'ETraP_Common':send_stubborn('CosTransactions_Terminator', + commit, [Term, true], + ?tr_max_retries, + ?tr_comm_failure_wait)), + + catch corba:dispose(SubCoord1), + catch corba:dispose(SubCoord2), + catch corba:dispose(SubCont1), + catch corba:dispose(SubCont2), + catch corba:dispose(Term), + catch corba:dispose(Control), + catch corba:dispose(Coord), + catch corba:dispose(O1), + catch corba:dispose(O2), + catch corba:dispose(O3), + catch corba:dispose(O4), + Reply. + + + +start_resources({A1, A2, A3, A4})-> + start_resources({A1, A2, A3, A4, ?no_context}); +start_resources({A1, A2, A3, A4, Ctx})-> + N1 = 'ETraP_Common':create_name("test"), + N2 = 'ETraP_Common':create_name("test"), + N3 = 'ETraP_Common':create_name("test"), + N4 = 'ETraP_Common':create_name("test"), + {_,_,O1} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A1, N1)), + {_,_,O2} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A2, N2)), +% {_,_,O2} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST([{sync,true}|A2], N2)), + {_,_,O3} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A3, N3)), + {_,_,O4} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A4, N4)), + {O1, O2, O3, O4, Ctx}. diff --git a/lib/debugger/test/Makefile b/lib/debugger/test/Makefile new file mode 100644 index 0000000000..ac929038f7 --- /dev/null +++ b/lib/debugger/test/Makefile @@ -0,0 +1,106 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1998-2010. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +MODULES= \ + andor_SUITE \ + bs_bincomp_SUITE \ + bs_construct_SUITE \ + bs_match_bin_SUITE \ + bs_match_int_SUITE \ + bs_match_misc_SUITE \ + bs_match_tail_SUITE \ + bs_utf_SUITE \ + bug_SUITE \ + erl_eval_SUITE \ + dbg_ui_SUITE \ + debugger_SUITE \ + int_SUITE \ + int_break_SUITE \ + int_eval_SUITE \ + guard_SUITE \ + exception_SUITE \ + fun_SUITE \ + lc_SUITE \ + record_SUITE \ + trycatch_SUITE \ + test_lib \ + cleanup + +ERL_FILES= $(MODULES:%=%.erl) + +TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) +INSTALL_PROGS= $(TARGET_FILES) + +EMAKEFILE=Emakefile + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/debugger_test + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- + +ERL_MAKE_FLAGS += +ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include + +EBIN = . + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +make_emakefile: + $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \ + > $(EMAKEFILE) + $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' \ + >> $(EMAKEFILE) + +tests debug opt: make_emakefile + erl $(ERL_MAKE_FLAGS) -make + +clean: + rm -f $(EMAKEFILE) + rm -f $(TARGET_FILES) $(GEN_FILES) + rm -f core + +docs: + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + +release_tests_spec: make_emakefile + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) debugger.spec $(RELSYSDIR) + chmod -f -R u+w $(RELSYSDIR) + @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + +release_docs_spec: diff --git a/lib/debugger/test/andor_SUITE.erl b/lib/debugger/test/andor_SUITE.erl new file mode 100644 index 0000000000..3482a22a34 --- /dev/null +++ b/lib/debugger/test/andor_SUITE.erl @@ -0,0 +1,305 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2006-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(andor_SUITE). + +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + t_andalso/1,t_orelse/1,inside/1,overlap/1, + combined/1,in_case/1]). + +-include("test_server.hrl"). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + ?line Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +cases() -> + [t_andalso,t_orelse,inside,overlap,combined,in_case]. + +t_andalso(Config) when is_list(Config) -> + Bs = [true,false], + Ps = [{X,Y} || X <- Bs, Y <- Bs], + lists:foreach(fun (P) -> t_andalso_1(P) end, Ps), + + ?line true = true andalso true, + ?line false = true andalso false, + ?line false = false andalso true, + ?line false = false andalso false, + + ?line false = false andalso glurf, + ?line false = false andalso exit(exit_now), + + ?line true = not id(false) andalso not id(false), + ?line false = not id(false) andalso not id(true), + ?line false = not id(true) andalso not id(false), + ?line false = not id(true) andalso not id(true), + + ?line {'EXIT',{badarg,_}} = (catch not id(glurf) andalso id(true)), + ?line {'EXIT',{badarg,_}} = (catch not id(false) andalso not id(glurf)), + ?line false = id(false) andalso not id(glurf), + ?line false = false andalso not id(glurf), + + ok. + +t_orelse(Config) when is_list(Config) -> + Bs = [true,false], + Ps = [{X,Y} || X <- Bs, Y <- Bs], + lists:foreach(fun (P) -> t_orelse_1(P) end, Ps), + + ?line true = true orelse true, + ?line true = true orelse false, + ?line true = false orelse true, + ?line false = false orelse false, + + ?line true = true orelse glurf, + ?line true = true orelse exit(exit_now), + + ?line true = not id(false) orelse not id(false), + ?line true = not id(false) orelse not id(true), + ?line true = not id(true) orelse not id(false), + ?line false = not id(true) orelse not id(true), + + ?line {'EXIT',{badarg,_}} = (catch not id(glurf) orelse id(true)), + ?line {'EXIT',{badarg,_}} = (catch not id(true) orelse not id(glurf)), + ?line true = id(true) orelse not id(glurf), + ?line true = true orelse not id(glurf), + + ok. + +t_andalso_1({X,Y}) -> + io:fwrite("~w andalso ~w: ",[X,Y]), + V1 = echo(X) andalso echo(Y), + V1 = if + X andalso Y -> true; + true -> false + end, + check(V1, X and Y). + +t_orelse_1({X,Y}) -> + io:fwrite("~w orelse ~w: ",[X,Y]), + V1 = echo(X) orelse echo(Y), + V1 = if + X orelse Y -> true; + true -> false + end, + check(V1, X or Y). + +inside(Config) when is_list(Config) -> + ?line true = inside(-8, 1), + ?line false = inside(-53.5, -879798), + ?line false = inside(1.0, -879), + ?line false = inside(59, -879), + ?line false = inside(-11, 1.0), + ?line false = inside(100, 0.2), + ?line false = inside(100, 1.2), + ?line false = inside(-53.5, 4), + ?line false = inside(1.0, 5.3), + ?line false = inside(59, 879), + ok. + +inside(Xm, Ym) -> + X = -10.0, + Y = -2.0, + W = 20.0, + H = 4.0, + Res = inside(Xm, Ym, X, Y, W, H), + Res = if + X =< Xm andalso Xm < X+W andalso Y =< Ym andalso Ym < Y+H -> true; + true -> false + end, + case not id(Res) of + Outside -> + Outside = if + not(X =< Xm andalso Xm < X+W andalso Y =< Ym andalso Ym < Y+H) -> true; + true -> false + end + end, + {Res,Xm,Ym,X,Y,W,H} = inside_guard(Xm, Ym, X, Y, W, H), + io:format("~p =< ~p andalso ~p < ~p andalso ~p =< ~p andalso ~p < ~p ==> ~p", + [X,Xm,Xm,X+W,Y,Ym,Ym,Y+H,Res]), + Res. + +inside(Xm, Ym, X, Y, W, H) -> + X =< Xm andalso Xm < X+W andalso Y =< Ym andalso Ym < Y+H. + +inside_guard(Xm, Ym, X, Y, W, H) when X =< Xm andalso Xm < X+W + andalso Y =< Ym andalso Ym < Y+H -> + {true,Xm,Ym,X,Y,W,H}; +inside_guard(Xm, Ym, X, Y, W, H) -> + {false,Xm,Ym,X,Y,W,H}. + +overlap(Config) when is_list(Config) -> + ?line true = overlap(7.0, 2.0, 8.0, 0.5), + ?line true = overlap(7.0, 2.0, 8.0, 2.5), + ?line true = overlap(7.0, 2.0, 5.3, 2), + ?line true = overlap(7.0, 2.0, 0.0, 100.0), + + ?line false = overlap(-1, 2, -35, 0.5), + ?line false = overlap(-1, 2, 777, 0.5), + ?line false = overlap(-1, 2, 2, 10), + ?line false = overlap(2, 10, 12, 55.3), + ok. + +overlap(Pos1, Len1, Pos2, Len2) -> + Res = case Pos1 of + Pos1 when (Pos2 =< Pos1 andalso Pos1 < Pos2+Len2) + orelse (Pos1 =< Pos2 andalso Pos2 < Pos1+Len1) -> + true; + Pos1 -> false + end, + Res = (Pos2 =< Pos1 andalso Pos1 < Pos2+Len2) + orelse (Pos1 =< Pos2 andalso Pos2 < Pos1+Len1), + Res = case Pos1 of + Pos1 when (Pos2 =< Pos1 andalso Pos1 < Pos2+Len2) + orelse (Pos1 =< Pos2 andalso Pos2 < Pos1+Len1) -> + true; + Pos1 -> false + end, + id(Res). + + +-define(COMB(A,B,C), (A andalso B orelse C)). + +combined(Config) when is_list(Config) -> + ?line false = comb(false, false, false), + ?line true = comb(false, false, true), + ?line false = comb(false, true, false), + ?line true = comb(false, true, true), + + ?line false = comb(true, false, false), + ?line true = comb(true, true, false), + ?line true = comb(true, false, true), + ?line true = comb(true, true, true), + + ?line false = comb(false, blurf, false), + ?line true = comb(false, blurf, true), + ?line true = comb(true, true, blurf), + + ?line false = ?COMB(false, false, false), + ?line true = ?COMB(false, false, true), + ?line false = ?COMB(false, true, false), + ?line true = ?COMB(false, true, true), + + ?line false = ?COMB(true, false, false), + ?line true = ?COMB(true, true, false), + ?line true = ?COMB(true, false, true), + ?line true = ?COMB(true, true, true), + + ?line false = ?COMB(false, blurf, false), + ?line true = ?COMB(false, blurf, true), + ?line true = ?COMB(true, true, blurf), + + ok. +-undef(COMB). + +comb(A, B, C) -> + Res = A andalso B orelse C, + Res = if + A andalso B orelse C -> true; + true -> false + end, + NotRes = if + not(A andalso B orelse C) -> true; + true -> false + end, + NotRes = id(not Res), + Res = A andalso B orelse C, + Res = if + A andalso B orelse C -> true; + true -> false + end, + NotRes = id(not Res), + Res = if + A andalso B orelse C -> true; + true -> false + end, + id(Res). + +%% Test that a boolean expression in a case expression is properly +%% optimized (in particular, that the error behaviour is correct). +in_case(Config) when is_list(Config) -> + ?line edge_rings = in_case_1(1, 1, 1, 1, 1), + ?line not_loop = in_case_1(0.5, 1, 1, 1, 1), + ?line loop = in_case_1(0.5, 0.9, 1.1, 1, 4), + ?line {'EXIT',{badarith,_}} = (catch in_case_1(1, 1, 1, 1, 0)), + ?line {'EXIT',{badarith,_}} = (catch in_case_1(1, 1, 1, 1, nan)), + ?line {'EXIT',{badarg,_}} = (catch in_case_1(1, 1, 1, blurf, 1)), + ?line {'EXIT',{badarith,_}} = (catch in_case_1([nan], 1, 1, 1, 1)), + ok. + +in_case_1(LenUp, LenDw, LenN, Rotation, Count) -> + Res = in_case_1_body(LenUp, LenDw, LenN, Rotation, Count), + Res = in_case_1_guard(LenUp, LenDw, LenN, Rotation, Count), + Res. + +in_case_1_body(LenUp, LenDw, LenN, Rotation, Count) -> + case (LenUp/Count > 0.707) and (LenN/Count > 0.707) and + (abs(Rotation) > 0.707) of + true -> + edge_rings; + false -> + case (LenUp >= 1) or (LenDw >= 1) or + (LenN =< 1) or (Count < 4) of + true -> + not_loop; + false -> + loop + end + end. + +in_case_1_guard(LenUp, LenDw, LenN, Rotation, Count) -> + case (LenUp/Count > 0.707) andalso (LenN/Count > 0.707) andalso + (abs(Rotation) > 0.707) of + true -> edge_rings; + false when LenUp >= 1 orelse LenDw >= 1 orelse + LenN =< 1 orelse Count < 4 -> not_loop; + false -> loop + end. + +check(V1, V0) -> + if V1 /= V0 -> + io:fwrite("error: ~w.\n", [V1]), + ?t:fail(); + true -> + io:fwrite("ok: ~w.\n", [V1]) + end. + +echo(X) -> + io:fwrite("eval(~w); ",[X]), + X. + +id(I) -> I. diff --git a/lib/debugger/test/bs_bincomp_SUITE.erl b/lib/debugger/test/bs_bincomp_SUITE.erl new file mode 100644 index 0000000000..8ca2b36f1c --- /dev/null +++ b/lib/debugger/test/bs_bincomp_SUITE.erl @@ -0,0 +1,106 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%% Originally based on Per Gustafsson's test suite. +%% + +-module(bs_bincomp_SUITE). + +-export([all/1,init_per_testcase/2,fin_per_testcase/2, + byte_aligned/1,bit_aligned/1,extended_byte_aligned/1, + extended_bit_aligned/1,mixed/1]). + +-include("test_server.hrl"). + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +all(suite) -> + [byte_aligned,bit_aligned,extended_byte_aligned, + extended_bit_aligned,mixed]. + + +byte_aligned(Config) when is_list(Config) -> + ?line <<"abcdefg">> = << <<(X+32)>> || <<X>> <= <<"ABCDEFG">> >>, + ?line <<1:32/little,2:32/little,3:32/little,4:32/little>> = + << <<X:32/little>> || <<X:32>> <= <<1:32,2:32,3:32,4:32>> >>, + ?line <<1:32/little,2:32/little,3:32/little,4:32/little>> = + << <<X:32/little>> || <<X:16>> <= <<1:16,2:16,3:16,4:16>> >>, + ok. + +bit_aligned(Config) when is_list(Config) -> + ?line <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> = + << <<(X+32):7>> || <<X>> <= <<"ABCDEFG">> >>, + ?line <<"ABCDEFG">> = + << <<(X-32)>> || <<X:7>> <= <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> >>, + ?line <<1:31/little,2:31/little,3:31/little,4:31/little>> = + << <<X:31/little>> || <<X:31>> <= <<1:31,2:31,3:31,4:31>> >>, + ?line <<1:31/little,2:31/little,3:31/little,4:31/little>> = + << <<X:31/little>> || <<X:15>> <= <<1:15,2:15,3:15,4:15>> >>, + ok. + +extended_byte_aligned(Config) when is_list(Config) -> + ?line <<"abcdefg">> = << <<(X+32)>> || X <- "ABCDEFG" >>, + ?line "abcdefg" = [(X+32) || <<X>> <= <<"ABCDEFG">>], + ?line <<1:32/little,2:32/little,3:32/little,4:32/little>> = + << <<X:32/little>> || X <- [1,2,3,4] >>, + ?line [256,512,768,1024] = + [X || <<X:16/little>> <= <<1:16,2:16,3:16,4:16>>], + ok. + +extended_bit_aligned(Config) when is_list(Config) -> + ?line <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> = + << <<(X+32):7>> || X <- "ABCDEFG" >>, + ?line "ABCDEFG" = [(X-32) || <<X:7>> <= <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>>], + ?line <<1:31/little,2:31/little,3:31/little,4:31/little>> = + << <<X:31/little>> || X <- [1,2,3,4] >>, + ?line [256,512,768,1024] = + [X || <<X:15/little>> <= <<1:15,2:15,3:15,4:15>>], + ok. + +mixed(Config) when is_list(Config) -> + ?line <<2,3,3,4,4,5,5,6>> = + << <<(X+Y)>> || <<X>> <= <<1,2,3,4>>, <<Y>> <= <<1,2>> >>, + ?line <<2,3,3,4,4,5,5,6>> = + << <<(X+Y)>> || <<X>> <= <<1,2,3,4>>, Y <- [1,2] >>, + ?line <<2,3,3,4,4,5,5,6>> = + << <<(X+Y)>> || X <- [1,2,3,4], Y <- [1,2] >>, + ?line [2,3,3,4,4,5,5,6] = + [(X+Y) || <<X>> <= <<1,2,3,4>>, <<Y>> <= <<1,2>>], + ?line [2,3,3,4,4,5,5,6] = + [(X+Y) || <<X>> <= <<1,2,3,4>>, Y <- [1,2]], + ?line <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> = + << <<(X+Y):3>> || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, <<Y:3>> <= <<1:3,2:3>> >>, + ?line <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> = + << <<(X+Y):3>> || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, Y <- [1,2] >>, + ?line <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> = + << <<(X+Y):3>> || X <- [1,2,3,4], Y <- [1,2] >>, + ?line [2,3,3,4,4,5,5,6] = + [(X+Y) || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, <<Y:3>> <= <<1:3,2:3>>], + ?line [2,3,3,4,4,5,5,6] = + [(X+Y) || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, Y <- [1,2]], + ok. diff --git a/lib/debugger/test/bs_construct_SUITE.erl b/lib/debugger/test/bs_construct_SUITE.erl new file mode 100644 index 0000000000..efc125c582 --- /dev/null +++ b/lib/debugger/test/bs_construct_SUITE.erl @@ -0,0 +1,432 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(bs_construct_SUITE). + +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + test1/1, test2/1, test3/1, test4/1, test5/1, testf/1, not_used/1, in_guard/1, + coerce_to_float/1]). + +-include("test_server.hrl"). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [test1, test2, test3, test4, test5, testf, + not_used, in_guard, coerce_to_float]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +big(1) -> + 57285702734876389752897683. + +i(X) -> X. + +r(L) -> + lists:reverse(L). + +-define(T(B, L), {B, ??B, L}). +-define(N(B), {B, ??B, unknown}). + +-define(FAIL(Expr), ?line {'EXIT',{badarg,_}} = (catch Expr)). + +l(I_13, I_big1) -> + [ + ?T(<<-43>>, + [256-43]), + ?T(<<56>>, + [56]), + ?T(<<1,2>>, + [1, 2]), + ?T(<<4:4, 7:4>>, + [4*16+7]), + ?T(<<777:16/big>>, + [3, 9]), + ?T(<<777:16/little>>, + [9, 3]), + ?T(<<0.0:32/float>>, + [0,0,0,0]), + ?T(<<0.125:32/float>>, + [62,0,0,0]), + ?T(<<0.125:32/little-float>>, + [0,0,0,62]), + ?T(<<I_big1:32>>, + [138, 99, 0, 147]), + ?T(<<57285702734876389752897684:32>>, + [138, 99, 0, 148]), + ?T(<<I_big1:32/little>>, + r([138, 99, 0, 147])), + ?T(<<-1:17/unit:8>>, + lists:duplicate(17, 255)), + + ?T(<<I_13>>, + [13]), + + ?T(<<4:8/unit:2,5:2/unit:8>>, + [0, 4, 0, 5]), + + ?T(<<1:1, 0:6, 1:1>>, + [129]), + ?T(<<1:1/little, 0:6/little, 1:1/little>>, + [129]), + + ?T(<<<<1,2>>/binary>>, + [1, 2]), + ?T(<<<<1,2>>:1/binary>>, + [1]), + ?T(<<4,3,<<1,2>>:1/binary>>, + [4,3,1]), + + ?T(<<(256*45+47)>>, + [47]), + + ?T(<<57:0>>, + []), + + ?T(<<"apa">>, + "apa"), + + ?T(<<1:3,"string",9:5>>, + [46,110,142,77,45,204,233]), + + ?T(<<>>, + []), + + ?T(<<37.98:64/native-float>>, + native_3798()), + + ?T(<<32978297842987249827298387697777669766334937:128/native-integer>>, + native_bignum()) + + ]. + +native_3798() -> + case <<1:16/native>> of + <<0,1>> -> [64,66,253,112,163,215,10,61]; + <<1,0>> -> [61,10,215,163,112,253,66,64] + end. + +native_bignum() -> + case <<1:16/native>> of + <<0,1>> -> [129,205,18,177,1,213,170,101,39,231,109,128,176,11,73,217]; + <<1,0>> -> [217,73,11,176,128,109,231,39,101,170,213,1,177,18,205,129] + end. + +evaluate(Str, Vars) -> + {ok,Tokens,_} = + erl_scan:string(Str ++ " . "), + {ok, [Expr]} = erl_parse:parse_exprs(Tokens), + case erl_eval:expr(Expr, Vars) of + {value, Result, _} -> + Result + end. + +eval_list([], _Vars) -> + []; +eval_list([{C_bin, Str, Bytes} | Rest], Vars) -> + case catch evaluate(Str, Vars) of + {'EXIT', Error} -> + io:format("Evaluation error: ~p, ~p, ~p~n", [Str, Vars, Error]), + exit(Error); + E_bin -> + [{C_bin, E_bin, Str, Bytes} | eval_list(Rest, Vars)] + end. + +one_test({C_bin, E_bin, Str, Bytes}) when list(Bytes) -> + io:format(" ~s, ~p~n", [Str, Bytes]), + Bin = list_to_binary(Bytes), + if + C_bin == Bin -> + ok; + true -> + io:format("ERROR: Compiled: ~p. Expected ~p. Got ~p.~n", + [Str, Bytes, binary_to_list(C_bin)]), + test_server:fail(comp) + end, + if + E_bin == Bin -> + ok; + true -> + io:format("ERROR: Interpreted: ~p. Expected ~p. Got ~p.~n", + [Str, Bytes, binary_to_list(E_bin)]), + test_server:fail(comp) + end; +one_test({C_bin, E_bin, Str, Result}) -> + io:format(" ~s ~p~n", [Str, C_bin]), + if + C_bin == E_bin -> + ok; + true -> + Arbitrary = case Result of + unknown -> + size(C_bin); + _ -> + Result + end, + case equal_lists(binary_to_list(C_bin), + binary_to_list(E_bin), + Arbitrary) of + false -> + io:format("ERROR: Compiled not equal to interpreted:" + "~n ~p, ~p.~n", + [binary_to_list(C_bin), binary_to_list(E_bin)]), + test_server:fail(comp); + 0 -> + ok; + %% For situations where the final bits may not matter, like + %% for floats: + N when integer(N) -> + io:format("Info: compiled and interpreted differ in the" + " last bytes:~n ~p, ~p.~n", + [binary_to_list(C_bin), binary_to_list(E_bin)]), + ok + end + end. + +equal_lists([], [], _) -> + 0; +equal_lists([], _, _) -> + false; +equal_lists(_, [], _) -> + false; +equal_lists([A|AR], [A|BR], R) -> + equal_lists(AR, BR, R); +equal_lists(A, B, R) -> + if + length(A) /= length(B) -> + false; + length(A) =< R -> + R; + true -> + false + end. + +%%% Simple working cases +test1(suite) -> []; +test1(Config) when list(Config) -> + ?line I_13 = i(13), + ?line I_big1 = big(1), + ?line Vars = [{'I_13', I_13}, + {'I_big1', I_big1}], + ?line lists:foreach(fun one_test/1, eval_list(l(I_13, I_big1), Vars)). + +%%% Misc + +%%% <<A:S, A:(N-S)>> +comp(N, A, S) -> + M1 = (1 bsl S) - 1, + M2 = (1 bsl (N-S)) - 1, + [((A band M1) bsl (N-S)) bor (A band M2)]. + +gen(N, S, A) -> + [?T(<<A:S, A:(N-S)>>, comp(N, A, S))]. + +gen_l(N, S, A) -> + [?T(<<A:S/little, A:(N-S)/little>>, comp(N, A, S))]. + +test2(suite) -> []; +test2(Config) when list(Config) -> + ?line test2(0, 8, 2#10101010101010101), + ?line test2(0, 8, 2#1111111111). + +test2(End, End, _) -> + ok; +test2(I, End, A) -> + test2(I, A), + test2(I+1, End, A). + +test2(S, A) -> + N = 8, + Vars = [{'A',A}, {'N',N}, {'S',S}], + io:format("Vars: ~p\n", [Vars]), + lists:foreach(fun one_test/1, eval_list(gen(N, S, A), Vars)), + lists:foreach(fun one_test/1, eval_list(gen_l(N, S, A), Vars)). + +%%% Tests without facit + +t3() -> + [?N(<<4711:13, 9876:13, 3:6>>), + ?N(<<4.57:64/float>>), + ?N(<<4.57:32/float>>), + + ?N(<<>>) + ]. + +test3(suite) -> []; +test3(Config) when list(Config) -> + ?line Vars = [], + ?line lists:foreach(fun one_test/1, eval_list(t3(), Vars)). + +gen_u(N, S, A) -> + [?N(<<A:S, A:(N-S)>>)]. + +gen_u_l(N, S, A) -> + [?N(<<A:S/little, A:(N-S)/little>>)]. + +test4(suite) -> []; +test4(Config) when list(Config) -> + ?line test4(0, 16, 2#10101010101010101), + ?line test4(0, 16, 2#1111111111). + +test4(End, End, _) -> + ok; +test4(I, End, A) -> + test4(I, A), + test4(I+1, End, A). + +test4(S, A) -> + N = 16, + Vars = [{'A', A}, {'N', 16}, {'S', S}], + lists:foreach(fun one_test/1, eval_list(gen_u(N, S, A), Vars)), + lists:foreach(fun one_test/1, eval_list(gen_u_l(N, S, A), Vars)). + +gen_b(N, S, A) -> + [?T(<<A:S/binary-unit:1, A:(N-S)/binary-unit:1>>, + binary_to_list(<<A:S/binary-unit:1, A:(N-S)/binary-unit:1>>))]. + +test5(suite) -> []; +test5(doc) -> ["OTP-3995"]; +test5(Config) when list(Config) -> + ?line test5(0, 8, <<73>>), + ?line test5(0, 8, <<68>>). + +test5(End, End, _) -> + ok; +test5(I, End, A) -> + test5(I, A), + test5(I+1, End, A). + +test5(S, A) -> + N = 8, + Vars = [{'A', A}, {'N', 8}, {'S', S}], + lists:foreach(fun one_test/1, eval_list(gen_b(N, S, A), Vars)). + +%%% Failure cases +testf(suite) -> []; +testf(Config) when list(Config) -> + ?FAIL(<<3.14>>), + ?FAIL(<<<<1,2>>>>), + + ?FAIL(<<2.71/binary>>), + ?FAIL(<<24334/binary>>), + ?FAIL(<<24334344294788947129487129487219847/binary>>), + + ?FAIL(<<<<1,2,3>>/float>>), + + %% Negative field widths. + testf_1(-8, <<1,2,3,4,5>>), + + ?FAIL(<<42:(-16)>>), + ?FAIL(<<3.14:(-8)/float>>), + ?FAIL(<<<<23,56,0,2>>:(-16)/binary>>), + ?FAIL(<<<<23,56,0,2>>:(2.5)/binary>>), + ?FAIL(<<<<23,56,0,2>>:(anka)>>), + + ok. + +testf_1(W, B) -> + ?FAIL(<<42:W>>), + ?FAIL(<<3.14:W/float>>), + ?FAIL(<<B:W/binary>>). + +not_used(doc) -> + "Test that constructed binaries that are not used will still give an exception."; +not_used(Config) when is_list(Config) -> + ?line ok = not_used1(3, <<"dum">>), + ?line ?FAIL(not_used1(3, "dum")), + ?line ?FAIL(not_used2(444, -2)), + ?line ?FAIL(not_used2(444, anka)), + ?line ?FAIL(not_used3(444)), + ok. + +not_used1(I, BinString) -> + <<I:32,BinString/binary>>, + ok. + +not_used2(I, Sz) -> + <<I:Sz>>, + ok. + +not_used3(I) -> + <<I:(-8)>>, + ok. + +in_guard(Config) when list(Config) -> + ?line 1 = in_guard(<<16#74ad:16>>, 16#e95, 5), + ?line 2 = in_guard(<<16#3A,16#F7,"hello">>, 16#3AF7, <<"hello">>), + ?line 3 = in_guard(<<16#FBCD:14,3.1415/float,3:2>>, 16#FBCD, 3.1415), + nope = in_guard(<<1>>, 42, b), + nope = in_guard(<<1>>, a, b), + nope = in_guard(<<1,2>>, 1, 1), + nope = in_guard(<<4,5>>, 1, 2.71), + nope = in_guard(<<4,5>>, 1, <<12,13>>), + ok. + +in_guard(Bin, A, B) when <<A:13,B:3>> == Bin -> 1; +in_guard(Bin, A, B) when <<A:16,B/binary>> == Bin -> 2; +in_guard(Bin, A, B) when <<A:14,B/float,3:2>> == Bin -> 3; +in_guard(Bin, A, B) when {a,b,<<A:14,B/float,3:2>>} == Bin -> cant_happen; +in_guard(_, _, _) -> nope. + +-define(COF(Int0), + ?line (fun(Int) -> + true = <<Int:32/float>> =:= <<(float(Int)):32/float>>, + true = <<Int:64/float>> =:= <<(float(Int)):64/float>> + end)(nonliteral(Int0)), + ?line true = <<Int0:32/float>> =:= <<(float(Int0)):32/float>>, + ?line true = <<Int0:64/float>> =:= <<(float(Int0)):64/float>>). + +-define(COF64(Int0), + ?line (fun(Int) -> + true = <<Int:64/float>> =:= <<(float(Int)):64/float>> + end)(nonliteral(Int0)), + ?line true = <<Int0:64/float>> =:= <<(float(Int0)):64/float>>). + +nonliteral(X) -> X. + +coerce_to_float(Config) when list(Config) -> + ?COF(0), + ?COF(-1), + ?COF(1), + ?COF(42), + ?COF(255), + ?COF(-255), + ?COF(38474), + ?COF(387498738948729893849444444443), + ?COF(-37489378937773899999999999999993), + ?COF64(298748888888888888888888888883478264866528467367364766666666666666663), + ?COF64(-367546729879999999999947826486652846736736476555566666663), + ok. diff --git a/lib/debugger/test/bs_match_bin_SUITE.erl b/lib/debugger/test/bs_match_bin_SUITE.erl new file mode 100644 index 0000000000..3966dc41ef --- /dev/null +++ b/lib/debugger/test/bs_match_bin_SUITE.erl @@ -0,0 +1,114 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + + +-module(bs_match_bin_SUITE). + +-author('[email protected]'). +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + byte_split_binary/1,bit_split_binary/1]). + +-include("test_server.hrl"). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [byte_split_binary,bit_split_binary]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +byte_split_binary(doc) -> "Tries to split a binary at all byte-aligned positions."; +byte_split_binary(suite) -> []; +byte_split_binary(Config) when list(Config) -> + ?line L = lists:seq(0, 57), + ?line B = mkbin(L), + ?line byte_split(L, B, size(B)). + +byte_split(L, B, Pos) when Pos >= 0 -> + ?line Sz1 = Pos, + ?line Sz2 = size(B) - Pos, + ?line <<B1:Sz1/binary,B2:Sz2/binary>> = B, + ?line B1 = list_to_binary(lists:sublist(L, 1, Pos)), + ?line B2 = list_to_binary(lists:nthtail(Pos, L)), + ?line byte_split(L, B, Pos-1); +byte_split(_L, _B, _) -> ok. + +bit_split_binary(doc) -> "Tries to split a binary at all positions."; +bit_split_binary(suite) -> []; +bit_split_binary(Config) when list(Config) -> + Fun = fun(Bin, List, SkipBef, N) -> + ?line SkipAft = 8*size(Bin) - N - SkipBef, + io:format("~p, ~p, ~p", [SkipBef,N,SkipAft]), + ?line <<_I1:SkipBef,OutBin:N/binary-unit:1,_I2:SkipAft>> = Bin, + ?line OutBin = make_bin_from_list(List, N) + end, + ?line bit_split_binary1(Fun, erlang:md5(<<1,2,3>>)), + ok. + +bit_split_binary1(Action, Bin) -> + BitList = bits_to_list(binary_to_list(Bin), 16#80), + bit_split_binary2(Action, Bin, BitList, 0). + +bit_split_binary2(Action, Bin, [_|T]=List, Bef) -> + bit_split_binary3(Action, Bin, List, Bef, size(Bin)*8), + bit_split_binary2(Action, Bin, T, Bef+1); +bit_split_binary2(_Action, _Bin, [], _Bef) -> ok. + +bit_split_binary3(Action, Bin, List, Bef, Aft) when Bef =< Aft -> + Action(Bin, List, Bef, (Aft-Bef) div 8 * 8), + bit_split_binary3(Action, Bin, List, Bef, Aft-8); +bit_split_binary3(_, _, _, _, _) -> ok. + +make_bin_from_list(_List, 0) -> + mkbin([]); +make_bin_from_list(List, N) -> + list_to_binary([make_int(List, 8, 0), + make_bin_from_list(lists:nthtail(8, List), N-8)]). + + +make_int(_List, 0, Acc) -> Acc; +make_int([H|T], N, Acc) -> make_int(T, N-1, Acc bsl 1 bor H). + +bits_to_list([_H|T], 0) -> bits_to_list(T, 16#80); +bits_to_list([H|_]=List, Mask) -> + [case H band Mask of + 0 -> 0; + _ -> 1 + end|bits_to_list(List, Mask bsr 1)]; +bits_to_list([], _) -> []. + + +mkbin(L) when list(L) -> list_to_binary(L). diff --git a/lib/debugger/test/bs_match_int_SUITE.erl b/lib/debugger/test/bs_match_int_SUITE.erl new file mode 100644 index 0000000000..1159ac9ef8 --- /dev/null +++ b/lib/debugger/test/bs_match_int_SUITE.erl @@ -0,0 +1,230 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(bs_match_int_SUITE). + +-author('[email protected]'). +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + integer/1,signed_integer/1,dynamic/1,more_dynamic/1,mml/1]). + +-include("test_server.hrl"). + +-import(lists, [seq/2]). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [integer,signed_integer,dynamic,more_dynamic,mml]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(4)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +integer(suite) -> []; +integer(Config) when list(Config) -> + ?line 0 = get_int(mkbin([])), + ?line 0 = get_int(mkbin([0])), + ?line 42 = get_int(mkbin([42])), + ?line 255 = get_int(mkbin([255])), + ?line 256 = get_int(mkbin([1,0])), + ?line 257 = get_int(mkbin([1,1])), + ?line 258 = get_int(mkbin([1,2])), + ?line 258 = get_int(mkbin([1,2])), + ?line 65534 = get_int(mkbin([255,254])), + ?line 16776455 = get_int(mkbin([255,253,7])), + ?line 4245492555 = get_int(mkbin([253,13,19,75])), + ?line Eight = [200,1,19,128,222,42,97,111], + ?line cmp128(Eight, uint(Eight)), + ?line fun_clause(catch get_int(mkbin(seq(1,5)))), + ok. + +get_int(<<I:0>>) -> I; +get_int(<<I:8>>) -> I; +get_int(<<I:16>>) -> I; +get_int(<<I:24>>) -> I; +get_int(<<I:32>>) -> I. + +cmp128(<<I:128>>, I) -> equal; +cmp128(_B, _I) -> not_equal. + +signed_integer(suite) -> []; +signed_integer(Config) when list(Config) -> + ?line {no_match,_} = sint(mkbin([])), + ?line {no_match,_} = sint(mkbin([1,2,3])), + ?line 127 = sint(mkbin([127])), + ?line -1 = sint(mkbin([255])), + ?line -128 = sint(mkbin([128])), + ?line 42 = sint(mkbin([42,255])), + ?line 127 = sint(mkbin([127,255])). + +sint(Bin) -> + case Bin of + <<I:8/signed>> -> I; + <<I:8/signed,_:3,_:5>> -> I; + Other -> {no_match,Other} + end. + +uint(L) -> uint(L, 0). +uint([H|T], Acc) -> uint(T, Acc bsl 8 bor H); +uint([], Acc) -> Acc. + +dynamic(Config) when list(Config) -> + dynamic(mkbin([255]), 8), + dynamic(mkbin([255,255]), 16), + dynamic(mkbin([255,255,255]), 24), + dynamic(mkbin([255,255,255,255]), 32), + ok. + +dynamic(Bin, S1) when S1 >= 0 -> + S2 = size(Bin) * 8 - S1, + dynamic(Bin, S1, S2, (1 bsl S1) - 1, (1 bsl S2) - 1), + dynamic(Bin, S1-1); +dynamic(_Bin, _) -> ok. + +dynamic(Bin, S1, S2, A, B) -> +% io:format("~p ~p ~p ~p\n", [S1,S2,A,B]), + case Bin of + <<A:S1,B:S2>> -> + io:format("~p ~p ~p ~p\n", [S1,S2,A,B]), + ok; + _Other -> + erlang:error(badmatch, [Bin,S1,S2,A,B]) + end. + +more_dynamic(doc) -> "Extract integers at different alignments and of different sizes."; +more_dynamic(Config) when list(Config) -> + + % Unsigned big-endian numbers. + Unsigned = fun(Bin, List, SkipBef, N) -> + SkipAft = 8*size(Bin) - N - SkipBef, + <<_I1:SkipBef,Int:N,_I2:SkipAft>> = Bin, + Int = make_int(List, N, 0) + end, + ?line more_dynamic1(Unsigned, funny_binary(42)), + + % Signed big-endian numbers. + Signed = fun(Bin, List, SkipBef, N) -> + SkipAft = 8*size(Bin) - N - SkipBef, + <<_I1:SkipBef,Int:N/signed,_I2:SkipAft>> = Bin, + case make_signed_int(List, N) of + Int -> ok; + Other -> + io:format("Bin = ~p,", [Bin]), + io:format("SkipBef = ~p, N = ~p", [SkipBef,N]), + io:format("Expected ~p, got ~p", [Int,Other]), + ?t:fail() + end + end, + ?line more_dynamic1(Signed, funny_binary(43)), + + % Unsigned little-endian numbers. + UnsLittle = fun(Bin, List, SkipBef, N) -> + SkipAft = 8*size(Bin) - N - SkipBef, + <<_I1:SkipBef,Int:N/little,_I2:SkipAft>> = Bin, + Int = make_int(big_to_little(List, N), N, 0) + end, + ?line more_dynamic1(UnsLittle, funny_binary(44)), + + % Signed little-endian numbers. + SignLittle = fun(Bin, List, SkipBef, N) -> + SkipAft = 8*size(Bin) - N - SkipBef, + <<_I1:SkipBef,Int:N/signed-little,_I2:SkipAft>> = Bin, + Little = big_to_little(List, N), + Int = make_signed_int(Little, N) + end, + ?line more_dynamic1(SignLittle, funny_binary(45)), + + ok. + +funny_binary(N) -> + B0 = erlang:md5([N]), + {B1,_B2} = split_binary(B0, size(B0) div 2), + B1. + +more_dynamic1(Action, Bin) -> + BitList = bits_to_list(binary_to_list(Bin), 16#80), + more_dynamic2(Action, Bin, BitList, 0). + +more_dynamic2(Action, Bin, [_|T]=List, Bef) -> + more_dynamic3(Action, Bin, List, Bef, size(Bin)*8), + more_dynamic2(Action, Bin, T, Bef+1); +more_dynamic2(_Action, _Bin, [], _Bef) -> ok. + +more_dynamic3(Action, Bin, List, Bef, Aft) when Bef =< Aft -> +%% io:format("~p, ~p", [Bef,Aft-Bef]), + Action(Bin, List, Bef, Aft-Bef), + more_dynamic3(Action, Bin, List, Bef, Aft-1); +more_dynamic3(_, _, _, _, _) -> ok. + +big_to_little(List, N) -> big_to_little(List, N, []). + +big_to_little([B0,B1,B2,B3,B4,B5,B6,B7|T], N, Acc) when N >= 8 -> + big_to_little(T, N-8, [B0,B1,B2,B3,B4,B5,B6,B7|Acc]); +big_to_little(List, N, Acc) -> lists:sublist(List, 1, N) ++ Acc. + +make_signed_int(_List, 0) -> 0; +make_signed_int([0|_T]=List, N) -> make_int(List, N, 0); +make_signed_int([1|_T]=List0, N) -> + List1 = reversed_sublist(List0, N, []), + List2 = two_complement_and_reverse(List1, 1, []), + -make_int(List2, length(List2), 0). + +reversed_sublist(_List, 0, Acc) -> Acc; +reversed_sublist([H|T], N, Acc) -> reversed_sublist(T, N-1, [H|Acc]). + +two_complement_and_reverse([H|T], Carry, Acc) -> + Sum = 1-H+Carry, + two_complement_and_reverse(T, Sum div 2, [Sum rem 2|Acc]); +two_complement_and_reverse([], Carry, Acc) -> [Carry|Acc]. + +make_int(_List, 0, Acc) -> Acc; +make_int([H|T], N, Acc) -> make_int(T, N-1, Acc bsl 1 bor H). + +bits_to_list([_H|T], 0) -> bits_to_list(T, 16#80); +bits_to_list([H|_]=List, Mask) -> + [case H band Mask of + 0 -> 0; + _ -> 1 + end|bits_to_list(List, Mask bsr 1)]; +bits_to_list([], _) -> []. + +fun_clause({'EXIT',{function_clause,_}}) -> ok. +mkbin(L) when list(L) -> list_to_binary(L). + +mml(Config) when list(Config) -> + ?line single_byte_binary = mml_choose(<<42>>), + ?line multi_byte_binary = mml_choose(<<42,43>>). + +mml_choose(<<_A:8>>) -> single_byte_binary; +mml_choose(<<_A:8, _T/binary>>) -> multi_byte_binary. diff --git a/lib/debugger/test/bs_match_misc_SUITE.erl b/lib/debugger/test/bs_match_misc_SUITE.erl new file mode 100644 index 0000000000..5e1160a8e9 --- /dev/null +++ b/lib/debugger/test/bs_match_misc_SUITE.erl @@ -0,0 +1,152 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(bs_match_misc_SUITE). + +-author('[email protected]'). +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + bound_var/1,bound_tail/1,t_float/1,little_float/1,sean/1]). + +-include("test_server.hrl"). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [bound_var,bound_tail,t_float,little_float,sean]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +bound_var(doc) -> "Test matching of bound variables."; +bound_var(Config) when list(Config) -> + ?line ok = bound_var(42, 13, <<42,13>>), + ?line nope = bound_var(42, 13, <<42,255>>), + ?line nope = bound_var(42, 13, <<154,255>>), + ok. + +bound_var(A, B, <<A:8,B:8>>) -> ok; +bound_var(_, _, _) -> nope. + +bound_tail(doc) -> "Test matching of a bound tail."; +bound_tail(Config) when list(Config) -> + ?line ok = bound_tail(<<>>, <<13,14>>), + ?line ok = bound_tail(<<2,3>>, <<1,1,2,3>>), + ?line nope = bound_tail(<<2,3>>, <<1,1,2,7>>), + ?line nope = bound_tail(<<2,3>>, <<1,1,2,3,4>>), + ?line nope = bound_tail(<<2,3>>, <<>>), + ok. + +bound_tail(T, <<_:16,T/binary>>) -> ok; +bound_tail(_, _) -> nope. + +t_float(Config) when list(Config) -> + F = f1(), + G = f_one(), + + ?line G = match_float(<<63,128,0,0>>, 32, 0), + ?line G = match_float(<<63,240,0,0,0,0,0,0>>, 64, 0), + + ?line fcmp(F, match_float(<<F:32/float>>, 32, 0)), + ?line fcmp(F, match_float(<<F:64/float>>, 64, 0)), + ?line fcmp(F, match_float(<<1:1,F:32/float,127:7>>, 32, 1)), + ?line fcmp(F, match_float(<<1:1,F:64/float,127:7>>, 64, 1)), + ?line fcmp(F, match_float(<<1:13,F:32/float,127:3>>, 32, 13)), + ?line fcmp(F, match_float(<<1:13,F:64/float,127:3>>, 64, 13)), + ok. + + +fcmp(F1, F2) when (F1 - F2) / F2 < 0.0000001 -> ok. + +match_float(Bin0, Fsz, I) -> + Bin = make_sub_bin(Bin0), + Bsz = size(Bin) * 8, + Tsz = Bsz - Fsz - I, + <<_:I,F:Fsz/float,_:Tsz>> = Bin, + F. + +little_float(Config) when list(Config) -> + F = f2(), + G = f_one(), + + ?line G = match_float_little(<<0,0,0,0,0,0,240,63>>, 64, 0), + ?line G = match_float_little(<<0,0,128,63>>, 32, 0), + + ?line fcmp(F, match_float_little(<<F:32/float-little>>, 32, 0)), + ?line fcmp(F, match_float_little(<<F:64/float-little>>, 64, 0)), + ?line fcmp(F, match_float_little(<<1:1,F:32/float-little,127:7>>, 32, 1)), + ?line fcmp(F, match_float_little(<<1:1,F:64/float-little,127:7>>, 64, 1)), + ?line fcmp(F, match_float_little(<<1:13,F:32/float-little,127:3>>, 32, 13)), + ?line fcmp(F, match_float_little(<<1:13,F:64/float-little,127:3>>, 64, 13)), + + ok. + +match_float_little(Bin0, Fsz, I) -> + Bin = make_sub_bin(Bin0), + Bsz = size(Bin) * 8, + Tsz = Bsz - Fsz - I, + <<_:I,F:Fsz/float-little,_:Tsz>> = Bin, + F. + + +make_sub_bin(Bin0) -> + Sz = size(Bin0), + Bin1 = <<37,Bin0/binary,38,39>>, + <<_:8,Bin:Sz/binary,_:8,_:8>> = Bin1, + Bin. + +f1() -> + 3.1415. + +f2() -> + 2.7133. + +f_one() -> + 1.0. + +sean(Config) when list(Config) -> + ?line small = sean1(<<>>), + ?line small = sean1(<<1>>), + ?line small = sean1(<<1,2>>), + ?line small = sean1(<<1,2,3>>), + ?line large = sean1(<<1,2,3,4>>), + + ?line small = sean1(<<4>>), + ?line small = sean1(<<4,5>>), + ?line small = sean1(<<4,5,6>>), + ?line {'EXIT',{function_clause,_}} = (catch sean1(<<4,5,6,7>>)), + ok. + +sean1(<<B/binary>>) when size(B) < 4 -> small; +sean1(<<1, _B/binary>>) -> large. diff --git a/lib/debugger/test/bs_match_tail_SUITE.erl b/lib/debugger/test/bs_match_tail_SUITE.erl new file mode 100644 index 0000000000..7fa16b3c6a --- /dev/null +++ b/lib/debugger/test/bs_match_tail_SUITE.erl @@ -0,0 +1,106 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(bs_match_tail_SUITE). + +-author('[email protected]'). +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + aligned/1,unaligned/1,zero_tail/1]). + +-include("test_server.hrl"). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [aligned,unaligned,zero_tail]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +aligned(doc) -> "Test aligned tails."; +aligned(Config) when list(Config) -> + ?line Tail1 = mkbin([]), + ?line {258,Tail1} = al_get_tail_used(mkbin([1,2])), + ?line Tail2 = mkbin(lists:seq(1, 127)), + ?line {35091,Tail2} = al_get_tail_used(mkbin([137,19|Tail2])), + + ?line 64896 = al_get_tail_unused(mkbin([253,128])), + ?line 64895 = al_get_tail_unused(mkbin([253,127|lists:seq(42, 255)])), + + ?line Tail3 = mkbin(lists:seq(0, 19)), + ?line {0,Tail1} = get_dyn_tail_used(Tail1, 0), + ?line {0,Tail3} = get_dyn_tail_used(mkbin([Tail3]), 0), + ?line {73,Tail3} = get_dyn_tail_used(mkbin([73|Tail3]), 8), + + ?line 0 = get_dyn_tail_unused(mkbin([]), 0), + ?line 233 = get_dyn_tail_unused(mkbin([233]), 8), + ?line 23 = get_dyn_tail_unused(mkbin([23,22,2]), 8), + ok. + +al_get_tail_used(<<A:16,T/binary>>) -> {A,T}. +al_get_tail_unused(<<A:16,_T/binary>>) -> A. + +unaligned(doc) -> "Test that an non-aligned tail cannot be matched out."; +unaligned(Config) when list(Config) -> + ?line {'EXIT',{function_clause,_}} = (catch get_tail_used(mkbin([42]))), + ?line {'EXIT',{{badmatch,_},_}} = (catch get_dyn_tail_used(mkbin([137]), 3)), + ?line {'EXIT',{function_clause,_}} = (catch get_tail_unused(mkbin([42,33]))), + ?line {'EXIT',{{badmatch,_},_}} = (catch get_dyn_tail_unused(mkbin([44]), 7)), + ok. + +get_tail_used(<<A:1,T/binary>>) -> {A,T}. + +get_tail_unused(<<A:15,_/binary>>) -> A. + +get_dyn_tail_used(Bin, Sz) -> + <<A:Sz,T/binary>> = Bin, + {A,T}. + +get_dyn_tail_unused(Bin, Sz) -> + <<A:Sz,_T/binary>> = Bin, + A. + +zero_tail(doc) -> "Test that zero tails are tested correctly."; +zero_tail(Config) when list(Config) -> + ?line 7 = (catch test_zero_tail(mkbin([7]))), + ?line {'EXIT',{function_clause,_}} = (catch test_zero_tail(mkbin([1,2]))), + ?line {'EXIT',{function_clause,_}} = (catch test_zero_tail2(mkbin([1,2,3]))), + ok. + +test_zero_tail(<<A:8>>) -> A. + +test_zero_tail2(<<_A:4,_B:4>>) -> ok. + +mkbin(L) when list(L) -> list_to_binary(L). diff --git a/lib/debugger/test/bs_utf_SUITE.erl b/lib/debugger/test/bs_utf_SUITE.erl new file mode 100644 index 0000000000..3d69d2a101 --- /dev/null +++ b/lib/debugger/test/bs_utf_SUITE.erl @@ -0,0 +1,292 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% + +-module(bs_utf_SUITE). + +-export([all/1,init_all/1,finish_all/1, + init_per_testcase/2,fin_per_testcase/2, + utf8_roundtrip/1,unused_utf_char/1,utf16_roundtrip/1, + utf32_roundtrip/1,guard/1,extreme_tripping/1]). + +-include("test_server.hrl"). +-compile([no_jopt,time]). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [utf8_roundtrip,unused_utf_char,utf16_roundtrip, + utf32_roundtrip,guard,extreme_tripping]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +utf8_roundtrip(Config) when is_list(Config) -> + ?line [utf8_roundtrip_1(P) || P <- utf_data()], + ok. + +utf8_roundtrip_1({Str,Bin,Bin}) -> + ?line Str = utf8_to_list(Bin), + ?line Bin = list_to_utf8(Str), + ?line [ok = utf8_guard(C, <<42,C/utf8>>) || C <- Str], + ?line [error = utf8_guard(C, <<C/utf8>>) || C <- Str], + ok. + +utf8_guard(C, Bin) when <<42,C/utf8>> =:= Bin -> ok; +utf8_guard(_, _) -> error. + +utf8_to_list(<<C/utf8,T/binary>>) -> + [C|utf8_to_list(T)]; +utf8_to_list(<<>>) -> []. + +list_to_utf8(L) -> + list_to_utf8(L, <<>>). + +list_to_utf8([H|T], Bin) -> + list_to_utf8(T, <<Bin/binary,H/utf8>>); +list_to_utf8([], Bin) -> Bin. + +unused_utf_char(Config) when is_list(Config) -> + [true = utf8_len(Utf8) =:= length(Str) || + {Str,Utf8} <- utf_data()], + ok. + +utf8_len(B) -> + utf8_len(B, 0). + +utf8_len(<<_/utf8,T/binary>>, N) -> + utf8_len(T, N+1); +utf8_len(<<>>, N) -> N. + +utf16_roundtrip(Config) when is_list(Config) -> + ?line {Str,Big,Big,Little,Little} = utf16_data(), + ?line 4 = utf16_big_len(Big), + ?line 4 = utf16_little_len(Little), + ?line Str = big_utf16_to_list(Big), + ?line Str = little_utf16_to_list(Little), + + ?line Big = list_to_big_utf16(Str), + ?line Little = list_to_little_utf16(Str), + + ok. + +utf16_big_len(B) -> + utf16_big_len(B, 0). + +utf16_big_len(<<_/utf16,T/binary>>, N) -> + utf16_big_len(T, N+1); +utf16_big_len(<<>>, N) -> N. + +utf16_little_len(B) -> + utf16_little_len(B, 0). + +utf16_little_len(<<_/little-utf16,T/binary>>, N) -> + utf16_little_len(T, N+1); +utf16_little_len(<<>>, N) -> N. + +list_to_big_utf16(List) -> + list_to_big_utf16(List, <<>>). + +list_to_big_utf16([H|T], Bin) -> + list_to_big_utf16(T, <<Bin/binary,H/utf16>>); +list_to_big_utf16([], Bin) -> Bin. + +list_to_little_utf16(List) -> + list_to_little_utf16(List, <<>>). + +list_to_little_utf16([H|T], Bin) -> + list_to_little_utf16(T, <<Bin/binary,H/little-utf16>>); +list_to_little_utf16([], Bin) -> Bin. + +big_utf16_to_list(<<H/utf16,T/binary>>) -> + [H|big_utf16_to_list(T)]; +big_utf16_to_list(<<>>) -> []. + +little_utf16_to_list(<<H/little-utf16,T/binary>>) -> + [H|little_utf16_to_list(T)]; +little_utf16_to_list(<<>>) -> []. + +utf32_roundtrip(Config) when is_list(Config) -> + ?line {Str,Big,Big,Little,Little} = utf32_data(), + ?line 4 = utf32_big_len(Big), + ?line 4 = utf32_little_len(Little), + ?line Str = big_utf32_to_list(Big), + ?line Str = little_utf32_to_list(Little), + + ?line Big = list_to_big_utf32(Str), + ?line Little = list_to_little_utf32(Str), + + ok. + +utf32_big_len(B) -> + utf32_big_len(B, 0). + +utf32_big_len(<<_/utf32,T/binary>>, N) -> + utf32_big_len(T, N+1); +utf32_big_len(<<>>, N) -> N. + +utf32_little_len(B) -> + utf32_little_len(B, 0). + +utf32_little_len(<<_/little-utf32,T/binary>>, N) -> + utf32_little_len(T, N+1); +utf32_little_len(<<>>, N) -> N. + +list_to_big_utf32(List) -> + list_to_big_utf32(List, <<>>). + +list_to_big_utf32([H|T], Bin) -> + list_to_big_utf32(T, <<Bin/binary,H/utf32>>); +list_to_big_utf32([], Bin) -> Bin. + +list_to_little_utf32(List) -> + list_to_little_utf32(List, <<>>). + +list_to_little_utf32([H|T], Bin) -> + list_to_little_utf32(T, <<Bin/binary,H/little-utf32>>); +list_to_little_utf32([], Bin) -> Bin. + +big_utf32_to_list(<<H/utf32,T/binary>>) -> + [H|big_utf32_to_list(T)]; +big_utf32_to_list(<<>>) -> []. + +little_utf32_to_list(<<H/little-utf32,T/binary>>) -> + [H|little_utf32_to_list(T)]; +little_utf32_to_list(<<>>) -> []. + + +guard(Config) when is_list(Config) -> + ?line error = do_guard(16#D800), + ok. + +do_guard(C) when byte_size(<<C/utf8>>) =/= 42 -> ok; +do_guard(C) when byte_size(<<C/utf16>>) =/= 42 -> ok; +do_guard(C) when byte_size(<<C/utf32>>) =/= 42 -> ok; +do_guard(_) -> error. + +%% The purpose of this test is to make sure that +%% the delayed creation of sub-binaries works. + +extreme_tripping(Config) when is_list(Config) -> + ?line Unicode = lists:seq(0, 1024), + ?line Utf8 = unicode_to_utf8(Unicode, <<>>), + ?line Utf16 = utf8_to_utf16(Utf8, <<>>), + ?line Utf32 = utf8_to_utf32(Utf8, <<>>), + ?line Utf32 = utf16_to_utf32(Utf16, <<>>), + ?line Utf8 = utf32_to_utf8(Utf32, <<>>), + ?line Unicode = utf32_to_unicode(Utf32), + ok. + +unicode_to_utf8([C|T], Bin) -> + unicode_to_utf8(T, <<Bin/bytes,C/utf8>>); +unicode_to_utf8([], Bin) -> Bin. + +utf8_to_utf16(<<C/utf8,T/binary>>, Bin) -> + utf8_to_utf16(T, <<Bin/bytes,C/utf16>>); +utf8_to_utf16(<<>>, Bin) -> Bin. + +utf16_to_utf32(<<C/utf16,T/binary>>, Bin) -> + utf16_to_utf32(T, <<Bin/bytes,C/utf32>>); +utf16_to_utf32(<<>>, Bin) -> Bin. + +utf8_to_utf32(<<C/utf8,T/binary>>, Bin) -> + utf8_to_utf32(T, <<Bin/bytes,C/utf32>>); +utf8_to_utf32(<<>>, Bin) -> Bin. + +utf32_to_utf8(<<C/utf32,T/binary>>, Bin) -> + utf32_to_utf8(T, <<Bin/bytes,C/utf8>>); +utf32_to_utf8(<<>>, Bin) -> Bin. + +utf32_to_unicode(<<C/utf32,T/binary>>) -> + [C|utf32_to_unicode(T)]; +utf32_to_unicode(<<>>) -> []. + +utf_data() -> +%% From RFC-3629. + + %% Give the compiler a change to do some constant propagation. + NotIdentical = 16#2262, + + [ + %% "A<NOT IDENTICAL TO><ALPHA>." + {[16#0041,NotIdentical,16#0391,16#002E], + <<16#0041/utf8,NotIdentical/utf8,16#0391/utf8,16#002E/utf8>>, + <<16#41,16#E2,16#89,16#A2,16#CE,16#91,16#2E>>}, + + %% Korean "hangugeo" (meaning "the Korean language") + {[16#D55C,16#AD6D,16#C5B4], + <<16#D55C/utf8,16#AD6D/utf8,16#C5B4/utf8>>, + <<16#ED,16#95,16#9C,16#EA,16#B5,16#AD,16#EC,16#96,16#B4>>}, + + %% Japanese "nihongo" (meaning "the Japanese language"). + {[16#65E5,16#672C,16#8A9E], + <<16#65E5/utf8,16#672C/utf8,16#8A9E/utf8>>, + <<16#E6,16#97,16#A5,16#E6,16#9C,16#AC,16#E8,16#AA,16#9E>>} + ]. + +utf16_data() -> + %% Example from RFC-2781. "*=Ra", where "*" represents a + %% hypothetical Ra hieroglyph (code point 16#12345). + + %% Give the compiler a change to do some constant propagation. + RaHieroglyph = 16#12345, + + %% First as a list of Unicode characters. + {[RaHieroglyph,16#3D,16#52,16#61], + + %% Big endian (the two binaries should be equal). + <<RaHieroglyph/big-utf16,16#3D/big-utf16,16#52/big-utf16,16#61/big-utf16>>, + <<16#D8,16#08,16#DF,16#45,16#00,16#3D,16#00,16#52,16#00,16#61>>, + + %% Little endian (the two binaries should be equal). + <<RaHieroglyph/little-utf16,16#3D/little-utf16, + 16#52/little-utf16,16#61/little-utf16>>, + <<16#08,16#D8,16#45,16#DF,16#3D,16#00,16#52,16#00,16#61,16#00>>}. + +utf32_data() -> + %% "A<NOT IDENTICAL TO><ALPHA>." + NotIdentical = 16#2262, + {[16#0041,NotIdentical,16#0391,16#002E], + + %% Big endian. + <<16#0041/utf32,NotIdentical/utf32,16#0391/utf32,16#002E/utf32>>, + <<16#41:32,NotIdentical:32,16#0391:32,16#2E:32>>, + + %% Little endian. + <<16#0041/little-utf32,NotIdentical/little-utf32, + 16#0391/little-utf32,16#002E/little-utf32>>, + <<16#41:32/little,NotIdentical:32/little, + 16#0391:32/little,16#2E:32/little>>}. diff --git a/lib/debugger/test/bug_SUITE.erl b/lib/debugger/test/bug_SUITE.erl new file mode 100644 index 0000000000..cf732c8115 --- /dev/null +++ b/lib/debugger/test/bug_SUITE.erl @@ -0,0 +1,79 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(bug_SUITE). + +-include("test_server.hrl"). + +-export([all/1]). + +-export([ticket_tests/1]). + +-export([otp2163/1, otp4845/1]). + +all(suite) -> [ticket_tests]. + +ticket_tests(doc) -> ["Tests tickets regarding bugs"]; +ticket_tests(suite) -> [otp2163, otp4845]. + +otp2163(doc) -> ["BIF exit reason"]; +otp2163(suite) -> []; +otp2163(Config) when list(Config) -> + ?line DataDir = ?config(data_dir, Config), + + %% First compile and get the expected results: + + ?line FileName = filename:join(DataDir, "otp2163"), + ?line {module,otp2163} = code:load_abs(FileName), + + ?line {'EXIT',{badarg,[ApplyRes|_]}} = (catch otp2163:apply_test()), + ?line {'EXIT',{badarg,[ListRes|_]}} = (catch otp2163:list_to_atom_test()), + + %% Then interpret, and check if the results are OK. + ?line {module,otp2163} = int:i(FileName), + + ?line ok = io:format("Expecting ~p", [ApplyRes]), + ?line {'EXIT',{badarg,[ApplyRes|_]}} = (catch otp2163:apply_test()), + ?line ok = io:format("Expecting ~p", [ListRes]), + ?line {'EXIT',{badarg,[ListRes|_]}} = (catch otp2163:list_to_atom_test()), + ok. + + +otp4845(doc) -> ["BIF not loading and not bug compatible, OTP-4845 OTP-4859"]; +otp4845(suite) -> []; +otp4845(Config) when list(Config) -> + ?line DataDir = ?config(data_dir, Config), + + %% First compile and get the expected results: + + ?line FileName = filename:join(DataDir, "otp4845"), + ?line {module,otp4845} = code:load_abs(FileName), + + ?line CompiledRes = (catch otp4845:test()), + ?line ok = io:format("Compiled ~p", [CompiledRes]), + + %% Then interpret, and check if the results are OK. + ?line {module,otp4845} = int:i(FileName), + + ?line IntRes = (catch otp4845:test()), + ?line ok = io:format("Interpreted ~p", [IntRes]), + + ?line CompiledRes = IntRes, + ok. diff --git a/lib/debugger/test/bug_SUITE_data/Makefile.src b/lib/debugger/test/bug_SUITE_data/Makefile.src new file mode 100644 index 0000000000..792b3299e1 --- /dev/null +++ b/lib/debugger/test/bug_SUITE_data/Makefile.src @@ -0,0 +1,25 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2000-2010. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +all: otp2163.@EMULATOR@ otp4845.@EMULATOR@ +EFLAGS=+debug_info + +otp2163.@EMULATOR@: otp2163.erl + erlc $(EFLAGS) otp2163.erl +otp4845.@EMULATOR@: otp4845.erl + erlc $(EFLAGS) otp4845.erl diff --git a/lib/debugger/test/bug_SUITE_data/otp2163.erl b/lib/debugger/test/bug_SUITE_data/otp2163.erl new file mode 100644 index 0000000000..4e3c487ef7 --- /dev/null +++ b/lib/debugger/test/bug_SUITE_data/otp2163.erl @@ -0,0 +1,60 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%%% Purpose : Test OTP-2163 + +-module(otp2163). + + +-export([apply_test/0, list_to_atom_test/0, error/1]). +-export([test/0]). + +apply_test() -> + M = {}, + apply(M,dummy,[]). + +list_to_atom_test() -> + list_to_atom(id({1,2})). + +id(I) -> I. + +%% OTP-4845 OTP 4859 +-record(sune, {a,sd,g,s}). +-record(error, {a,sd,g,s}). + +test() -> + sune = error(#sune{}), + {false,false} = error(false), + {true,true} = error(true), + error(#error{}). + +error(X) -> + if + is_record(X, sune) -> + sune; + X -> + {true, X}; + not X -> + {false, X}; + not is_record(X, error) -> + error; + true -> + ok + end. diff --git a/lib/debugger/test/bug_SUITE_data/otp4845.erl b/lib/debugger/test/bug_SUITE_data/otp4845.erl new file mode 100644 index 0000000000..18ca08b977 --- /dev/null +++ b/lib/debugger/test/bug_SUITE_data/otp4845.erl @@ -0,0 +1,52 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%%% Purpose : Test OTP-4845 + +-module(otp4845). + + +%%-export([error/1]). +-export([test/0]). + +%% OTP-4845 OTP 4859 +-record(sune, {a,sd,g,s}). +-record(error, {a,sd,g,s}). + +test() -> + R1 = error(#sune{}), + R2 = error(false), + R3 = error(true), + R4 = error(#error{}), + {R1,R2,R3,R4}. + +error(X) -> + if + is_record(X, sune) -> + sune; + X -> + {true, X}; + not X -> + {false, X}; + not is_record(X, error) -> + error; + true -> + ok + end. diff --git a/lib/debugger/test/cleanup.erl b/lib/debugger/test/cleanup.erl new file mode 100644 index 0000000000..59b4c35ac7 --- /dev/null +++ b/lib/debugger/test/cleanup.erl @@ -0,0 +1,45 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(cleanup). + +-export([all/1, cleanup/1]). + +-include("test_server.hrl"). + +all(suite) -> {req, [interpreter], [cleanup]}. + +cleanup(suite) -> []; +cleanup(_) -> + ?line Mods = int:interpreted(), + ?line ok = int:n(Mods), + case whereis(interpret) of + undefined -> + ok; + Pid -> + exit(Pid, kill) + end, + case whereis(int_db) of + undefined -> + ok; + Pid2 -> + exit(Pid2, kill) + end, + ok. diff --git a/lib/debugger/test/dbg_ui_SUITE.erl b/lib/debugger/test/dbg_ui_SUITE.erl new file mode 100644 index 0000000000..629aac9fd6 --- /dev/null +++ b/lib/debugger/test/dbg_ui_SUITE.erl @@ -0,0 +1,288 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(dbg_ui_SUITE). + + +-include("test_server.hrl"). + + +% Test server specific exports +-export([all/1]). +-export([function_tests/1]). + + +% Test cases must be exported. +-export ([dbg_ui/1]). + + + + + +% Manual test suites/cases exports +-export([manual_tests/1]). +-export([start1/1, interpret1/1, quit1/1, + start2/1, interpret2/1, break2/1, options2/1, quit2/1, + interpret3/1, all_step3/1,all_next3/1,save3/1,restore3/1,finish3/1, + killinit3/1, killone3/1, killall3/1, deleteone3/1, deleteall3/1, + viewbreak4/1, delete4/1, + attach5/1, normal5/1, exit5/1, options5/1, + distsetup6/1, all_step6/1, all_next6/1]). + + + + +-export([init_per_testcase/2, fin_per_testcase/2]). + + + +init_per_testcase(_Func, Config) -> + Dog=test_server:timetrap(60*1000), + [{watchdog, Dog}|Config]. + +fin_per_testcase(_Func, Config) -> + Dog=?config(watchdog, Config), + test_server:timetrap_cancel(Dog). + + +all (suite)-> + {req, [debugger], [function_tests, manual_tests]}. + + +function_tests (doc) -> + ["Tests documented functions"]; + +function_tests (suite) -> + [dbg_ui]. + + + +dbg_ui (doc) -> + ["Debugger GUI"]; + +dbg_ui (suite) -> + []; + +dbg_ui (_Config) -> + case os:getenv("DISPLAY") of + false -> + {skipped,"No display"}; + Other when list(Other) -> +% ?line {ok, Pid} = debugger:start (), +% ?line ok = is_pid (Pid), +% ?line true = erlang:is_process_alive(Pid), +% ?line ok = debugger:stop(), +% ?line false = erlang:is_process_alive(Pid) + {skipped,"Gunilla: Workaround"} + end. + + + + + + +%% check/2 - returns the result for the specified testcase. +%% pass - means the user has run the case, and it passed +%% fail - means the user has run the case, and it failed +%% unknown - means the user has (tried to) run the case, and the result is unclear. +%% skip - means the user has not yet run the case. + +check(Case, Config) -> + + ?line DataDir = ?config(data_dir, Config), + ?line ResultFileName = filename:join([DataDir, "manual_results.erl"]), + case file:consult(ResultFileName) of + {ok, Results} -> + ?line io:format("Results: ~p~n",[Results]), + case Results of + [] -> + no_result; + %% Incomplete "sanity" check of file contents. + [{_Key,_Value}|_Rest] -> + case lists:keysearch(Case, 1, Results) of + {value, {Case, Value}} -> + Value; % pass, fail, unknown + false -> + no_result; % skip + _Otherwise -> + {error, "Contents of results file not valid"} + end; + _Otherwise2 -> + {error, "Contents of results file not valid"} + end; + _Otherwise3 -> + {error, "Problems reading results file"} + end. + + + + + + +-define(MAN_CASE(Name,Doc, Description), + Name(doc) -> [Doc]; + Name(suite) -> []; + Name(Config) -> + ?line io:format("Checking ~p~n",[Name]), + ?line io:format("Config = ~p~n",[Config]), + case check(Name, Config) of + pass -> + ?line ok; + fail -> + ?line test_server:fail("Manual test failed"); + unknown -> + ?line {skipped, "Manual test result unknown"}; + + no_result -> + ?line {skipped, Description}; + + {error, _Reason} -> +%% Text = lists:flatten( +%% io_lib:format("[File problem: ~s]~s", +%% [Reason,Description])), + ?line {skipped, Description} + end + ). + + + + +manual_tests(doc) -> ["Manual tests"]; +manual_tests(suite) -> [start1, interpret1, quit1, + start2, interpret2, break2, options2, + interpret3, all_step3,all_next3,save3,restore3,finish3, + killinit3, killone3, killall3, deleteone3, deleteall3, + viewbreak4, delete4, + attach5, normal5, exit5, options5, + distsetup6, all_step6, all_next6 + ]. + + + + + + +%% SET 1 +?MAN_CASE(start1, "Start the debugger from the toolbar", + "Before proceeding with the test cases, please move or remove +the directory .erlang_tools/debugger in your home directory. Next, +please start the debugger from the toolbar"). + +?MAN_CASE(interpret1, "Interpreting modules", + "In this test case and all of the ones following, the source code +files to use can be found in the test data directory for this debugger test + suite (probably in +/clearcase/otp/tools/debugger/test/dbg_ui_SUITE_data/manual_data/src ). +Interpret one module"). + +?MAN_CASE(quit1, "Quit the debugger", +"Quit the debugger using File->Exit in the main window"). + + +%% SET 2 +?MAN_CASE(start2, "Start the debugger from the shell", +"Start the debugger from the shell. Use debugger:start()"). + +?MAN_CASE(interpret2, "Interpret all modules", +"Interpret all modules"). + +?MAN_CASE(break2, "Set break points", +"Set break points"). + +?MAN_CASE(options2, "Set options to attach on break", +"Set options to attach on break"). + +?MAN_CASE(quit2, "Quit the debugger", +"Quit the debugger using the close box in the main window title frame"). + + +%% SET3 +?MAN_CASE(interpret3, "Test attach options", +"Start the debugger and interpret the modules [test, lists1, ordsets1]. Close the Interpret dialog. Set Attach on First Call and Attach on Break."). + +?MAN_CASE(all_step3, "Click Step through all evaluation", +"In the shell, call test:test1(). Use the Step button, the Process->Step menu item and the ctrl-s shortcut to step through the *entire* execution of the call. (Approx 36 steps). Then close the Attach window. The result printed in the shell should be: {\"peter\",[1,2,4,a,b,c],\"olin\"}"). + +?MAN_CASE(all_next3,"Click Next through all evaluation", +"Again call test:test1() in the shell. This time Use the Next button, the Process->Next menu and the ctrl-n shortcut to quickly step over the execution of the four lines in the test1-function. The result printed in the shell should be: {\"peter\",[1,2,4,a,b,c],\"olin\"}"). + +?MAN_CASE(save3, "Save the debugger state", +"Use File->Save Settings to save the debugger state with the name 'three.state'"). + +?MAN_CASE(restore3,"Quit the debugger, restart and restore the state", +"Quit the debugger. Start it again. Use File->Load Settings to restore the state saved in 'three.state'. Check that the Attach-options are the same as what you set them to in the interpret3 test case. Check that the three modules [test,lists1,ordsets1] are interpreted."). + + +?MAN_CASE(finish3, "Finish the current function body", +"Call the fucntion test:test1() from the shell. Press Finish to evaluate the remaining lines in the function. The result printed in the shell should be: {\"peter\",[1,2,4,a,b,c],\"olin\"}"). + +?MAN_CASE(killinit3,"Set up for killing and clearing processes", +"Call test:test2() from the shell. Set a break point at the last line of test:test2. Click Continue. This should open three new attach windows. One for each spawn called in test:test2/0. "). + +?MAN_CASE(killone3, "Kill a process and clear it", +"In one of the newly openend Attach windows: select Process->Kill. A message should appear above the Code Area in the Attach window. Use Windows->Monitor to verify that the Monitor window also shows that the process has been killed. In the Monitor window: select Edit->Clear. This should do two things: 1) close/remove the window of the killed process. 2) Remove the entry of the killed process from the monitor window."). + +?MAN_CASE(killall3,"KIll all processes, and clear them", +"In the Monitor window: Select Edit->Kill All. Verify that all processes have been killed (in their respective windows and in the monitor window). Windows will be raised as their processes die. Next select, Edit->Clear. All attach windows should now be closed. Their entris should also disappear from the monitor window. The shell should have reported: ** exited: killed **"). + +?MAN_CASE(deleteone3,"Delete/uniterpret one module", +"In the Monitor window: Select Module->test->Delete. This should remove the breakpoints set in the test module, and the test module should disappear from the Module menu."). + +?MAN_CASE(deleteall3,"Delete/uniterpret all modules", +"In the Monitor window: Select Module->Delete All Modules. This should remove all modules from the Module menu. "). + +%% SET 4 + + + +?MAN_CASE(viewbreak4, "Test the View window", +"Restore the settings from the three.state file again. In the Monitor window: Use Module->test->View to view the source code of the test module. In the View window, select Break->Line Break and set a break at line 53. Check that it appears in the View window and in the Monitor Window Break-menu. Also in the View window, select Break->Function Break and set a break at function test:test4. Check that the break (at line 59) appears in the View Window and in the Monitor Window Break-menu."). + +?MAN_CASE(delete4, "Remove breaks", +"Use the Break->Delete All function in the View window to remove all breaks in the test module. Check that they are all removed. Close the View window."). + +%% SET 5 + +?MAN_CASE(attach5,"Set attach options", +"Set the attach options to only attach on exit"). + +?MAN_CASE(normal5, "Test normal exit", +"Call test:test12(normal) in the shell. This should return the atom 'done', and no windows should be opened."). + +?MAN_CASE(exit5, "Test abnormal exit", +"Call test:test12(crash) in the shell. This should give the error message ** exited: crash **, and an attach window should be opened highlighting the last line in the test12-function."). + +?MAN_CASE(options5, "Experiment with the frames in the attach window", +"Try all possible configurations of the [Button, Evaluator, Bindings, Trace] Frames in the attach window and see that the expected frames are shown/hidden."). + + +%% SET 6 (Distribution) + +?MAN_CASE(distsetup6,"Set up distribution", +"Start two erlang systems [foo,bar] (with option -sname), make them aware of eachother using net_adm:ping/1. Start the debugger on foo. Interpret the modules [test, lists1, ordsets1]. Set attach on First call. "). + + + + +?MAN_CASE(all_step6, "Click Step through all evaluation", +"In the bar shell, call test:test1().This should open an attach window. Use the Step button, the Process->Step menu item and the ctrl-s shortcut to step through the *entire* execution of the call. (Approx 36 steps). Then close the Attach window. The result printed in the bar shell should be: {\"peter\",[1,2,4,a,b,c],\"olin\"}"). + +?MAN_CASE(all_next6,"Click Next through all evaluation", +"Again, in the bar shell, call test:test1(). This time Use the Next button, the Process->Next menu and the ctrl-n shortcut to quickly step over the execution of the four lines in the test1-function. The result printed in the shell should be: {\"peter\",[1,2,4,a,b,c],\"olin\"}"). diff --git a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl new file mode 100644 index 0000000000..0214983c11 --- /dev/null +++ b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/lists1.erl @@ -0,0 +1,469 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%% Purpose : Basic lists processing functions. + +-module(lists1). + + +-export([member/2, append/2, append/1, subtract/2, reverse/1, reverse/2, + nth/2, nthtail/2, prefix/2, suffix/2, last/1, + seq/2, seq/3, sum/1, duplicate/2, min/1, max/1, sublist/2, sublist/3, + delete/2, sort/1, merge/2, concat/1, + flatten/1, flatten/2, flat_length/1, flatlength/1, + keymember/3, keysearch/3, keydelete/3, keyreplace/4, + keysort/2, keymerge/3, keymap/3, keymap/4]). + +-export([all/2,any/2,map/2,flatmap/2,foldl/3,foldr/3,filter/2,zf/2, + mapfoldl/3,mapfoldr/3,foreach/2,takewhile/2,dropwhile/2,splitwith/2]). +-export([all/3,any/3,map/3,flatmap/3,foldl/4,foldr/4,filter/3,zf/3, + mapfoldl/4,mapfoldr/4,foreach/3]). + +%% member(X, L) -> (true | false) +%% test if X is a member of the list L + +member(X, [X|_]) -> true; +member(X, [_|Y]) -> + member(X, Y); +member(X, []) -> false. + +%% append(X, Y) appends lists X and Y + +append(L1, L2) -> L1 ++ L2. + +%% append(L) appends the list of lists L + +append([E]) -> E; +append([H|T]) -> H ++ append(T); +append([]) -> []. + +%% subtract(List1, List2) subtract elements in List2 form List1. + +subtract(L1, L2) -> L1 -- L2. + +%% reverse(L) reverse all elements in the list L + +reverse(X) -> reverse(X, []). + +reverse([H|T], Y) -> + reverse(T, [H|Y]); +reverse([], X) -> X. + +%% nth(N, L) returns the N`th element of the list L +%% nthtail(N, L) returns the N`th tail of the list L + +nth(1, [H|T]) -> H; +nth(N, [_|T]) when N > 1 -> + nth(N - 1, T). + +nthtail(1, [H|T]) -> T; +nthtail(N, [H|T]) when N > 1 -> + nthtail(N - 1, T); +nthtail(0, L) when list(L) -> L. + +%% prefix(Prefix, List) -> (true | false) + +prefix([X|PreTail], [X|Tail]) -> + prefix(PreTail, Tail); +prefix([], List) -> true; +prefix(_,_) -> false. + + +%% suffix(Suffix, List) -> (true | false) + +suffix(Suffix, Suffix) -> true; +suffix(Suffix, [_|Tail]) -> + suffix(Suffix, Tail); +suffix(Suffix, []) -> false. + +%% last(List) returns the last element in a list. + +last([E]) -> E; +last([E|Es]) -> + last(Es). + +%% seq(Min, Max) -> [Min,Min+1, ..., Max] +%% seq(Min, Max, Incr) -> [Min,Min+Incr, ..., Max] +%% returns the sequence Min..Max +%% Min <= Max and Min and Max must be integers + +seq(Min, Max) when integer(Min), integer(Max), Min =< Max -> + seq(Min, Max, 1, []). + +seq(Min, Max, Incr) -> + seq(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []). + +seq(Min, Min, I, L) -> [Min|L]; +seq(Min, Max, I, L) -> seq(Min, Max-I, I, [Max|L]). + +%% sum(L) suns the sum of the elements in L + +sum(L) -> sum(L, 0). +sum([H|T], Sum) -> sum(T, Sum + H); +sum([], Sum) -> Sum. + +%% duplicate(N, X) -> [X,X,X,.....,X] (N times) +%% return N copies of X + +duplicate(N, X) when integer(N), N >= 0 -> duplicate(N, X, []). + +duplicate(0, _, L) -> L; +duplicate(N, X, L) -> duplicate(N-1, X, [X|L]). + + +%% min(L) -> returns the minimum element of the list L + +min([H|T]) -> min(T, H). + +min([H|T], Min) when H < Min -> min(T, H); +min([_|T], Min) -> min(T, Min); +min([], Min) -> Min. + +%% max(L) -> returns the maximum element of the list L + +max([H|T]) -> max(T, H). + +max([H|T], Max) when H > Max -> max(T, H); +max([_|T], Max) -> max(T, Max); +max([], Max) -> Max. + +%% sublist(List, Start, Length) +%% Returns the sub-list starting at Start of length Length. + +sublist(List, S, L) when L >= 0 -> + sublist(nthtail(S-1, List), L). + +sublist([H|T], L) when L > 0 -> + [H|sublist(T, L-1)]; +sublist(List, L) -> []. + +%% delete(Item, List) -> List' +%% Delete the first occurance of Item from the list L. + +delete(Item, [Item|Rest]) -> Rest; +delete(Item, [H|Rest]) -> + [H|delete(Item, Rest)]; +delete(Item, []) -> []. + +%% sort(L) -> sorts the list L + +sort([X]) -> [X]; +sort([]) -> []; +sort(X) -> split_and_sort(X, [], []). + +split_and_sort([A,B|T], X, Y) -> + split_and_sort(T, [A|X], [B|Y]); +split_and_sort([H], X, Y) -> + split_and_sort([], [H|X], Y); +split_and_sort([], X, Y) -> + merge(sort(X), sort(Y), []). + +%% merge(X, Y) -> L +%% merges two sorted lists X and Y + +merge(X, Y) -> merge(X, Y, []). + +merge([H1|T1], [H2|T2], L) when H1 < H2 -> + merge(T1, [H2|T2], [H1|L]); +merge(T1, [H2|T2], L) -> + merge(T1, T2, [H2|L]); +merge([H|T], T2, L) -> + merge(T, T2, [H|L]); +merge([], [], L) -> + reverse(L). + +%% concat(L) concatinate the list representation of the elements +%% in L - the elements in L can be atoms, integers of strings. +%% Returns a list of characters. + +concat(List) -> + flatmap(fun thing_to_list/1, List). + +thing_to_list(X) when integer(X) -> integer_to_list(X); +thing_to_list(X) when float(X) -> float_to_list(X); +thing_to_list(X) when atom(X) -> atom_to_list(X); +thing_to_list(X) when list(X) -> X. %Assumed to be a string + +%% flatten(List) +%% flatten(List, Tail) +%% Flatten a list, adding optional tail. + +flatten(List) -> + flatten(List, [], []). + +flatten(List, Tail) -> + flatten(List, [], Tail). + +flatten([H|T], Cont, Tail) when list(H) -> + flatten(H, [T|Cont], Tail); +flatten([H|T], Cont, Tail) -> + [H|flatten(T, Cont, Tail)]; +flatten([], [H|Cont], Tail) -> + flatten(H, Cont, Tail); +flatten([], [], Tail) -> + Tail. + +%% flat_length(List) (undocumented can be rmove later) +%% Calculate the length of a list of lists. + +flat_length(List) -> flatlength(List). + +%% flatlength(List) +%% Calculate the length of a list of lists. + +flatlength(List) -> + flatlength(List, 0). + +flatlength([H|T], L) when list(H) -> + flatlength(H, flatlength(T, L)); +flatlength([H|T], L) -> + flatlength(T, L + 1); +flatlength([], L) -> L. + +%% keymember(Key, Index, [Tuple]) +%% keysearch(Key, Index, [Tuple]) +%% keydelete(Key, Index, [Tuple]) +%% keyreplace(Key, Index, [Tuple], NewTuple) +%% keysort(Index, [Tuple]) +%% keymerge(Index, [Tuple], [Tuple]) +%% keymap(Function, Index, [Tuple]) +%% keymap(Function, ExtraArgs, Index, [Tuple]) + +keymember(Key, N, [T|Ts]) when element(N, T) == Key -> true; +keymember(Key, N, [T|Ts]) -> + keymember(Key, N, Ts); +keymember(Key, N, []) -> false. + +keysearch(Key, N, [H|T]) when element(N, H) == Key -> + {value, H}; +keysearch(Key, N, [H|T]) -> + keysearch(Key, N, T); +keysearch(Key, N, []) -> false. + +keydelete(Key, N, [H|T]) when element(N, H) == Key -> T; +keydelete(Key, N, [H|T]) -> + [H|keydelete(Key, N, T)]; +keydelete(Key, N, []) -> []. + +keyreplace(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key -> + [New|Tail]; +keyreplace(Key, Pos, [H|T], New) -> + [H|keyreplace(Key, Pos, T, New)]; +keyreplace(Key, Pos, [], New) -> []. + +keysort(Index, [X]) -> [X]; +keysort(Index, []) -> []; +keysort(Index, X) -> split_and_keysort(X, [], [], Index). + +split_and_keysort([A,B|T], X, Y, Index) -> + split_and_keysort(T, [A|X], [B|Y], Index); +split_and_keysort([H], X, Y, Index) -> + split_and_keysort([], [H|X], Y, Index); +split_and_keysort([], X, Y, Index) -> + keymerge(Index, keysort(Index, X), keysort(Index, Y), []). + +keymerge(Index, X, Y) -> keymerge(Index, X, Y, []). + +keymerge(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) -> + keymerge(I, T1, [H2|T2], [H1|L]); +keymerge(Index, T1, [H2|T2], L) -> + keymerge(Index,T1, T2, [H2|L]); +keymerge(Index,[H|T], T2, L) -> + keymerge(Index,T, T2, [H|L]); +keymerge(Index, [], [], L) -> + reverse(L). + +keymap(Fun, Index, [Tup|Tail]) -> + [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap(Fun, Index, Tail)]; +keymap( _, _ , []) -> []. + +keymap(Fun, ExtraArgs, Index, [Tup|Tail]) -> + [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| + keymap(Fun, ExtraArgs, Index, Tail)]; +keymap( _, _ , _, []) -> []. + +%% all(Predicate, List) +%% any(Predicate, List) +%% map(Function, List) +%% flatmap(Function, List) +%% foldl(Function, First, List) +%% foldr(Function, Last, List) +%% filter(Predicate, List) +%% zf(Function, List) +%% mapfoldl(Function, First, List) +%% mapfoldr(Function, Last, List) +%% foreach(Function, List) +%% takewhile(Predicate, List) +%% dropwhile(Predicate, List) +%% splitwith(Predicate, List) +%% for list programming. Function here is either a 'fun' or a tuple +%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke! +%% +%% N.B. Unless where the functions actually needs it only foreach/2/3, +%% which is meant to be used for its side effects, has a defined order +%% of evaluation. +%% +%% There are also versions with an extra argument, ExtraArgs, which is a +%% list of extra arguments to each call. + +all(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> all(Pred, Tail); + false -> false + end; +all(Pred, []) -> true. + +any(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> true; + false -> any(Pred, Tail) + end; +any(Pred, []) -> false. + +map(F, List) -> [ F(E) || E <- List ]. + +flatmap(F, [Hd|Tail]) -> + F(Hd) ++ flatmap(F, Tail); +flatmap(F, []) -> []. + +foldl(F, Accu, [Hd|Tail]) -> + foldl(F, F(Hd, Accu), Tail); +foldl(F, Accu, []) -> Accu. + +foldr(F, Accu, [Hd|Tail]) -> + F(Hd, foldr(F, Accu, Tail)); +foldr(F, Accu, []) -> Accu. + +filter(Pred, List) -> [ E || E <- List, Pred(E) ]. + +zf(F, [Hd|Tail]) -> + case F(Hd) of + true -> + [Hd|zf(F, Tail)]; + {true,Val} -> + [Val|zf(F, Tail)]; + false -> + zf(F, Tail) + end; +zf(F, []) -> []. + +foreach(F, [Hd|Tail]) -> + F(Hd), + foreach(F, Tail); +foreach(F, []) -> ok. + +mapfoldl(F, Accu0, [Hd|Tail]) -> + {R,Accu1} = F(Hd, Accu0), + {Rs,Accu2} = mapfoldl(F, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl(F, Accu, []) -> {[],Accu}. + +mapfoldr(F, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr(F, Accu0, Tail), + {R,Accu2} = F(Hd, Accu1), + {[R|Rs],Accu2}; +mapfoldr(F, Accu, []) -> {[],Accu}. + +takewhile(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> [Hd|takewhile(Pred, Tail)]; + false -> [] + end; +takewhile(Pred, []) -> []. + +dropwhile(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> dropwhile(Pred, Tail); + false -> [Hd|Tail] + end; +dropwhile(Pred, []) -> []. + +splitwith(Pred, List) -> splitwith(Pred, List, []). + +splitwith(Pred, [Hd|Tail], Taken) -> + case Pred(Hd) of + true -> splitwith(Pred, Tail, [Hd|Taken]); + false -> {reverse(Taken), [Hd|Tail]} + end; +splitwith(Pred, [], Taken) -> {reverse(Taken),[]}. + +%% Versions of the above functions with extra arguments. + +all(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> all(Pred, Eas, Tail); + false -> false + end; +all(Pred, Eas, []) -> true. + +any(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> true; + false -> any(Pred, Eas, Tail) + end; +any(Pred, Eas, []) -> false. + +map(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ]. + +flatmap(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]) ++ flatmap(F, Eas, Tail); +flatmap(F, Eas, []) -> []. + +foldl(F, Eas, Accu, [Hd|Tail]) -> + foldl(F, Eas, apply(F, [Hd,Accu|Eas]), Tail); +foldl(F, Eas, Accu, []) -> Accu. + +foldr(F, Eas, Accu, [Hd|Tail]) -> + apply(F, [Hd,foldr(F, Eas, Accu, Tail)|Eas]); +foldr(F, Eas, Accu, []) -> + Accu. + +filter(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ]. + +zf(F, Eas, [Hd|Tail]) -> + case apply(F, [Hd|Eas]) of + true -> + [Hd|zf(F, Eas, Tail)]; + {true,Val} -> + [Val|zf(F, Eas, Tail)]; + false -> + zf(F, Eas, Tail) + end; +zf(F, Eas, []) -> []. + +foreach(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]), + foreach(F, Eas, Tail); +foreach(F, Eas, []) -> ok. + +mapfoldl(F, Eas, Accu0, [Hd|Tail]) -> + {R,Accu1} = apply(F, [Hd,Accu0|Eas]), + {Rs,Accu2} = mapfoldl(F, Eas, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl(F, Eas, Accu, []) -> {[],Accu}. + +mapfoldr(F, Eas, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr(F, Eas, Accu0, Tail), + {R,Accu2} = apply(F, [Hd,Accu1|Eas]), + {[R|Rs],Accu2}; +mapfoldr(F, Eas, Accu, []) -> {[],Accu}. + +%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with +%% extra arguments as this going to be discontinued. diff --git a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl new file mode 100644 index 0000000000..ea72150bca --- /dev/null +++ b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/ordsets1.erl @@ -0,0 +1,188 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%% Purpose : Functions for manipulating sets as ordered lists. + +%% As yet some of these are not very efficiently written. + +-module(ordsets1). + +-export([new_set/0,is_set/1,set_to_list/1,list_to_set/1]). +-export([is_element/2,add_element/2,del_element/2]). +-export([union/2,union/1,intersection/2,intersection/1]). +-export([subtract/2,subset/2]). + +%% new_set() +%% Return a new empty ordered set. + +new_set() -> + []. + +%% is_set(Set) +%% Return 'true' if Set is an ordered set of elements, else 'false'. + +is_set([E|Es]) -> + is_set(Es, E); +is_set([]) -> + true. + +is_set([E2|Es], E1) when E1 < E2 -> + is_set(Es, E2); +is_set([E2|Es], E1) -> + false; +is_set([], E1) -> + true. + +%% set_to_list(OrdSet) +%% Return the elements in OrdSet as a list. + +set_to_list(S) -> + S. + +%% list_to_set(List) +%% Build an ordered set from the elements in List. + +list_to_set([E|Es]) -> + add_element(E, list_to_set(Es)); +list_to_set([]) -> + []. + +%% is_element(Element, OrdSet) +%% Return 'true' if Element is an element of OrdSet, else 'false'. + +is_element(E, [H|Es]) when E < H -> + false; +is_element(E, [H|Es]) when E == H -> + true; +is_element(E, [H|Es]) when E > H -> + is_element(E, Es); +is_element(E, []) -> + false. + +%% add_element(Element, OrdSet) +%% Return OrdSet with Element inserted in it. + +add_element(E, [H|Es]) when E < H -> + [E,H|Es]; +add_element(E, [H|Es]) when E == H -> + [H|Es]; +add_element(E, [H|Es]) when E > H -> + [H|add_element(E, Es)]; +add_element(E, []) -> + [E]. + +%% del_element(Element, OrdSet) +%% Return OrdSet but with Element removed. + +del_element(E, [H|Es]) when E < H -> + [H|Es]; +del_element(E, [H|Es]) when E == H -> + Es; +del_element(E, [H|Es]) when E > H -> + [H|del_element(E, Es)]; +del_element(E, []) -> + []. + +%% union(Set1, Set2) +%% Return the union of Set1 and Set2. + +union([H1|Es1], [H2|Es2]) when H1 < H2 -> + [H1|union(Es1, [H2|Es2])]; +union([H1|Es1], [H2|Es2]) when H1 == H2 -> + [H1|union(Es1, Es2)]; +union([H1|Es1], [H2|Es2]) when H1 > H2 -> + [H2|union([H1|Es1], Es2)]; +union([], Es2) -> + Es2; +union(Es1, []) -> + Es1. + +%% union(OrdSets) +%% Return the union of the list of sets. + +union([S1,S2|Ss]) -> + union1(union(S1,S2), Ss); +union([S]) -> + S; +union([]) -> + []. + +union1(S1, [S2|Ss]) -> + union1(union(S1, S2), Ss); +union1(S1, []) -> + S1. + +%% intersection(Set1, Set2) +%% Return the intersection of Set1 and Set2. + +intersection([H1|Es1], [H2|Es2]) when H1 < H2 -> + intersection(Es1, [H2|Es2]); +intersection([H1|Es1], [H2|Es2]) when H1 == H2 -> + [H1|intersection(Es1, Es2)]; +intersection([H1|Es1], [H2|Es2]) when H1 > H2 -> + intersection([H1|Es1], Es2); +intersection([], Es2) -> + []; +intersection(Es1, []) -> + []. + +%% intersection(OrdSets) +%% Return the intersection of the list of sets. + +intersection([S1,S2|Ss]) -> + intersection1(intersection(S1,S2), Ss); +intersection([S]) -> + S; +intersection([]) -> + []. + +intersection1(S1, [S2|Ss]) -> + intersection1(intersection(S1, S2), Ss); +intersection1(S1, []) -> + S1. + +%% subtract(Set1, Set2) +%% Return all and only the elements of Set1 which are not also in Set2. + +subtract([H1|Es1], [H2|Es2]) when H1 < H2 -> + [H1|subtract(Es1, [H2|Es2])]; +subtract([H1|Es1], [H2|Es2]) when H1 == H2 -> + subtract(Es1, Es2); +subtract([H1|Es1], [H2|Es2]) when H1 > H2 -> + subtract([H1|Es1], Es2); +subtract([], Es2) -> + []; +subtract(Es1, []) -> + Es1. + +%% subset(Set1, Set2) +%% Return 'true' when every element of Set1 is also a member of Set2, +%% else 'false'. + +subset([H1|Es1], [H2|Es2]) when H1 < H2 -> %H1 not in Set2 + false; +subset([H1|Es1], [H2|Es2]) when H1 == H2 -> + subset(Es1, Es2); +subset([H1|Es1], [H2|Es2]) when H1 > H2 -> + subset([H1|Es1], Es2); +subset([], Es2) -> + true; +subset(Es1, []) -> + false. diff --git a/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl new file mode 100644 index 0000000000..a48a7e112f --- /dev/null +++ b/lib/debugger/test/dbg_ui_SUITE_data/manual_data/src/test.erl @@ -0,0 +1,157 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(test). + +%%-compile(export_all). +-export([test1/0, + test2/0, + test3/0, + test4/0, + test5/0, + test6/1, + test7/0, + test8/1, + test9/0, + test10/0, + test11/0, + test12/1 + ]). + + +-export([test9_server/1]). + + +test1() -> + R1 = lists1:reverse("retep"), + R2 = ordsets1:list_to_set([b,c,a,2,4,1]), + R3 = lists1:reverse("nilo"), + {R1,R2, R3}. + +test2() -> + R1 = spawn(lists1,reverse,["retep"]), + R2 = spawn(ordsets1,list_to_set,[[b,c,a,2,4,1]]), + R3 = spawn(lists1,reverse,["nilo"]), + {R1,R2, R3}. + + +test3() -> + A = a, + Pid = spawn(?MODULE, test1,[]), + B = b, + {A, B, Pid}. + +test4() -> + Pid = spawn(?MODULE, test1,[]), + A = a, + B = b, + {A, B, Pid}. +test5() -> + L1 = [a,b,c], + L = length(L1), + A = a, + B = b, + {A, B, L, L1}. + + + +test6(0) -> + ok; +test6(N) when N>0 -> + spawn(lists1,reverse,["adolfiparisrorsirapifloda"]), + test6(N-1). + + +test7() -> + CurDirReturn = file:get_cwd(), + {ok, CurDir} = CurDirReturn, + DirListReturn = file:list_dir(CurDir), + {ok, DirList} = DirListReturn, + io:format("~w~n",[DirList]). + + +test8(List) -> + %% foo + %%bar + %% foo + %%bar + %% foo + %%bar + %% foo + %%bar + + L2 = [gamma|List], + {L2, List}. + +test9() -> + S1 = spawn(?MODULE, test9_server,[self()]), + S2 = spawn(?MODULE, test9_server,[bongo]), + S3 = spawn(?MODULE, test9_server,[42]), + + test9_loop(S1,S2,S3). + +test9_loop(S1,S2,S3) -> + receive + {S1, hej} -> + io:format("S1 ~n"), + test9_loop(S1,S2,S3); + {S2, hej} -> + io:format("S2 ~n"), + test9_loop(S1,S2,S3); + {S3, hej} -> + io:format("S3 ~n"), + test9_loop(S1,S2,S3) + end. + + +test9_server(Pid) -> + io:format("started server: ~p~n",[Pid]), + test9_server1(Pid). + +test9_server1(Pid) -> + Pad = {pad, Pid}, + test9_server2(Pad). + +test9_server2(Pad) -> + {pad, Pid} = Pad, + Pid ! {self(), hej}. + + + + + +test10() -> + receive + X -> + done + after 20000 -> + timeout + end. + +test11() -> + receive + X -> + done + end. + +test12(normal) -> + done; +test12(crash) -> + exit(crash). diff --git a/lib/debugger/test/debugger.spec b/lib/debugger/test/debugger.spec new file mode 100644 index 0000000000..cc8a5aff37 --- /dev/null +++ b/lib/debugger/test/debugger.spec @@ -0,0 +1 @@ +{topcase, {dir, "../debugger_test"}}. diff --git a/lib/debugger/test/debugger_SUITE.erl b/lib/debugger/test/debugger_SUITE.erl new file mode 100644 index 0000000000..4bd9057f98 --- /dev/null +++ b/lib/debugger/test/debugger_SUITE.erl @@ -0,0 +1,123 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(debugger_SUITE). + +%% Test break points. + +-include("test_server.hrl"). + +-export([all/1,init_per_testcase/2,fin_per_testcase/2, + app_test/1,erts_debug/1,encrypted_debug_info/1, + no_abstract_code/1]). + +all(suite) -> + [app_test,erts_debug,no_abstract_code,encrypted_debug_info]. + +init_per_testcase(_Case, Config) -> + Dog=test_server:timetrap(?t:minutes(0.5)), + [{watchdog, Dog}|Config]. +fin_per_testcase(_Case, Config) -> + Dog=?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +app_test(Config) when is_list(Config) -> + ?line ?t:app_test(debugger), + ok. + +erts_debug(Config) when is_list(Config) -> + c:l(erts_debug), + ok. + +no_abstract_code(Config) when is_list(Config) -> + ?line PrivDir = ?config(priv_dir, Config), + ?line Simple = filename:join(PrivDir, "simple"), + ?line Source = Simple ++ ".erl", + ?line BeamFile = Simple ++ ".beam", + ?line simple_file(Source), + + %% Compile module without abstract code. + CompileFlags = [{outdir,PrivDir}], + ?line {ok,_} = compile:file(Source, CompileFlags), + ?line error = int:i(Simple), + + %% Cleanup. + ?line ok = file:delete(Source), + ?line ok = file:delete(BeamFile), + + ok. + +encrypted_debug_info(Config) when is_list(Config) -> + try begin crypto:start(), crypto:info(), crypto:stop(), ok end of + ok -> + encrypted_debug_info_1(Config) + catch + error:_ -> + {skip,"The crypto application is missing or broken"} + end. + +encrypted_debug_info_1(Config) -> + ?line PrivDir = ?config(priv_dir, Config), + ?line Simple = filename:join(PrivDir, "simple"), + ?line Source = Simple ++ ".erl", + ?line BeamFile = Simple ++ ".beam", + ?line simple_file(Source), + + %% Compile module. + Key = "_This a Crypto Key_", + CompileFlags = [{outdir,PrivDir},debug_info,{debug_info_key,Key}], + ?line {ok,_} = compile:file(Source, CompileFlags), + + %% Interpret module + ?line ok = beam_lib:crypto_key_fun(simple_crypto_fun(Key)), + ?line {module,simple} = int:i(Simple), + + %% Remove key. + ?line {ok,_} = beam_lib:clear_crypto_key_fun(), + ?line error = int:i(Simple), + + %% Cleanup. + ?line ok = file:delete(Source), + ?line ok = file:delete(BeamFile), + + ok. + +simple_crypto_fun(Key) -> + fun(init) -> ok; + ({debug_info, des3_cbc, simple, _}) -> Key + end. + + +simple_file(File) -> + simple_file(File, simple). + +simple_file(File, Module) -> + simple_file(File, Module, member). + +simple_file(File, Module, F) -> + B = list_to_binary(["-module(", atom_to_list(Module), "). " + "-export([t/0]). " + "t() -> " + " t([]). " + "t(L) -> " + " lists:", + atom_to_list(F), "(a, L). "]), + ok = file:write_file(File, B). diff --git a/lib/debugger/test/debugger_test.erl b/lib/debugger/test/debugger_test.erl new file mode 100644 index 0000000000..a64bed5db1 --- /dev/null +++ b/lib/debugger/test/debugger_test.erl @@ -0,0 +1,154 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%%%---------------------------------------------------------------------- +%%% Purpose : This is the test module to be used in with the test cases +%%% in the debugger test document. +%%%---------------------------------------------------------------------- + +-module(debugger_test). + + +-export ([installation_ok/0, + list/0, + fac/1, + c_break/1]). + + +-define (INT_DIR, "misc"). % The directory of the Interpreter directory +-define (INT, "interpreter"). % The Interpreter directory name. +-define (DBG, "debugger"). % Debugger name + + +%%% installation_ok /0 +%%% + +installation_ok () -> + debugger_ok (), + interpreter_ok (). + + + +%%% debugger_ok /0 +%%% + +debugger_ok () -> + L = code:get_path (), + + case debugger_in_codepath (L) of + {true, Msg} -> + out_put (Msg); + + Other -> + out_put (Other) + end. + + + +%%% debugger_in_codepath /2 +%%% + +debugger_in_codepath ([]) -> + Msg = io_lib:format ("False: ~s not in code path", [?DBG]), + lists:flatten (Msg); + +debugger_in_codepath ([Path | T]) -> + case string:str (Path, ?DBG) =/= 0 of + true -> + Msg = io_lib:format ("Ok: ~s in code path (~s)", [?DBG, Path]), + Msg1 = lists:flatten (Msg), + {true, Msg1}; + + _Other -> + debugger_in_codepath (T) + end. + + + +%%% interpreter_ok /0 +%%% + +interpreter_ok () -> + Root_dir = code:root_dir (), + Misc_dir = filename:join (Root_dir, ?INT_DIR), + + In_misc = case file:list_dir (Misc_dir) of + {ok, L} -> + lists:member (?INT, L); + + Other -> + Other + end, + + case In_misc of + true -> + Msg = io_lib:format ("Ok: ~s is in ~s", [?INT, ?INT_DIR]), + Msg1 = lists:flatten (Msg), + out_put (Msg1); + + Other1 -> + Msg = io_lib:format ("Error: interpreter in misc - ~s", [Other1]), + Msg1 = lists:flatten (Msg), + out_put (Msg1) + end. + + + +%%% list /0 +%%% + +list () -> + A = [1, 2, 3, 4, 5], + B = [a, b, c, d, e], + lists:append (A, B). + + + +%%% fac /1 +%%% + +fac (0) -> + 1; + + +fac (N) -> + N * fac (N - 1). + + + +%%% c_break /1 +%%% + +c_break (Bindings) -> + case int:get_binding ('N', Bindings) of + {value, 3} -> + true; + + _Other -> + false + end. + + + +%%% out_put /1 +%%% + +out_put (X) -> + io:format ("~n~p~n", [X]). diff --git a/lib/debugger/test/debugger_testdoc.fm5 b/lib/debugger/test/debugger_testdoc.fm5 Binary files differnew file mode 100644 index 0000000000..56882b8bd5 --- /dev/null +++ b/lib/debugger/test/debugger_testdoc.fm5 diff --git a/lib/debugger/test/erl_eval_SUITE.erl b/lib/debugger/test/erl_eval_SUITE.erl new file mode 100644 index 0000000000..fd4d28b2c7 --- /dev/null +++ b/lib/debugger/test/erl_eval_SUITE.erl @@ -0,0 +1,1388 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +-module(erl_eval_SUITE). +-export([all/1]). + +-export([guard_1/1, guard_2/1, + match_pattern/1, + match_bin/1, + string_plusplus/1, + pattern_expr/1, + guard_3/1, guard_4/1, + lc/1, + simple_cases/1, + unary_plus/1, + apply_atom/1, + otp_5269/1, + otp_6539/1, + otp_6543/1, + otp_6787/1, + otp_6977/1, + otp_7550/1, + otp_8133/1, + funs/1, + try_catch/1, + eval_expr_5/1]). + +%% +%% Define to run outside of test server +%% +%%-define(STANDALONE,1). + +-import(lists,[concat/1, sort/1]). + +-export([count_down/2, count_down_fun/0, do_apply/2, + local_func/3, local_func_value/2]). + +-ifdef(STANDALONE). +-define(config(A,B),config(A,B)). +-export([config/2]). +-define(line, noop, ). +config(priv_dir,_) -> + ".". +-else. +-include("test_server.hrl"). +-export([init_per_testcase/2, fin_per_testcase/2]). +% Default timetrap timeout (set in init_per_testcase). +-define(default_timeout, ?t:minutes(1)). +init_per_testcase(_Case, Config) -> + ?line Dog = ?t:timetrap(?default_timeout), + [{watchdog, Dog} | Config]. +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. +-endif. + +all(doc) -> + ["Test cases for the 'erl_eval' module."]; +all(suite) -> + [guard_1, guard_2, match_pattern, string_plusplus, pattern_expr, + match_bin, guard_3, guard_4, + lc, simple_cases, unary_plus, apply_atom, otp_5269, otp_6539, otp_6543, + otp_6787, otp_6977, otp_7550, otp_8133, funs, try_catch, eval_expr_5]. + +guard_1(doc) -> + ["(OTP-2405)"]; +guard_1(suite) -> + []; +guard_1(Config) when is_list(Config) -> + ?line {ok,Tokens ,_} = + erl_scan:string("if a+4 == 4 -> yes; true -> no end. "), + ?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens), + ?line no = guard_1_compiled(), + ?line {value, no, []} = erl_eval:expr(Expr, []), + ok. + +guard_1_compiled() -> + if a+4 == 4 -> yes; true -> no end. + +guard_2(doc) -> + ["Similar to guard_1, but type-correct"]; +guard_2(suite) -> + []; +guard_2(Config) when is_list(Config) -> + ?line {ok,Tokens ,_} = + erl_scan:string("if 6+4 == 4 -> yes; true -> no end. "), + ?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens), + ?line no = guard_2_compiled(), + ?line {value, no, []} = erl_eval:expr(Expr, []), + ok. + +guard_2_compiled() -> + if 6+4 == 4 -> yes; true -> no end. + +string_plusplus(doc) -> + ["OTP-3069: syntactic sugar string ++ ..."]; +string_plusplus(suite) -> + []; +string_plusplus(Config) when is_list(Config) -> + ?line check(fun() -> case "abc" of "ab" ++ L -> L end end, + "case \"abc\" of \"ab\" ++ L -> L end. ", + "c"), + ?line check(fun() -> case "abcde" of "ab" ++ "cd" ++ L -> L end end, + "case \"abcde\" of \"ab\" ++ \"cd\" ++ L -> L end. ", + "e"), + ?line check(fun() -> case "abc" of [97, 98] ++ L -> L end end, + "case \"abc\" of [97, 98] ++ L -> L end. ", + "c"), + ok. + +match_pattern(doc) -> + ["OTP-2983: match operator in pattern"]; +match_pattern(suite) -> + []; +match_pattern(Config) when is_list(Config) -> + ?line check(fun() -> case {a, b} of {a, _X}=Y -> {x,Y} end end, + "case {a, b} of {a, X}=Y -> {x,Y} end. ", + {x, {a, b}}), + ?line check(fun() -> case {a, b} of Y={a, _X} -> {x,Y} end end, + "case {a, b} of Y={a, X} -> {x,Y} end. ", + {x, {a, b}}), + ?line check(fun() -> case {a, b} of Y={a, _X}=Z -> {Z,Y} end end, + "case {a, b} of Y={a, X}=Z -> {Z,Y} end. ", + {{a, b}, {a, b}}), + ?line check(fun() -> A = 4, B = 28, <<13:(A+(X=B))>>, X end, + "begin A = 4, B = 28, <<13:(A+(X=B))>>, X end.", + 28), + ok. + +match_bin(doc) -> + ["binary match problems"]; +match_bin(suite) -> + []; +match_bin(Config) when is_list(Config) -> + ?line check(fun() -> <<"abc">> = <<"abc">> end, + "<<\"abc\">> = <<\"abc\">>. ", + <<"abc">>), + ?line check(fun() -> + <<Size,B:Size/binary,Rest/binary>> = <<2,"AB","CD">>, + {Size,B,Rest} + end, + "begin <<Size,B:Size/binary,Rest/binary>> = <<2,\"AB\",\"CD\">>, " + "{Size,B,Rest} end. ", + {2,<<"AB">>,<<"CD">>}), + ok. + +pattern_expr(doc) -> + ["OTP-3144: compile-time expressions in pattern"]; +pattern_expr(suite) -> + []; +pattern_expr(Config) when is_list(Config) -> + ?line check(fun() -> case 4 of 2+2 -> ok end end, + "case 4 of 2+2 -> ok end. ", + ok), + ?line check(fun() -> case 2 of +2 -> ok end end, + "case 2 of +2 -> ok end. ", + ok), + ok. + +guard_3(doc) -> + ["OTP-4518."]; +guard_3(suite) -> + []; +guard_3(Config) when is_list(Config) -> + ?line check(fun() -> if false -> false; true -> true end end, + "if false -> false; true -> true end.", + true), + ?line check(fun() -> if <<"hej">> == <<"hopp">> -> true; + true -> false end end, + "begin if <<\"hej\">> == <<\"hopp\">> -> true; + true -> false end end.", + false), + ?line check(fun() -> if <<"hej">> == <<"hej">> -> true; + true -> false end end, + "begin if <<\"hej\">> == <<\"hej\">> -> true; + true -> false end end.", + true), + ok. + +guard_4(doc) -> + ["OTP-4885."]; +guard_4(suite) -> + []; +guard_4(Config) when is_list(Config) -> + ?line check(fun() -> if {erlang,'+'}(3,a) -> true ; true -> false end end, + "if {erlang,'+'}(3,a) -> true ; true -> false end.", + false), + ?line check(fun() -> if {erlang,is_integer}(3) -> true ; true -> false end + end, + "if {erlang,is_integer}(3) -> true ; true -> false end.", + true), + ?line check(fun() -> [X || X <- [1,2,3], erlang:is_integer(X)] end, + "[X || X <- [1,2,3], erlang:is_integer(X)].", + [1,2,3]), + ?line check(fun() -> if is_atom(is_integer(a)) -> true ; true -> false end + end, + "if is_atom(is_integer(a)) -> true ; true -> false end.", + true), + ?line check(fun() -> if {erlang,is_atom}({erlang,is_integer}(a)) -> true; + true -> false end end, + "if {erlang,is_atom}({erlang,is_integer}(a)) -> true; " + "true -> false end.", + true), + ?line check(fun() -> if is_atom(3+a) -> true ; true -> false end end, + "if is_atom(3+a) -> true ; true -> false end.", + false), + ?line check(fun() -> if erlang:is_atom(3+a) -> true ; true -> false end + end, + "if erlang:is_atom(3+a) -> true ; true -> false end.", + false), + ok. + + +lc(doc) -> + ["OTP-4518."]; +lc(suite) -> + []; +lc(Config) when is_list(Config) -> + ?line check(fun() -> X = 32, [X || X <- [1,2,3]] end, + "begin X = 32, [X || X <- [1,2,3]] end.", + [1,2,3]), + ?line check(fun() -> X = 32, + [X || <<X:X>> <- [<<1:32>>,<<2:32>>,<<3:8>>]] end, + %% "binsize variable" ^ + "begin X = 32, + [X || <<X:X>> <- [<<1:32>>,<<2:32>>,<<3:8>>]] end.", + [1,2]), + ?line check(fun() -> Y = 13,[X || {X,Y} <- [{1,2}]] end, + "begin Y = 13,[X || {X,Y} <- [{1,2}]] end.", + [1]), + ?line error_check("begin [A || X <- [{1,2}], 1 == A] end.", + {unbound_var,'A'}), + ?line error_check("begin X = 32, + [{Y,W} || X <- [1,2,32,Y=4], Z <- [1,2,W=3]] end.", + {unbound_var,'Y'}), + ?line error_check("begin X = 32,<<A:B>> = <<100:X>> end.", + {unbound_var,'B'}), + ?line check(fun() -> [X || X <- [1,2,3,4], not (X < 2)] end, + "begin [X || X <- [1,2,3,4], not (X < 2)] end.", + [2,3,4]), + ?line check(fun() -> [X || X <- [true,false], X] end, + "[X || X <- [true,false], X].", [true]), + ok. + +simple_cases(doc) -> + ["Simple cases, just to cover some code."]; +simple_cases(suite) -> + []; +simple_cases(Config) when is_list(Config) -> + ?line check(fun() -> A = $C end, "A = $C.", $C), + %% ?line check(fun() -> A = 3.14 end, "A = 3.14.", 3.14), + ?line check(fun() -> self() ! a, A = receive a -> true end end, + "begin self() ! a, A = receive a -> true end end.", + true), + ?line check(fun() -> c:flush(), self() ! a, self() ! b, self() ! c, + receive b -> b end, + {messages, [a,c]} = + erlang:process_info(self(), messages), + c:flush() end, + "begin c:flush(), self() ! a, self() ! b, self() ! c," + "receive b -> b end," + "{messages, [a,c]} =" + " erlang:process_info(self(), messages), c:flush() end.", + ok), + ?line check(fun() -> self() ! a, A = receive a -> true + after 0 -> false end end, + "begin self() ! a, A = receive a -> true" + " after 0 -> false end end.", + true), + ?line check(fun() -> c:flush(), self() ! a, self() ! b, self() ! c, + receive b -> b after 0 -> true end, + {messages, [a,c]} = + erlang:process_info(self(), messages), + c:flush() end, + "begin c:flush(), self() ! a, self() ! b, self() ! c," + "receive b -> b after 0 -> true end," + "{messages, [a,c]} =" + " erlang:process_info(self(), messages), c:flush() end.", + ok), + ?line check(fun() -> receive _ -> true after 10 -> false end end, + "receive _ -> true after 10 -> false end.", + false), + ?line check(fun() -> F = fun(A) -> A end, true = 3 == F(3) end, + "begin F = fun(A) -> A end, true = 3 == F(3) end.", + true), + ?line check(fun() -> F = fun(A) -> A end, true = 3 == apply(F, [3]) end, + "begin F = fun(A) -> A end, true = 3 == apply(F,[3]) end.", + true), + ?line check(fun() -> catch throw(a) end, "catch throw(a).", a), + ?line check(fun() -> catch a end, "catch a.", a), + ?line check(fun() -> 4 == 3 end, "4 == 3.", false), + ?line check(fun() -> not true end, "not true.", false), + ?line check(fun() -> -3 end, "-3.", -3), + + ?line error_check("3.0 = 4.0.", {badmatch,4.0}), + ?line check(fun() -> <<(3.0+2.0):32/float>> = <<5.0:32/float>> end, + "<<(3.0+2.0):32/float>> = <<5.0:32/float>>.", + <<5.0:32/float>>), + + ?line check(fun() -> false andalso kludd end, "false andalso kludd.", + false), + ?line check(fun() -> true andalso true end, "true andalso true.", + true), + ?line check(fun() -> true andalso false end, "true andalso false.", + false), + ?line check(fun() -> true andalso kludd end, "true andalso kludd.", + kludd), + ?line error_check("kladd andalso kludd.", {badarg,kladd}), + + ?line check(fun() -> if false andalso kludd -> a; true -> b end end, + "if false andalso kludd -> a; true -> b end.", + b), + ?line check(fun() -> if true andalso true -> a; true -> b end end, + "if true andalso true -> a; true -> b end.", + a), + ?line check(fun() -> if true andalso false -> a; true -> b end end, + "if true andalso false -> a; true -> b end.", + b), + + ?line check(fun() -> true orelse kludd end, + "true orelse kludd.", true), + ?line check(fun() -> false orelse false end, + "false orelse false.", false), + ?line check(fun() -> false orelse true end, + "false orelse true.", true), + ?line check(fun() -> false orelse kludd end, + "false orelse kludd.", kludd), + ?line error_check("kladd orelse kludd.", {badarg,kladd}), + ?line error_check("[X || X <- [1,2,3], begin 1 end].",{bad_filter,1}), + ?line error_check("[X || X <- a].",{bad_generator,a}), + + ?line check(fun() -> if true orelse kludd -> a; true -> b end end, + "if true orelse kludd -> a; true -> b end.", a), + ?line check(fun() -> if false orelse false -> a; true -> b end end, + "if false orelse false -> a; true -> b end.", b), + ?line check(fun() -> if false orelse true -> a; true -> b end end, + "if false orelse true -> a; true -> b end.", a), + + ?line check(fun() -> [X || X <- [1,2,3], X+2] end, + "[X || X <- [1,2,3], X+2].", []), + + ?line check(fun() -> [X || X <- [1,2,3], [X] == [X || X <- [2]]] end, + "[X || X <- [1,2,3], [X] == [X || X <- [2]]].", + [2]), + ?line check(fun() -> F = fun(1) -> ett; (2) -> zwei end, + ett = F(1), zwei = F(2) end, + "begin F = fun(1) -> ett; (2) -> zwei end, + ett = F(1), zwei = F(2) end.", + zwei), + ?line check(fun() -> F = fun(X) when X == 1 -> ett; + (X) when X == 2 -> zwei end, + ett = F(1), zwei = F(2) end, + "begin F = fun(X) when X == 1 -> ett; + (X) when X == 2 -> zwei end, + ett = F(1), zwei = F(2) end.", + zwei), + ?line error_check("begin F = fun(1) -> ett end, zwei = F(2) end.", + function_clause), + ?line check(fun() -> if length([1]) == 1 -> yes; + true -> no end end, + "if length([1]) == 1 -> yes; + true -> no end.", + yes), + ?line check(fun() -> if is_integer(3) -> true; true -> false end end, + "if is_integer(3) -> true; true -> false end.", true), + ?line check(fun() -> if integer(3) -> true; true -> false end end, + "if integer(3) -> true; true -> false end.", true), + ?line check(fun() -> if is_float(3) -> true; true -> false end end, + "if is_float(3) -> true; true -> false end.", false), + ?line check(fun() -> if float(3) -> true; true -> false end end, + "if float(3) -> true; true -> false end.", false), + ?line check(fun() -> if is_number(3) -> true; true -> false end end, + "if is_number(3) -> true; true -> false end.", true), + ?line check(fun() -> if number(3) -> true; true -> false end end, + "if number(3) -> true; true -> false end.", true), + ?line check(fun() -> if is_atom(a) -> true; true -> false end end, + "if is_atom(a) -> true; true -> false end.", true), + ?line check(fun() -> if atom(a) -> true; true -> false end end, + "if atom(a) -> true; true -> false end.", true), + ?line check(fun() -> if is_list([]) -> true; true -> false end end, + "if is_list([]) -> true; true -> false end.", true), + ?line check(fun() -> if list([]) -> true; true -> false end end, + "if list([]) -> true; true -> false end.", true), + ?line check(fun() -> if is_tuple({}) -> true; true -> false end end, + "if is_tuple({}) -> true; true -> false end.", true), + ?line check(fun() -> if tuple({}) -> true; true -> false end end, + "if tuple({}) -> true; true -> false end.", true), + ?line check(fun() -> if is_pid(self()) -> true; true -> false end end, + "if is_pid(self()) -> true; true -> false end.", true), + ?line check(fun() -> if pid(self()) -> true; true -> false end end, + "if pid(self()) -> true; true -> false end.", true), + ?line check(fun() -> R = make_ref(), if is_reference(R) -> true; + true -> false end end, + "begin R = make_ref(), if is_reference(R) -> true;" + "true -> false end end.", true), + ?line check(fun() -> R = make_ref(), if reference(R) -> true; + true -> false end end, + "begin R = make_ref(), if reference(R) -> true;" + "true -> false end end.", true), + ?line check(fun() -> if is_port(a) -> true; true -> false end end, + "if is_port(a) -> true; true -> false end.", false), + ?line check(fun() -> if port(a) -> true; true -> false end end, + "if port(a) -> true; true -> false end.", false), + ?line check(fun() -> if is_function(a) -> true; true -> false end end, + "if is_function(a) -> true; true -> false end.", false), + ?line check(fun() -> if function(a) -> true; true -> false end end, + "if function(a) -> true; true -> false end.", false), + ?line check(fun() -> if is_binary(<<>>) -> true; true -> false end end, + "if is_binary(<<>>) -> true; true -> false end.", true), + ?line check(fun() -> if binary(<<>>) -> true; true -> false end end, + "if binary(<<>>) -> true; true -> false end.", true), + ?line check(fun() -> if is_integer(a) == true -> yes; + true -> no end end, + "if is_integer(a) == true -> yes; + true -> no end.", + no), + ?line check(fun() -> if [] -> true; true -> false end end, + "if [] -> true; true -> false end.", false), + ?line error_check("if lists:member(1,[1]) -> true; true -> false end.", + illegal_guard_expr), + ?line error_check("if false -> true end.", if_clause), + ?line check(fun() -> if a+b -> true; true -> false end end, + "if a + b -> true; true -> false end.", false), + ?line check(fun() -> if + b -> true; true -> false end end, + "if + b -> true; true -> false end.", false), + ?line error_check("case foo of bar -> true end.", {case_clause,foo}), + ?line error_check("case 4 of 2+a -> true; _ -> false end.", + illegal_pattern), + ?line error_check("case 4 of +a -> true; _ -> false end.", + illegal_pattern), + ?line check(fun() -> case a of + X when X == b -> one; + X when X == a -> two + end end, + "begin case a of + X when X == b -> one; + X when X == a -> two + end end.", two), + ?line error_check("3 = 4.", {badmatch,4}), + ?line error_check("a = 3.", {badmatch,3}), + %% ?line error_check("3.1 = 2.7.",{badmatch,2.7}), + ?line error_check("$c = 4.", {badmatch,4}), + ?line check(fun() -> $c = $c end, "$c = $c.", $c), + ?line check(fun() -> _ = bar end, "_ = bar.", bar), + ?line check(fun() -> A = 14, A = 14 end, + "begin A = 14, A = 14 end.", 14), + ?line error_check("begin A = 14, A = 16 end.", {badmatch,16}), + ?line error_check("\"hej\" = \"san\".", {badmatch,"san"}), + ?line check(fun() -> "hej" = "hej" end, + "\"hej\" = \"hej\".", "hej"), + ?line error_check("[] = [a].", {badmatch,[a]}), + ?line check(fun() -> [] = [] end, "[] = [].", []), + ?line error_check("[a] = [].", {badmatch,[]}), + ?line error_check("{a,b} = 34.", {badmatch,34}), + ?line check(fun() -> <<X:7>> = <<8:7>>, X end, + "begin <<X:7>> = <<8:7>>, X end.", 8), + ?line error_check("<<34:32>> = \"hej\".", {badmatch,"hej"}), + ?line check(fun() -> trunc((1 * 3 div 3 + 4 - 3) / 1) rem 2 end, + "begin trunc((1 * 3 div 3 + 4 - 3) / 1) rem 2 end.", 0), + ?line check(fun() -> (2#101 band 2#10101) bor (2#110 bxor 2#010) end, + "(2#101 band 2#10101) bor (2#110 bxor 2#010).", 5), + ?line check(fun() -> (2#1 bsl 4) + (2#10000 bsr 3) end, + "(2#1 bsl 4) + (2#10000 bsr 3).", 18), + ?line check(fun() -> ((1<3) and ((1 =:= 2) or (1 =/= 2))) xor (1=<2) end, + "((1<3) and ((1 =:= 2) or (1 =/= 2))) xor (1=<2).", false), + ?line check(fun() -> (a /= b) or (2 > 4) or (3 >= 3) end, + "(a /= b) or (2 > 4) or (3 >= 3).", true), + ?line check(fun() -> "hej" ++ "san" =/= "hejsan" -- "san" end, + "\"hej\" ++ \"san\" =/= \"hejsan\" -- \"san\".", true), + ?line check(fun() -> (bnot 1) < -0 end, "(bnot (+1)) < -0.", true), + ok. + +unary_plus(doc) -> + ["OTP-4929. Unary plus rejects non-numbers."]; +unary_plus(suite) -> + []; +unary_plus(Config) when is_list(Config) -> + ?line check(fun() -> F = fun(X) -> + X end, + true = -1 == F(-1) end, + "begin F = fun(X) -> + X end," + " true = -1 == F(-1) end.", true, ['F'], none, none), + ?line error_check("+a.", badarith), + ok. + +apply_atom(doc) -> + ["OTP-5064. Can no longer apply atoms."]; +apply_atom(suite) -> + []; +apply_atom(Config) when is_list(Config) -> + ?line error_check("[X || X <- [[1],[2]], + begin L = length, L(X) =:= 1 end].", + {badfun,length}), + ok. + +otp_5269(doc) -> + ["OTP-5269. Bugs in the bit syntax."]; +otp_5269(suite) -> + []; +otp_5269(Config) when is_list(Config) -> + ?line check(fun() -> L = 8, + F = fun(<<A:L,B:A>>) -> B end, + F(<<16:8, 7:16>>) + end, + "begin + L = 8, F = fun(<<A:L,B:A>>) -> B end, F(<<16:8, 7:16>>) + end.", + 7), + ?line check(fun() -> L = 8, + F = fun(<<L:L,B:L>>) -> B end, + F(<<16:8, 7:16>>) + end, + "begin + L = 8, F = fun(<<L:L,B:L>>) -> B end, F(<<16:8, 7:16>>) + end.", + 7), + ?line check(fun() -> L = 8, <<A:L,B:A>> = <<16:8, 7:16>>, B end, + "begin L = 8, <<A:L,B:A>> = <<16:8, 7:16>>, B end.", + 7), + ?line error_check("begin L = 8, <<L:L,B:L>> = <<16:8, 7:16>> end.", + {badmatch,<<16:8,7:16>>}), + + ?line error_check("begin <<L:16,L:L>> = <<16:16,8:16>>, L end.", + {badmatch, <<16:16,8:16>>}), + ?line check(fun() -> U = 8, (fun(<<U:U>>) -> U end)(<<32:8>>) end, + "begin U = 8, (fun(<<U:U>>) -> U end)(<<32:8>>) end.", + 32), + ?line check(fun() -> U = 8, [U || <<U:U>> <- [<<32:8>>]] end, + "begin U = 8, [U || <<U:U>> <- [<<32:8>>]] end.", + [32]), + ?line error_check("(fun({3,<<A:32,A:32>>}) -> a end) + ({3,<<17:32,19:32>>}).", + function_clause), + ?line check(fun() -> [X || <<A:8, + B:A>> <- [<<16:8,19:16>>], + <<X:8>> <- [<<B:8>>]] end, + "[X || <<A:8, + B:A>> <- [<<16:8,19:16>>], + <<X:8>> <- [<<B:8>>]].", + [19]), + ok. + +otp_6539(doc) -> + ["OTP-6539. try/catch bugs."]; +otp_6539(suite) -> + []; +otp_6539(Config) when is_list(Config) -> + ?line check(fun() -> + F = fun(A,B) -> + try A+B + catch _:_ -> dontthinkso + end + end, + lists:zipwith(F, [1,2], [2,3]) + end, + "begin + F = fun(A,B) -> + try A+B + catch _:_ -> dontthinkso + end + end, + lists:zipwith(F, [1,2], [2,3]) + end.", + [3, 5]), + ok. + +otp_6543(doc) -> + ["OTP-6543. bitlevel binaries."]; +otp_6543(suite) -> + []; +otp_6543(Config) when is_list(Config) -> + ?line check(fun() -> + << <<X>> || <<X>> <- [1,2,3] >> + end, + "<< <<X>> || <<X>> <- [1,2,3] >>.", + <<>>), + ?line check(fun() -> + << <<X>> || X <- [1,2,3] >> + end, + "<< <<X>> || X <- [1,2,3] >>.", + <<1,2,3>>), + ?line check(fun() -> + << <<X:8>> || <<X:2>> <= <<"hej">> >> + end, + "<< <<X:8>> || <<X:2>> <= <<\"hej\">> >>.", + <<1,2,2,0,1,2,1,1,1,2,2,2>>), + ?line check(fun() -> + << <<X:8>> || + <<65,X:4>> <= <<65,7:4,65,3:4,66,8:4>> >> + end, + "<< <<X:8>> || + <<65,X:4>> <= <<65,7:4,65,3:4,66,8:4>> >>.", + <<7,3>>), + ?line check(fun() -> <<34:18/big>> end, + "<<34:18/big>>.", + <<0,8,2:2>>), + ?line check(fun() -> <<34:18/big-unit:2>> end, + "<<34:18/big-unit:2>>.", + <<0,0,0,2,2:4>>), + ?line check(fun() -> <<34:18/little>> end, + "<<34:18/little>>.", + <<34,0,0:2>>), + ?line case eval_string("<<34:18/native>>.") of + <<0,8,2:2>> -> ok; + <<34,0,0:2>> -> ok + end, + ?line check(fun() -> <<34:18/big-signed>> end, + "<<34:18/big-signed>>.", + <<0,8,2:2>>), + ?line check(fun() -> <<34:18/little-signed>> end, + "<<34:18/little-signed>>.", + <<34,0,0:2>>), + ?line case eval_string("<<34:18/native-signed>>.") of + <<0,8,2:2>> -> ok; + <<34,0,0:2>> -> ok + end, + ?line check(fun() -> <<34:18/big-unsigned>> end, + "<<34:18/big-unsigned>>.", + <<0,8,2:2>>), + ?line check(fun() -> <<34:18/little-unsigned>> end, + "<<34:18/little-unsigned>>.", + <<34,0,0:2>>), + ?line case eval_string("<<34:18/native-unsigned>>.") of + <<0,8,2:2>> -> ok; + <<34,0,0:2>> -> ok + end, + ?line check(fun() -> <<3.14:32/float-big>> end, + "<<3.14:32/float-big>>.", + <<64,72,245,195>>), + ?line check(fun() -> <<3.14:32/float-little>> end, + "<<3.14:32/float-little>>.", + <<195,245,72,64>>), + ?line case eval_string("<<3.14:32/float-native>>.") of + <<64,72,245,195>> -> ok; + <<195,245,72,64>> -> ok + end, + ?line error_check("<<(<<17,3:2>>)/binary>>.", badarg), + ?line check(fun() -> <<(<<17,3:2>>)/bitstring>> end, + "<<(<<17,3:2>>)/bitstring>>.", + <<17,3:2>>), + ?line check(fun() -> <<(<<17,3:2>>):10/bitstring>> end, + "<<(<<17,3:2>>):10/bitstring>>.", + <<17,3:2>>), + ?line check(fun() -> <<<<344:17>>/binary-unit:17>> end, + "<<<<344:17>>/binary-unit:17>>.", + <<344:17>>), + + ?line check(fun() -> <<X:18/big>> = <<34:18/big>>, X end, + "begin <<X:18/big>> = <<34:18/big>>, X end.", + 34), + ?line check(fun() -> <<X:18/big-unit:2>> = <<34:18/big-unit:2>>, X end, + "begin <<X:18/big-unit:2>> = <<34:18/big-unit:2>>, X end.", + 34), + ?line check(fun() -> <<X:18/little>> = <<34:18/little>>, X end, + "begin <<X:18/little>> = <<34:18/little>>, X end.", + 34), + ?line check(fun() -> <<X:18/native>> = <<34:18/native>>, X end, + "begin <<X:18/native>> = <<34:18/native>>, X end.", + 34), + ?line check(fun() -> <<X:18/big-signed>> = <<34:18/big-signed>>, X end, + "begin <<X:18/big-signed>> = <<34:18/big-signed>>, X end.", + 34), + ?line check(fun() -> <<X:18/little-signed>> = <<34:18/little-signed>>, + X end, + "begin <<X:18/little-signed>> = <<34:18/little-signed>>, + X end.", + 34), + ?line check(fun() -> <<X:18/native-signed>> = <<34:18/native-signed>>, + X end, + "begin <<X:18/native-signed>> = <<34:18/native-signed>>, + X end.", + 34), + ?line check(fun() -> <<X:18/big-unsigned>> = <<34:18/big-unsigned>>, + X end, + "begin <<X:18/big-unsigned>> = <<34:18/big-unsigned>>, + X end.", + 34), + ?line check(fun() -> + <<X:18/little-unsigned>> = <<34:18/little-unsigned>>, + X end, + "begin <<X:18/little-unsigned>> = <<34:18/little-unsigned>>, + X end.", + 34), + ?line check(fun() -> + <<X:18/native-unsigned>> = <<34:18/native-unsigned>>, + X end, + "begin <<X:18/native-unsigned>> = <<34:18/native-unsigned>>, + X end.", + 34), + ?line check(fun() -> <<X:32/float-big>> = <<2.0:32/float-big>>, X end, + "begin <<X:32/float-big>> = <<2.0:32/float-big>>, + X end.", + 2.0), + ?line check(fun() -> <<X:32/float-little>> = <<2.0:32/float-little>>, + X end, + "begin <<X:32/float-little>> = <<2.0:32/float-little>>, + X end.", + 2.0), + ?line check(fun() -> <<X:32/float-native>> = <<2.0:32/float-native>>, + X end, + "begin <<X:32/float-native>> = <<2.0:32/float-native>>, + X end.", + 2.0), + + ?line check( + fun() -> + [X || <<"hej",X:8>> <= <<"hej",8,"san",9,"hej",17,"hej">>] + end, + "[X || <<\"hej\",X:8>> <= + <<\"hej\",8,\"san\",9,\"hej\",17,\"hej\">>].", + [8,17]), + ?line check( + fun() -> + L = 8, << <<B:32>> || <<L:L,B:L>> <= <<16:8, 7:16>> >> + end, + "begin L = 8, << <<B:32>> || <<L:L,B:L>> <= <<16:8, 7:16>> >> + end.", + <<0,0,0,7>>), + %% Test the Value part of a binary segment. + %% "Old" bugs have been fixed (partial_eval is called on Value). + ?line check(fun() -> [ 3 || <<17/float>> <= <<17.0/float>>] end, + "[ 3 || <<17/float>> <= <<17.0/float>>].", + [3]), + ?line check(fun() -> [ 3 || <<17/float>> <- [<<17.0/float>>]] end, + "[ 3 || <<17/float>> <- [<<17.0/float>>]].", + [3]), + ?line check(fun() -> [ X || <<17/float,X:3>> <= <<17.0/float,2:3>>] end, + "[ X || <<17/float,X:3>> <= <<17.0/float,2:3>>].", + [2]), + ?line check(fun() -> + [ foo || <<(1 bsl 1023)/float>> <= <<(1 bsl 1023)/float>>] + end, + "[ foo || <<(1 bsl 1023)/float>> <= <<(1 bsl 1023)/float>>].", + [foo]), + ?line check(fun() -> + [ foo || <<(1 bsl 1023)/float>> <- [<<(1 bsl 1023)/float>>]] + end, + "[ foo || <<(1 bsl 1023)/float>> <- [<<(1 bsl 1023)/float>>]].", + [foo]), + ?line error_check("[ foo || <<(1 bsl 1024)/float>> <- + [<<(1 bsl 1024)/float>>]].", + badarg), + ?line check(fun() -> + [ foo || <<(1 bsl 1024)/float>> <- [<<(1 bsl 1023)/float>>]] + end, + "[ foo || <<(1 bsl 1024)/float>> <- + [<<(1 bsl 1023)/float>>]].", + []), + ?line check(fun() -> + [ foo || <<(1 bsl 1024)/float>> <= <<(1 bsl 1023)/float>>] + end, + "[ foo || <<(1 bsl 1024)/float>> <= + <<(1 bsl 1023)/float>>].", + []), + ?line check(fun() -> + L = 8, + [{L,B} || <<L:L,B:L/float>> <= <<32:8,7:32/float>>] + end, + "begin L = 8, + [{L,B} || <<L:L,B:L/float>> <= <<32:8,7:32/float>>] + end.", + [{32,7.0}]), + ?line check(fun() -> + L = 8, + [{L,B} || <<L:L,B:L/float>> <- [<<32:8,7:32/float>>]] + end, + "begin L = 8, + [{L,B} || <<L:L,B:L/float>> <- [<<32:8,7:32/float>>]] + end.", + [{32,7.0}]), + ?line check(fun() -> + [foo || <<"s">> <= <<"st">>] + end, + "[foo || <<\"s\">> <= <<\"st\">>].", + [foo]), + ?line check(fun() -> <<_:32>> = <<17:32>> end, + "<<_:32>> = <<17:32>>.", + <<17:32>>), + ?line check(fun() -> [foo || <<_:32>> <= <<17:32,20:32>>] end, + "[foo || <<_:32>> <= <<17:32,20:32>>].", + [foo,foo]), + + ?line check(fun() -> << <<X:32>> || X <- [1,2,3], X > 1 >> end, + "<< <<X:32>> || X <- [1,2,3], X > 1 >>.", + <<0,0,0,2,0,0,0,3>>), + ?line error_check("[X || <<X>> <= [a,b]].",{bad_generator,[a,b]}), + ok. + +otp_6787(doc) -> + ["OTP-6787. bitlevel binaries."]; +otp_6787(suite) -> + []; +otp_6787(Config) when is_list(Config) -> + ?line check( + fun() -> <<16:(1024*1024)>> = <<16:(1024*1024)>> end, + "<<16:(1024*1024)>> = <<16:(1024*1024)>>.", + <<16:1048576>>), + ok. + +otp_6977(doc) -> + ["OTP-6977. ++ bug."]; +otp_6977(suite) -> + []; +otp_6977(Config) when is_list(Config) -> + ?line check( + fun() -> (fun([$X] ++ _) -> ok end)("X") end, + "(fun([$X] ++ _) -> ok end)(\"X\").", + ok), + ok. + +otp_7550(doc) -> + ["OTP-7550. Support for UTF-8, UTF-16, UTF-32."]; +otp_7550(Config) when is_list(Config) -> + + %% UTF-8. + ?line check( + fun() -> <<65>> = <<65/utf8>> end, + "<<65>> = <<65/utf8>>.", + <<65>>), + ?line check( + fun() -> <<350/utf8>> = <<197,158>> end, + "<<350/utf8>> = <<197,158>>.", + <<197,158>>), + ?line check( + fun() -> <<$b,$j,$\303,$\266,$r,$n>> = <<"bj\366rn"/utf8>> end, + "<<$b,$j,$\303,$\266,$r,$n>> = <<\"bj\366rn\"/utf8>>.", + <<$b,$j,$\303,$\266,$r,$n>>), + + %% UTF-16. + ?line check( + fun() -> <<0,65>> = <<65/utf16>> end, + "<<0,65>> = <<65/utf16>>.", + <<0,65>>), + ?line check( + fun() -> <<16#D8,16#08,16#DF,16#45>> = <<16#12345/utf16>> end, + "<<16#D8,16#08,16#DF,16#45>> = <<16#12345/utf16>>.", + <<16#D8,16#08,16#DF,16#45>>), + ?line check( + fun() -> <<16#08,16#D8,16#45,16#DF>> = <<16#12345/little-utf16>> end, + "<<16#08,16#D8,16#45,16#DF>> = <<16#12345/little-utf16>>.", + <<16#08,16#D8,16#45,16#DF>>), + + ?line check( + fun() -> <<350/utf16>> = <<1,94>> end, + "<<350/utf16>> = <<1,94>>.", + <<1,94>>), + ?line check( + fun() -> <<350/little-utf16>> = <<94,1>> end, + "<<350/little-utf16>> = <<94,1>>.", + <<94,1>>), + ?line check( + fun() -> <<16#12345/utf16>> = <<16#D8,16#08,16#DF,16#45>> end, + "<<16#12345/utf16>> = <<16#D8,16#08,16#DF,16#45>>.", + <<16#D8,16#08,16#DF,16#45>>), + ?line check( + fun() -> <<16#12345/little-utf16>> = <<16#08,16#D8,16#45,16#DF>> end, + "<<16#12345/little-utf16>> = <<16#08,16#D8,16#45,16#DF>>.", + <<16#08,16#D8,16#45,16#DF>>), + + %% UTF-32. + ?line check( + fun() -> <<16#12345/utf32>> = <<16#0,16#01,16#23,16#45>> end, + "<<16#12345/utf32>> = <<16#0,16#01,16#23,16#45>>.", + <<16#0,16#01,16#23,16#45>>), + ?line check( + fun() -> <<16#0,16#01,16#23,16#45>> = <<16#12345/utf32>> end, + "<<16#0,16#01,16#23,16#45>> = <<16#12345/utf32>>.", + <<16#0,16#01,16#23,16#45>>), + ?line check( + fun() -> <<16#12345/little-utf32>> = <<16#45,16#23,16#01,16#00>> end, + "<<16#12345/little-utf32>> = <<16#45,16#23,16#01,16#00>>.", + <<16#45,16#23,16#01,16#00>>), + ?line check( + fun() -> <<16#12345/little-utf32>> end, + "<<16#12345/little-utf32>>.", + <<16#45,16#23,16#01,16#00>>), + + %% Mixed. + ?line check( + fun() -> <<16#41,16#12345/utf32,16#0391:16,16#2E:8>> end, + "<<16#41,16#12345/utf32,16#0391:16,16#2E:8>>.", + <<16#41,16#00,16#01,16#23,16#45,16#03,16#91,16#2E>>), + ok. + + +otp_8133(doc) -> + ["OTP-8133. Bit comprehension bug."]; +otp_8133(suite) -> + []; +otp_8133(Config) when is_list(Config) -> + ?line check( + fun() -> + E = fun(N) -> + if + is_integer(N) -> <<N/integer>>; + true -> throw(foo) + end + end, + try << << (E(V))/binary >> || V <- [1,2,3,a] >> + catch foo -> ok + end + end, + "begin + E = fun(N) -> + if is_integer(N) -> <<N/integer>>; + true -> throw(foo) + end + end, + try << << (E(V))/binary >> || V <- [1,2,3,a] >> + catch foo -> ok + end + end.", + ok), + ?line check( + fun() -> + E = fun(N) -> + if + is_integer(N) -> <<N/integer>>; + true -> erlang:error(foo) + end + end, + try << << (E(V))/binary >> || V <- [1,2,3,a] >> + catch error:foo -> ok + end + end, + "begin + E = fun(N) -> + if is_integer(N) -> <<N/integer>>; + true -> erlang:error(foo) + end + end, + try << << (E(V))/binary >> || V <- [1,2,3,a] >> + catch error:foo -> ok + end + end.", + ok), + ok. + +funs(doc) -> + ["Simple cases, just to cover some code."]; +funs(suite) -> + []; +funs(Config) when is_list(Config) -> + do_funs(none, none), + do_funs(lfh(), none), + do_funs(lfh(), efh()), + + ?line error_check("nix:foo().", {access_not_allowed,nix}, lfh(), efh()), + ?line error_check("bar().", undef, none, none), + + ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end, + F1(F1, 1000) end, + "begin F1 = fun(F,N) -> count_down(F, N) end," + "F1(F1,1000) end.", + 0, ['F1'], lfh(), none), + + ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end, + F1(F1, 1000) end, + "begin F1 = fun(F,N) -> count_down(F, N) end," + "F1(F1,1000) end.", + 0, ['F1'], lfh_value(), none), + + ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end, + F1(F1, 1000) end, + "begin F1 = fun(F,N) -> count_down(F, N) end," + "F1(F1,1000) end.", + 0, ['F1'], lfh_value_extra(), none), + + ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end, + F1(F1, 1000) end, + "begin F1 = fun(F,N) -> count_down(F, N) end," + "F1(F1,1000) end.", + 0, ['F1'], {?MODULE,local_func_value}, none), + %% This is not documented, and only for backward compatibility (good!). + B0 = erl_eval:new_bindings(), + ?line check(fun() -> is_function(?MODULE:count_down_fun()) end, + "begin is_function(count_down_fun()) end.", + true, [], {?MODULE,local_func,[B0]},none), + + EF = fun({timer,sleep}, As) when length(As) == 1 -> exit({got_it,sleep}); + ({M,F}, As) -> apply(M, F, As) + end, + EFH = {value, EF}, + ?line error_check("apply(timer, sleep, [1]).", got_it, none, EFH), + ?line error_check("begin F = fun(T) -> timer:sleep(T) end,F(1) end.", + got_it, none, EFH), + ?line error_check("fun c/1.", undef), + ?line error_check("fun a:b/0().", undef), + + MaxArgs = 20, + ?line [true] = + lists:usort([run_many_args(SAs) || SAs <- many_args(MaxArgs)]), + ?line {'EXIT',{{argument_limit,_},_}} = + (catch run_many_args(many_args1(MaxArgs+1))), + ok. + +run_many_args({S, As}) -> + apply(eval_string(S), As) =:= As. + +many_args(N) -> + [many_args1(I) || I <- lists:seq(1, N)]. + +many_args1(N) -> + F = fun(L, P) -> + tl(lists:flatten([","++P++integer_to_list(E) || E <- L])) + end, + L = lists:seq(1, N), + T = F(L, "V"), + S = lists:flatten(io_lib:format("fun(~s) -> [~s] end.", [T, T])), + {S, L}. + +do_funs(LFH, EFH) -> + %% LFH is not really used by these examples... + + %% These tests do not prove that tail recursive functions really + %% work (that the process does not grow); one should also run them + %% manually with 1000 replaced by 1000000. + + M = atom_to_list(?MODULE), + ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end, + F1(F1, 1000) end, + concat(["begin F1 = fun(F,N) -> ", M, + ":count_down(F, N) end, F1(F1,1000) end."]), + 0, ['F1'], LFH, EFH), + ?line check(fun() -> F1 = fun(F,N) -> apply(?MODULE,count_down,[F,N]) + end, F1(F1, 1000) end, + concat(["begin F1 = fun(F,N) -> apply(", M, + ",count_down,[F, N]) end, F1(F1,1000) end."]), + 0, ['F1'], LFH, EFH), + ?line check(fun() -> F1 = fun(F,N) -> {?MODULE,count_down}(F,N) + end, F1(F1, 1000) end, + concat(["begin F1 = fun(F,N) -> {", M, + ",count_down}(F, N) end, F1(F1,1000) end."]), + 0, ['F1'], LFH, EFH), + ?line check(fun() -> F = fun(F,N) when N > 0 -> apply(F,[F,N-1]); + (_F,0) -> ok end, + F(F, 1000) + end, + "begin F = fun(F,N) when N > 0 -> apply(F,[F,N-1]);" + "(_F,0) -> ok end," + "F(F, 1000) end.", + ok, ['F'], LFH, EFH), + ?line check(fun() -> F = fun(F,N) when N > 0 -> + apply(erlang,apply,[F,[F,N-1]]); + (_F,0) -> ok end, + F(F, 1000) + end, + "begin F = fun(F,N) when N > 0 ->" + "apply(erlang,apply,[F,[F,N-1]]);" + "(_F,0) -> ok end," + "F(F, 1000) end.", + ok, ['F'], LFH, EFH), + ?line check(fun() -> F = count_down_fun(), + SF = fun(SF, F1, N) -> F(SF, F1, N) end, + SF(SF, F, 1000) end, + concat(["begin F = ", M, ":count_down_fun()," + "SF = fun(SF, F1, N) -> F(SF, F1, N) end," + "SF(SF, F, 1000) end."]), + ok, ['F','SF'], LFH, EFH), + + + ?line check(fun() -> F = fun(X) -> A = 1+X, {X,A} end, + true = {2,3} == F(2) end, + "begin F = fun(X) -> A = 1+X, {X,A} end, + true = {2,3} == F(2) end.", true, ['F'], LFH, EFH), + ?line check(fun() -> F = fun(X) -> {erlang,'+'}(X,2) end, + true = 3 == F(1) end, + "begin F = fun(X) -> {erlang,'+'}(X,2) end," + " true = 3 == F(1) end.", true, ['F'], + LFH, EFH), + ?line check(fun() -> F = fun(X) -> byte_size(X) end, + ?MODULE:do_apply(F,<<"hej">>) end, + concat(["begin F = fun(X) -> size(X) end,", + M,":do_apply(F,<<\"hej\">>) end."]), + 3, ['F'], LFH, EFH), + + ?line check(fun() -> F1 = fun(X, Z) -> {X,Z} end, + Z = 5, + F2 = fun(X, Y) -> F1(Z,{X,Y}) end, + F3 = fun(X, Y) -> {a,F1(Z,{X,Y})} end, + {5,{x,y}} = F2(x,y), + {a,{5,{y,x}}} = F3(y,x), + {5,{5,y}} = F2(Z,y), + true = {5,{x,5}} == F2(x,Z) end, + "begin F1 = fun(X, Z) -> {X,Z} end, + Z = 5, + F2 = fun(X, Y) -> F1(Z,{X,Y}) end, + F3 = fun(X, Y) -> {a,F1(Z,{X,Y})} end, + {5,{x,y}} = F2(x,y), + {a,{5,{y,x}}} = F3(y,x), + {5,{5,y}} = F2(Z,y), + true = {5,{x,5}} == F2(x,Z) end.", + true, ['F1','Z','F2','F3'], LFH, EFH), + ?line check(fun() -> F = fun(X) -> byte_size(X) end, + F2 = fun(Y) -> F(Y) end, + ?MODULE:do_apply(F2,<<"hej">>) end, + concat(["begin F = fun(X) -> size(X) end,", + "F2 = fun(Y) -> F(Y) end,", + M,":do_apply(F2,<<\"hej\">>) end."]), + 3, ['F','F2'], LFH, EFH), + ?line check(fun() -> Z = 5, F = fun(X) -> {Z,X} end, + F2 = fun(Z) -> F(Z) end, F2(3) end, + "begin Z = 5, F = fun(X) -> {Z,X} end, + F2 = fun(Z) -> F(Z) end, F2(3) end.", + {5,3},['F','F2','Z'], LFH, EFH), + ?line check(fun() -> F = fun(Z) -> Z end, + F2 = fun(X) -> F(X), Z = {X,X}, Z end, + {1,1} = F2(1), Z = 7, Z end, + "begin F = fun(Z) -> Z end, + F2 = fun(X) -> F(X), Z = {X,X}, Z end, + {1,1} = F2(1), Z = 7, Z end.", 7, ['F','F2','Z'], + LFH, EFH), + ?line check(fun() -> F = fun(F, N) -> [?MODULE:count_down(F,N) || X <-[1]] + end, F(F,2) end, + concat(["begin F = fun(F, N) -> [", M, + ":count_down(F,N) || X <-[1]] end, F(F,2) end."]), + [[[0]]], ['F'], LFH, EFH), + ok. + +count_down(F, N) when N > 0 -> + F(F, N-1); +count_down(_F, N) -> + N. + +count_down_fun() -> + fun(SF,F,N) when N > 0 -> SF(SF,F,N-1); + (_SF,_F,_N) -> ok + end. + +do_apply(F, V) -> + F(V). + +lfh() -> + {eval, fun(F, As, Bs) -> local_func(F, As, Bs) end}. + +local_func(F, As0, Bs0) when is_atom(F) -> + {As,Bs} = erl_eval:expr_list(As0, Bs0, {eval,lfh()}), + case erlang:function_exported(?MODULE, F, length(As)) of + true -> + {value,apply(?MODULE, F, As),Bs}; + false -> + {value,apply(shell_default, F, As),Bs} + end. + +lfh_value_extra() -> + %% Not documented. + {value, fun(F, As) -> local_func_value(F, As) end, []}. + +lfh_value() -> + {value, fun(F, As) -> local_func_value(F, As) end}. + +local_func_value(F, As) when is_atom(F) -> + case erlang:function_exported(?MODULE, F, length(As)) of + true -> + apply(?MODULE, F, As); + false -> + apply(shell_default, F, As) + end. + +efh() -> + {value, fun(F, As) -> external_func(F, As) end}. + +external_func({M,_}, _As) when M == nix -> + exit({{access_not_allowed,M},[mfa]}); +external_func(F, As) when is_function(F) -> + apply(F, As); +external_func({M,F}, As) -> + apply(M, F, As). + + + +try_catch(doc) -> + ["Test try-of-catch-after-end statement"]; +try_catch(suite) -> + []; +try_catch(Config) when is_list(Config) -> + %% Match in of with catch + ?line check(fun() -> try 1 of 1 -> 2 catch _:_ -> 3 end end, + "try 1 of 1 -> 2 catch _:_ -> 3 end.", 2), + ?line check(fun() -> try 1 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end end, + "try 1 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end.", 2), + ?line check(fun() -> try 3 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end end, + "try 3 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end.", 4), + %% Just after + ?line check(fun () -> X = try 1 after put(try_catch, 2) end, + {X,get(try_catch)} end, + "begin X = try 1 after put(try_catch, 2) end, " + "{X,get(try_catch)} end.", {1,2}), + %% Match in of with after + ?line check(fun() -> X = try 1 of 1 -> 2 after put(try_catch, 3) end, + {X,get(try_catch)} end, + "begin X = try 1 of 1 -> 2 after put(try_catch, 3) end, " + "{X,get(try_catch)} end.", {2,3}), + ?line check(fun() -> X = try 1 of 1 -> 2; 3 -> 4 + after put(try_catch, 5) end, + {X,get(try_catch)} end, + "begin X = try 1 of 1 -> 2; 3 -> 4 " + " after put(try_catch, 5) end, " + " {X,get(try_catch)} end.", {2,5}), + ?line check(fun() -> X = try 3 of 1 -> 2; 3 -> 4 + after put(try_catch, 5) end, + {X,get(try_catch)} end, + "begin X = try 3 of 1 -> 2; 3 -> 4 " + " after put(try_catch, 5) end, " + " {X,get(try_catch)} end.", {4,5}), + %% Nomatch in of + ?line error_check("try 1 of 2 -> 3 catch _:_ -> 4 end.", + {try_clause,1}), + %% Nomatch in of with after + ?line check(fun () -> {'EXIT',{{try_clause,1},_}} = + begin catch try 1 of 2 -> 3 + after put(try_catch, 4) end end, + get(try_catch) end, + "begin {'EXIT',{{try_clause,1},_}} = " + " begin catch try 1 of 2 -> 3 " + " after put(try_catch, 4) end end, " + " get(try_catch) end. ", 4), + %% Exception in try + ?line check(fun () -> try 1=2 catch error:{badmatch,2} -> 3 end end, + "try 1=2 catch error:{badmatch,2} -> 3 end.", 3), + ?line check(fun () -> try 1=2 of 3 -> 4 + catch error:{badmatch,2} -> 5 end end, + "try 1=2 of 3 -> 4 " + "catch error:{badmatch,2} -> 5 end.", 5), + %% Exception in try with after + ?line check(fun () -> X = try 1=2 + catch error:{badmatch,2} -> 3 + after put(try_catch, 4) end, + {X,get(try_catch)} end, + "begin X = try 1=2 " + " catch error:{badmatch,2} -> 3 " + " after put(try_catch, 4) end, " + " {X,get(try_catch)} end. ", {3,4}), + ?line check(fun () -> X = try 1=2 of 3 -> 4 + catch error:{badmatch,2} -> 5 + after put(try_catch, 6) end, + {X,get(try_catch)} end, + "begin X = try 1=2 of 3 -> 4" + " catch error:{badmatch,2} -> 5 " + " after put(try_catch, 6) end, " + " {X,get(try_catch)} end. ", {5,6}), + %% Uncaught exception + ?line error_check("try 1=2 catch error:undefined -> 3 end. ", + {badmatch,2}), + ?line error_check("try 1=2 of 3 -> 4 catch error:undefined -> 5 end. ", + {badmatch,2}), + %% Uncaught exception with after + ?line check(fun () -> {'EXIT',{{badmatch,2},_}} = + begin catch try 1=2 + after put(try_catch, 3) end end, + get(try_catch) end, + "begin {'EXIT',{{badmatch,2},_}} = " + " begin catch try 1=2 " + " after put(try_catch, 3) end end, " + " get(try_catch) end. ", 3), + ?line check(fun () -> {'EXIT',{{badmatch,2},_}} = + begin catch try 1=2 of 3 -> 4 + after put(try_catch, 5) end end, + get(try_catch) end, + "begin {'EXIT',{{badmatch,2},_}} = " + " begin catch try 1=2 of 3 -> 4" + " after put(try_catch, 5) end end, " + " get(try_catch) end. ", 5), + ?line check(fun () -> {'EXIT',{{badmatch,2},_}} = + begin catch try 1=2 catch error:undefined -> 3 + after put(try_catch, 4) end end, + get(try_catch) end, + "begin {'EXIT',{{badmatch,2},_}} = " + " begin catch try 1=2 catch error:undefined -> 3 " + " after put(try_catch, 4) end end, " + " get(try_catch) end. ", 4), + ?line check(fun () -> {'EXIT',{{badmatch,2},_}} = + begin catch try 1=2 of 3 -> 4 + catch error:undefined -> 5 + after put(try_catch, 6) end end, + get(try_catch) end, + "begin {'EXIT',{{badmatch,2},_}} = " + " begin catch try 1=2 of 3 -> 4 " + " catch error:undefined -> 5 " + " after put(try_catch, 6) end end, " + " get(try_catch) end. ", 6), + ok. + + +eval_expr_5(doc) -> + ["(OTP-7933)"]; +eval_expr_5(suite) -> + []; +eval_expr_5(Config) when is_list(Config) -> + ?line {ok,Tokens ,_} = + erl_scan:string("if a+4 == 4 -> yes; true -> no end. "), + ?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens), + ?line {value, no, []} = erl_eval:expr(Expr, [], none, none, none), + ?line no = erl_eval:expr(Expr, [], none, none, value), + try + erl_eval:expr(Expr, [], none, none, 4711), + ?line function_clause = should_never_reach_here + catch + error:function_clause -> + ok + end. + +%% Check the string in different contexts: as is; in fun; from compiled code. +check(F, String, Result) -> + check1(F, String, Result), + FunString = concat(["fun() -> ", no_final_dot(String), " end(). "]), + check1(F, FunString, Result), + CompileString = concat(["hd(lists:map(fun(_) -> ", no_final_dot(String), + " end, [foo])). "]), + check1(F, CompileString, Result). + +check1(F, String, Result) -> + Result = F(), + case catch parse_and_run(String) of + {value, Result, _} -> + ok; + Other -> + test_server:fail({eval, Other, Result}) + end. + +check(F, String, Result, BoundVars, LFH, EFH) -> + Result = F(), + case catch parse_and_run(String, LFH, EFH) of + {value, Result, Bs} -> + %% We just assume that Bs is an orddict... + Keys = orddict:fetch_keys(Bs), + case sort(BoundVars) == Keys of + true -> + ok; + false -> + test_server:fail({check, BoundVars, Keys}) + end, + ok; + Other -> + test_server:fail({check, Other, Result}) + end. + +error_check(String, Result) -> + case catch parse_and_run(String) of + {'EXIT', {Result,_}} -> + ok; + Other -> + test_server:fail({eval, Other, Result}) + end. + +error_check(String, Result, LFH, EFH) -> + case catch parse_and_run(String, LFH, EFH) of + {'EXIT', {Result,_}} -> + ok; + Other -> + test_server:fail({eval, Other, Result}) + end. + +eval_string(String) -> + {value, Result, _} = parse_and_run(String), + Result. + +parse_and_run(String) -> + {ok,Tokens,_} = erl_scan:string(String), + {ok, [Expr]} = erl_parse:parse_exprs(Tokens), + erl_eval:expr(Expr, []). + +parse_and_run(String, LFH, EFH) -> + {ok,Tokens,_} = erl_scan:string(String), + {ok, [Expr]} = erl_parse:parse_exprs(Tokens), + erl_eval:expr(Expr, [], LFH, EFH). + +no_final_dot(S) -> + case lists:reverse(S) of + " ." ++ R -> lists:reverse(R); + "." ++ R -> lists:reverse(R); + _ -> S + end. diff --git a/lib/debugger/test/exception_SUITE.erl b/lib/debugger/test/exception_SUITE.erl new file mode 100644 index 0000000000..a74a93fd22 --- /dev/null +++ b/lib/debugger/test/exception_SUITE.erl @@ -0,0 +1,256 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(exception_SUITE). + +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + badmatch/1,pending_errors/1,nil_arith/1]). + +-export([bad_guy/2]). + +-include("test_server.hrl"). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [badmatch, pending_errors, nil_arith]. + +-define(try_match(E), + catch ?MODULE:bar(), + {'EXIT', {{badmatch, nomatch}, _}} = (catch E = nomatch)). + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +badmatch(doc) -> "Test that deliberately bad matches are reported correctly."; +badmatch(suite) -> []; +badmatch(Config) when list(Config) -> + ?line ?try_match(a), + ?line ?try_match(42), + ?line ?try_match({a, b, c}), + ?line ?try_match([]), + ?line ?try_match(1.0), + ok. + +pending_errors(doc) -> + ["Test various exceptions, in the presence of a previous error suppressed ", + "in a guard."]; +pending_errors(suite) -> []; +pending_errors(Config) when list(Config) -> + ?line pending(e_badmatch, {badmatch, b}), + ?line pending(x, function_clause), + ?line pending(e_case, {case_clause, xxx}), + ?line pending(e_if, if_clause), + ?line pending(e_badarith, badarith), + ?line pending(e_undef, undef), + ?line pending(e_timeoutval, timeout_value), + ?line pending(e_badarg, badarg), + ?line pending(e_badarg_spawn, badarg), + ok. + +bad_guy(pe_badarith, Other) when Other+1 == 0 -> % badarith (suppressed) + ok; +bad_guy(pe_badarg, Other) when length(Other) > 0 -> % badarg (suppressed) + ok; +bad_guy(_, e_case) -> + case xxx of + ok -> ok + end; % case_clause +bad_guy(_, e_if) -> + if + a == b -> ok + end; % if_clause +bad_guy(_, e_badarith) -> + 1+b; % badarith +bad_guy(_, e_undef) -> + non_existing_module:foo(); % undef +bad_guy(_, e_timeoutval) -> + receive + after arne -> % timeout_value + ok + end; +bad_guy(_, e_badarg) -> + node(xxx); % badarg +bad_guy(_, e_badarg_spawn) -> + spawn({}, {}, {}); % badarg +bad_guy(_, e_badmatch) -> + a = b. % badmatch + +pending(Arg, Expected) -> + pending(pe_badarith, Arg, Expected), + pending(pe_badarg, Arg, Expected). + +pending(First, Second, Expected) -> + pending_catched(First, Second, Expected), + pending_exit_message([First, Second], Expected). + +pending_catched(First, Second, Expected) -> + ok = io:format("Catching bad_guy(~p, ~p)", [First, Second]), + case catch bad_guy(First, Second) of + {'EXIT', Reason} -> + pending(Reason, bad_guy, [First, Second], Expected); + Other -> + test_server:fail({not_exit, Other}) + end. + +pending_exit_message(Args, Expected) -> + ok = io:format("Trapping EXITs from spawn_link(~p, ~p, ~p)", + [?MODULE, bad_guy, Args]), + process_flag(trap_exit, true), + Pid = spawn_link(?MODULE, bad_guy, Args), + receive + {'EXIT', Pid, Reason} -> + pending(Reason, bad_guy, Args, Expected); + Other -> + test_server:fail({unexpected_message, Other}) + after 10000 -> + test_server:fail(timeout) + end, + process_flag(trap_exit, false). + +pending({badarg,[{erlang,Bif,BifArgs},{?MODULE,Func,Arity}|_]}, Func, Args, _Code) + when atom(Bif), list(BifArgs), length(Args) == Arity -> %Threaded code. + ok; +pending({badarg,[{erlang,Bif,BifArgs},{?MODULE,Func,Args}|_]}, Func, Args, _Code) + when atom(Bif), list(BifArgs) -> %From interpreted code. + ok; +pending({undef,[{non_existing_module,foo,[]}|_]}, _, _, _) -> + ok; +pending({function_clause,[{?MODULE,Func,Args}|_]}, Func, Args, _Code) -> + ok; +pending({Code,[{?MODULE,Func,Arity}|_]}, Func, Args, Code) when length(Args) == Arity -> %Threaded code + ok; +pending({Code,[{?MODULE,Func,Args}|_]}, Func, Args, Code) -> %From interpreted code. + ok; +pending(Reason, Func, Args, Code) -> + test_server:fail({bad_exit_reason,Reason,{Func,Args,Code}}). + +nil_arith(doc) -> + "Test that doing arithmetics on [] gives a badarith EXIT and not a crash."; +nil_arith(suite) -> + []; +nil_arith(Config) when list(Config) -> + ?line ba_plus_minus_times([], []), + + ?line ba_plus_minus_times([], 0), + ?line ba_plus_minus_times([], 42), + ?line ba_plus_minus_times([], 38724978123478923784), + ?line ba_plus_minus_times([], 38.72), + + ?line ba_plus_minus_times(0, []), + ?line ba_plus_minus_times(334, []), + ?line ba_plus_minus_times(387249797813478923784, []), + ?line ba_plus_minus_times(344.22, []), + + ?line ba_div_rem([], []), + + ?line ba_div_rem([], 0), + ?line ba_div_rem([], 1), + ?line ba_div_rem([], 42), + ?line ba_div_rem([], 38724978123478923784), + ?line ba_div_rem(344.22, []), + + ?line ba_div_rem(0, []), + ?line ba_div_rem(1, []), + ?line ba_div_rem(334, []), + ?line ba_div_rem(387249797813478923784, []), + ?line ba_div_rem(344.22, []), + + ?line ba_div_rem(344.22, 0.0), + ?line ba_div_rem(1, 0.0), + ?line ba_div_rem(392873498733971, 0.0), + + ?line ba_bop([], []), + ?line ba_bop(0, []), + ?line ba_bop(42, []), + ?line ba_bop(-42342742987343, []), + ?line ba_bop(238.342, []), + ?line ba_bop([], 0), + ?line ba_bop([], -243), + ?line ba_bop([], 243), + ?line ba_bop([], 2438724982478933), + ?line ba_bop([], 3987.37), + + ?line ba_bnot([]), + ?line ba_bnot(23.33), + + ?line ba_shift([], []), + ?line ba_shift([], 0), + ?line ba_shift([], 4), + ?line ba_shift([], -4), + ?line ba_shift([], 2343333333333), + ?line ba_shift([], -333333333), + ?line ba_shift([], 234.00), + ?line ba_shift(23, []), + ?line ba_shift(0, []), + ?line ba_shift(-3433443433433323, []), + ?line ba_shift(433443433433323, []), + ?line ba_shift(343.93, []), + ok. + +ba_plus_minus_times(A, B) -> + io:format("~p + ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A + B), + io:format("~p - ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A - B), + io:format("~p * ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A * B). + +ba_div_rem(A, B) -> + io:format("~p / ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A / B), + io:format("~p div ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A div B), + io:format("~p rem ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A rem B). + +ba_bop(A, B) -> + io:format("~p band ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A band B), + io:format("~p bor ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A bor B), + io:format("~p bxor ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A bxor B). + +ba_shift(A, B) -> + io:format("~p bsl ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A bsl B), + io:format("~p bsr ~p", [A, B]), + {'EXIT', {badarith, _}} = (catch A bsr B). + +ba_bnot(A) -> + io:format("bnot ~p", [A]), + {'EXIT', {badarith, _}} = (catch bnot A). diff --git a/lib/debugger/test/fun_SUITE.erl b/lib/debugger/test/fun_SUITE.erl new file mode 100644 index 0000000000..721048b6b6 --- /dev/null +++ b/lib/debugger/test/fun_SUITE.erl @@ -0,0 +1,233 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(fun_SUITE). + +-export([all/1, + init_per_testcase/2,end_per_testcase/2, + init_all/1,finish_all/1, + good_call/1,bad_apply/1,bad_fun_call/1,badarity/1, + ext_badarity/1,otp_6061/1]). +-export([nothing/0]). + +-include("test_server.hrl"). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [good_call,bad_apply,bad_fun_call,badarity,ext_badarity,otp_6061]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +end_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +good_call(Config) when is_list(Config) -> + ?line F = fun() -> ok end, + ?line ok = F(), + ?line FF = fun ?MODULE:nothing/0, + ?line ok = FF(), + ok. + +bad_apply(doc) -> + "Test that the correct EXIT code is returned for all types of bad funs."; +bad_apply(suite) -> []; +bad_apply(Config) when is_list(Config) -> + ?line bad_apply_fc(42, [0]), + ?line bad_apply_fc(xx, [1]), + ?line bad_apply_fc({}, [2]), + ?line bad_apply_fc({1}, [3]), + ?line bad_apply_fc({1,2,3}, [4]), + ?line bad_apply_fc({1,2,3}, [5]), + ?line bad_apply_fc({1,2,3,4}, [6]), + ?line bad_apply_fc({1,2,3,4,5,6}, [7]), + ?line bad_apply_fc({1,2,3,4,5}, [8]), + ?line bad_apply_badarg({1,2}, [9]), + ok. + +bad_apply_fc(Fun, Args) -> + Res = (catch apply(Fun, Args)), + erlang:garbage_collect(), + erlang:yield(), + case Res of + {'EXIT',{{badfun,Fun},_Where}} -> + ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res]); + Other -> + ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res]), + ?t:fail({bad_result,Other}) + end. + +bad_apply_badarg(Fun, Args) -> + Res = (catch apply(Fun, Args)), + erlang:garbage_collect(), + erlang:yield(), + case Res of + {'EXIT',{{badfun,Fun},_Where}} -> + ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res]); + Other -> + ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res]), + ?t:fail({bad_result, Other}) + end. + +bad_fun_call(doc) -> + "Try directly calling bad funs."; +bad_fun_call(suite) -> []; +bad_fun_call(Config) when is_list(Config) -> + ?line bad_call_fc(42), + ?line bad_call_fc(xx), + ?line bad_call_fc({}), + ?line bad_call_fc({1}), + ?line bad_call_fc({1,2,3}), + ?line bad_call_fc({1,2,3}), + ?line bad_call_fc({1,2,3,4}), + ?line bad_call_fc({1,2,3,4,5,6}), + ?line bad_call_fc({1,2,3,4,5}), + ?line bad_call_fc({1,2}), + ok. + +bad_call_fc(Fun) -> + Args = [some,stupid,args], + Res = (catch Fun(Args)), + case Res of + {'EXIT',{{badfun,Fun},_Where}} -> + ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]); + Other -> + ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]), + ?t:fail({bad_result,Other}) + end. + +%% Call and apply valid external funs with wrong number of arguments. + +badarity(Config) when is_list(Config) -> + ?line Fun = fun() -> ok end, + ?line Stupid = {stupid,arguments}, + ?line Args = [some,{stupid,arguments},here], + + %% Simple call. + + ?line Res = (catch Fun(some, Stupid, here)), + erlang:garbage_collect(), + erlang:yield(), + case Res of + {'EXIT',{{badarity,{Fun,Args}},[_|_]}} -> + ?line ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]); + _ -> + ?line ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]), + ?line ?t:fail({bad_result,Res}) + end, + + %% Apply. + + ?line Res2 = (catch apply(Fun, Args)), + erlang:garbage_collect(), + erlang:yield(), + case Res2 of + {'EXIT',{{badarity,{Fun,Args}},[_|_]}} -> + ?line ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res2]); + _ -> + ?line ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res2]), + ?line ?t:fail({bad_result,Res2}) + end, + ok. + +%% Call and apply valid external funs with wrong number of arguments. + +ext_badarity(Config) when is_list(Config) -> + ?line Fun = fun ?MODULE:nothing/0, + ?line Stupid = {stupid,arguments}, + ?line Args = [some,{stupid,arguments},here], + + %% Simple call. + + ?line Res = (catch Fun(some, Stupid, here)), + erlang:garbage_collect(), + erlang:yield(), + case Res of + {'EXIT',{{badarity,{Fun,Args}},_}} -> + ?line ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]); + _ -> + ?line ok = io:format("~p(~p) -> ~p\n", [Fun,Args,Res]), + ?line ?t:fail({bad_result,Res}) + end, + + %% Apply. + + ?line Res2 = (catch apply(Fun, Args)), + erlang:garbage_collect(), + erlang:yield(), + case Res2 of + {'EXIT',{{badarity,{Fun,Args}},_}} -> + ?line ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res2]); + _ -> + ?line ok = io:format("apply(~p, ~p) -> ~p\n", [Fun,Args,Res2]), + ?line ?t:fail({bad_result,Res2}) + end, + ok. + +nothing() -> + ok. + +otp_6061(suite) -> + []; +otp_6061(doc) -> + ["Test handling of fun expression referring to uninterpreted code"]; +otp_6061(Config) when is_list(Config) -> + + ?line OrigFlag = process_flag(trap_exit, true), + + ?line Self = self(), + ?line Pid = spawn_link(fun() -> test_otp_6061(Self) end), + + receive + working -> + ?line ok; + not_working -> + ?line ?t:fail(not_working); + {'EXIT', Pid, Reason} -> + ?line ?t:fail({crash, Reason}) + after + 5000 -> + ?line ?t:fail(timeout) + end, + + ?line process_flag(trap_exit, OrigFlag), + + ok. + +test_otp_6061(Starter) -> + Passes = [2], + PassesF = [fun() -> Starter ! not_working end, + fun() -> Starter ! working end, + fun() -> Starter ! not_working end], + lists:foreach(fun(P)->(lists:nth(P,PassesF))() end,Passes). diff --git a/lib/debugger/test/guard_SUITE.erl b/lib/debugger/test/guard_SUITE.erl new file mode 100644 index 0000000000..b5269989c8 --- /dev/null +++ b/lib/debugger/test/guard_SUITE.erl @@ -0,0 +1,1479 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(guard_SUITE). + +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + bad_arith/1,bad_tuple/1,test_heap_guards/1,guard_bifs/1, + type_tests/1,const_guard/1, + const_cond/1,basic_not/1,complex_not/1, + semicolon/1,complex_semicolon/1,comma/1, + or_guard/1,more_or_guards/1, + complex_or_guards/1,and_guard/1, + xor_guard/1,more_xor_guards/1, + old_guard_tests/1, + build_in_guard/1,gbif/1, + t_is_boolean/1,is_function_2/1, + tricky/1,rel_ops/1, + basic_andalso_orelse/1,traverse_dcd/1, + check_qlc_hrl/1]). + +-include("test_server.hrl"). + +-export([init/4]). +-import(lists, [member/2]). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [bad_arith,bad_tuple,test_heap_guards,guard_bifs,type_tests,const_guard, + const_cond,basic_not,complex_not, + semicolon,complex_semicolon, + comma,or_guard,more_or_guards, + complex_or_guards,and_guard, + xor_guard,more_xor_guards, + build_in_guard,old_guard_tests,gbif, + t_is_boolean,is_function_2,tricky,rel_ops, + basic_andalso_orelse,traverse_dcd,check_qlc_hrl]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + ?line Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +bad_arith(doc) -> "Test that a bad arithmetic operation in a guard works correctly."; +bad_arith(suite) -> []; +bad_arith(Config) when list(Config) -> + ?line 5 = bad_arith1(2, 3), + ?line 10 = bad_arith1(1, infinity), + ?line 10 = bad_arith1(infinity, 1), + ?line 42 = bad_div(24, 0), + ok. + +bad_arith1(T1, T2) when T1+T2 < 10 -> + T1+T2; +bad_arith1(_, _) -> + 10. + +bad_div(A, B) when A/B > 0 -> + A/B; +bad_div(A, B) when A div B > 0 -> + A div B; +bad_div(_A, _B) -> + 42. + +bad_tuple(doc) -> "Test that bad arguments to element/2 are handled correctly."; +bad_tuple(suite) -> []; +bad_tuple(Config) when list(Config) -> + ?line error = bad_tuple1(a), + ?line error = bad_tuple1({a, b}), + ?line x = bad_tuple1({x, b}), + ?line y = bad_tuple1({a, b, y}), + ok. + +bad_tuple1(T) when element(1, T) == x -> x; +bad_tuple1(T) when element(3, T) == y -> y; +bad_tuple1(_) -> error. + +test_heap_guards(doc) -> ""; +test_heap_guards(suite) -> []; +test_heap_guards(Config) when list(Config) -> + ?line process_flag(trap_exit, true), + ?line Tuple = {a, tuple, is, built, here, xxx}, + ?line List = [a, list, is, built, here], + + ?line try_fun(fun a_case/1, [Tuple], [Tuple]), + ?line try_fun(fun a_case/1, [List], [List, List]), + ?line try_fun(fun a_case/1, [a], [a]), + + ?line try_fun(fun an_if/1, [Tuple], [Tuple]), + ?line try_fun(fun an_if/1, [List], [List, List]), + ?line try_fun(fun an_if/1, [a], [a]), + + ?line try_fun(fun receive_test/1, [Tuple], [Tuple]), + ?line try_fun(fun receive_test/1, [List], [List, List]), + ?line try_fun(fun receive_test/1, [a], [a]), + ok. + +a_case(V) -> + case V of + T when T == {a, tuple, is, built, here, xxx} -> + [T]; + L when L == [a, list, is, built, here] -> + [L, L]; + a -> + [a] + end. + +an_if(V) -> + if + V == {a, tuple, is, built, here, xxx} -> + [V]; + V == [a, list, is, built, here] -> + [V, V]; + V == a -> + [a] + end. + +receive_test(V) -> + self() ! V, + a_receive(). + +a_receive() -> + receive + T when T == {a, tuple, is, built, here, xxx} -> + [T]; + L when L == [a, list, is, built, here] -> + [L, L]; + a -> + [a] + end. + +try_fun(Fun, Args, Result) -> + try_fun(16, Fun, Args, Result, []). + +try_fun(0, _, _, _, _) -> + ok; +try_fun(Iter, Fun, Args, Result, Filler) -> + Pid = spawn_link(?MODULE, init, [self(),Fun,Args,list_to_tuple(Filler)]), + receive + {'EXIT',Pid,{result,Result}} -> + ?line try_fun(Iter-1, Fun, Args, Result, [0|Filler]); + {'EXIT',Pid,{result,Other}} -> + ?line io:format("Expected ~p; got ~p~n", [Result,Other]), + ?line test_server:fail(); + Other -> + ?line test_server:fail({unexpected_message,Other}) + end. + +init(_ReplyTo, Fun, Args, Filler) -> + Result = {result, apply(Fun, Args)}, + dummy(Filler), + io:format("~p: result = ~p\n", [?LINE,Result]), + exit(Result). + +dummy(_) -> + ok. + +guard_bifs(doc) -> "Test all guard bifs with nasty (but legal arguments)."; +guard_bifs(suite) -> []; +guard_bifs(Config) when list(Config) -> + ?line Big = -237849247829874297658726487367328971246284736473821617265433, + ?line Float = 387924.874, + + %% Succeding use of guard bifs. + + ?line try_gbif('abs/1', Big, -Big), + ?line try_gbif('float/1', Big, float(Big)), + ?line try_gbif('trunc/1', Float, 387924.0), + ?line try_gbif('round/1', Float, 387925.0), + ?line try_gbif('length/1', [], 0), + + ?line try_gbif('length/1', [a], 1), + ?line try_gbif('length/1', [a, b], 2), + ?line try_gbif('length/1', lists:seq(0, 31), 32), + + ?line try_gbif('hd/1', [a], a), + ?line try_gbif('hd/1', [a, b], a), + + ?line try_gbif('tl/1', [a], []), + ?line try_gbif('tl/1', [a, b], [b]), + ?line try_gbif('tl/1', [a, b, c], [b, c]), + + ?line try_gbif('size/1', {}, 0), + ?line try_gbif('size/1', {a}, 1), + ?line try_gbif('size/1', {a, b}, 2), + ?line try_gbif('size/1', {a, b, c}, 3), + ?line try_gbif('size/1', list_to_binary([]), 0), + ?line try_gbif('size/1', list_to_binary([1]), 1), + ?line try_gbif('size/1', list_to_binary([1, 2]), 2), + ?line try_gbif('size/1', list_to_binary([1, 2, 3]), 3), + + ?line try_gbif('element/2', {x}, {1, x}), + ?line try_gbif('element/2', {x, y}, {1, x}), + ?line try_gbif('element/2', {x, y}, {2, y}), + + ?line try_gbif('self/0', 0, self()), + ?line try_gbif('node/0', 0, node()), + ?line try_gbif('node/1', self(), node()), + + %% Failing use of guard bifs. + + ?line try_fail_gbif('abs/1', Big, 1), + ?line try_fail_gbif('abs/1', [], 1), + + ?line try_fail_gbif('float/1', Big, 42), + ?line try_fail_gbif('float/1', [], 42), + + ?line try_fail_gbif('trunc/1', Float, 0.0), + ?line try_fail_gbif('trunc/1', [], 0.0), + + ?line try_fail_gbif('round/1', Float, 1.0), + ?line try_fail_gbif('round/1', [], a), + + ?line try_fail_gbif('length/1', [], 1), + ?line try_fail_gbif('length/1', [a], 0), + ?line try_fail_gbif('length/1', a, 0), + ?line try_fail_gbif('length/1', {a}, 0), + + ?line try_fail_gbif('hd/1', [], 0), + ?line try_fail_gbif('hd/1', [a], x), + ?line try_fail_gbif('hd/1', x, x), + + ?line try_fail_gbif('tl/1', [], 0), + ?line try_fail_gbif('tl/1', [a], x), + ?line try_fail_gbif('tl/1', x, x), + + ?line try_fail_gbif('size/1', {}, 1), + ?line try_fail_gbif('size/1', [], 0), + ?line try_fail_gbif('size/1', [a], 1), + + ?line try_fail_gbif('element/2', {}, {1, x}), + ?line try_fail_gbif('element/2', {x}, {1, y}), + ?line try_fail_gbif('element/2', [], {1, z}), + + ?line try_fail_gbif('self/0', 0, list_to_pid("<0.0.0>")), + ?line try_fail_gbif('node/0', 0, xxxx), + ?line try_fail_gbif('node/1', self(), xxx), + ?line try_fail_gbif('node/1', yyy, xxx), + ok. + +try_gbif(Id, X, Y) -> + case guard_bif(Id, X, Y) of + {Id, X, Y} -> + io:format("guard_bif(~p, ~p, ~p) -- ok", [Id, X, Y]); + Other -> + ?line ok = io:format("guard_bif(~p, ~p, ~p) -- bad result: ~p\n", + [Id, X, Y, Other]), + ?line test_server:fail() + end. + +try_fail_gbif(Id, X, Y) -> + case catch guard_bif(Id, X, Y) of + {'EXIT', {function_clause,{?MODULE,guard_bif,[Id,X,Y]}}} -> %Jam + io:format("guard_bif(~p, ~p, ~p) -- ok", [Id,X,Y]); + {'EXIT', {function_clause,[{?MODULE,guard_bif,[Id,X,Y]}|_]}} -> %Beam + io:format("guard_bif(~p, ~p, ~p) -- ok", [Id,X,Y]); + Other -> + ?line ok = io:format("guard_bif(~p, ~p, ~p) -- bad result: ~p\n", + [Id, X, Y, Other]), + ?line test_server:fail() + end. + +guard_bif('abs/1', X, Y) when abs(X) == Y -> + {'abs/1', X, Y}; +guard_bif('float/1', X, Y) when float(X) == Y -> + {'float/1', X, Y}; +guard_bif('trunc/1', X, Y) when trunc(X) == Y -> + {'trunc/1', X, Y}; +guard_bif('round/1', X, Y) when round(X) == Y -> + {'round/1', X, Y}; +guard_bif('length/1', X, Y) when length(X) == Y -> + {'length/1', X, Y}; +guard_bif('hd/1', X, Y) when hd(X) == Y -> + {'hd/1', X, Y}; +guard_bif('tl/1', X, Y) when tl(X) == Y -> + {'tl/1', X, Y}; +guard_bif('size/1', X, Y) when size(X) == Y -> + {'size/1', X, Y}; +guard_bif('element/2', X, {Pos, Expected}) when element(Pos, X) == Expected -> + {'element/2', X, {Pos, Expected}}; +guard_bif('self/0', X, Y) when self() == Y -> + {'self/0', X, Y}; +guard_bif('node/0', X, Y) when node() == Y -> + {'node/0', X, Y}; +guard_bif('node/1', X, Y) when node(X) == Y -> + {'node/1', X, Y}. + +type_tests(doc) -> "Test the type tests."; +type_tests(suite) -> []; +type_tests(Config) when list(Config) -> + ?line Types = all_types(), + ?line Tests = type_test_desc(), + ?line put(errors, 0), + ?line put(violations, 0), + ?line type_tests(Tests, Types), + ?line case {get(errors), get(violations)} of + {0, 0} -> + ok; + {0, N} -> + {comment, integer_to_list(N) ++ " standard violation(s)"}; + {Errors, Violations} -> + io:format("~p sub test(s) failed, ~p violation(s)", + [Errors, Violations]), + ?line test_server:fail() + end. + +type_tests([{Test, AllowedTypes}| T], AllTypes) -> + type_tests(Test, AllTypes, AllowedTypes), + type_tests(T, AllTypes); +type_tests([], _) -> + ok. + +type_tests(Test, [Type|T], Allowed) -> + {TypeTag, Value} = Type, + case member(TypeTag, Allowed) of + true -> + case catch type_test(Test, Value) of + Test -> + ok; + _Other -> + io:format("Test ~p(~p) failed", [Test, Value]), + put(errors, get(errors) + 1) + end; + false -> + case catch type_test(Test, Value) of + {'EXIT', {function_clause, {?MODULE, type_test, [Test, Value]}}} -> + ok; + {'EXIT', {function_clause,[{?MODULE,type_test,[Test,Value]}|_]}} -> + ok; + {'EXIT',Other} -> + ?line test_server:fail({unexpected_error_reason,Other}); + tuple when function(Value) -> + io:format("Standard violation: Test ~p(~p) should fail", + [Test, Value]), + put(violations, get(violations) + 1); + _Other -> + io:format("Test ~p(~p) succeeded (should fail)", [Test, Value]), + put(errors, get(errors) + 1) + end + end, + type_tests(Test, T, Allowed); +type_tests(_, [], _) -> + ok. + +all_types() -> + [{small, 42}, + {big, 392742928742947293873938792874019287447829874290742}, + {float, 3.14156}, + {nil, []}, + {cons, [a]}, + {tuple, {a, b}}, + {atom, xxxx}, + {ref, make_ref()}, + {pid, self()}, + {port, open_port({spawn, efile}, [])}, + {function, fun(X) -> X+1, "" end}, + {binary, list_to_binary([])}]. + +type_test_desc() -> + [{integer, [small, big]}, + {float, [float]}, + {number, [small, big, float]}, + {atom, [atom]}, + {list, [cons, nil]}, + {nonempty_list, [cons]}, + {nil, [nil]}, + {tuple, [tuple]}, + {pid, [pid]}, + {port, [port]}, + {reference, [ref]}, + {function, [function]}]. + +type_test(integer, X) when integer(X) -> + integer; +type_test(float, X) when float(X) -> + float; +type_test(number, X) when number(X) -> + number; +type_test(atom, X) when atom(X) -> + atom; +type_test(list, X) when list(X) -> + list; +type_test(nonempty_list, [_]) -> + nonempty_list; +type_test(nil, []) -> + nil; +type_test(tuple, X) when tuple(X) -> + tuple; +type_test(pid, X) when pid(X) -> + pid; +type_test(reference, X) when reference(X) -> + reference; +type_test(port, X) when port(X) -> + port; +type_test(binary, X) when binary(X) -> + binary; +type_test(function, X) when function(X) -> + function. + +const_guard(Config) when is_list(Config) -> + ?line if + (0 == 0) and ((0 == 0) or (0 == 0)) -> + ok + end. + + +const_cond(Config) when is_list(Config) -> + ?line ok = const_cond({}, 0), + ?line ok = const_cond({a}, 1), + ?line error = const_cond({a,b}, 3), + ?line error = const_cond({a}, 0), + ?line error = const_cond({a,b}, 1), + ok. + +const_cond(T, Sz) -> + case T of + _X when false -> never; + _X when tuple(T), eq == eq, size(T) == Sz -> ok; + _X when tuple(T), eq == leq, size(T) =< Sz -> ok; + _X -> error + end. + +basic_not(Config) when is_list(Config) -> + True = id(true), + False = id(false), + Glurf = id(glurf), + A = id(5), + B = id(37.5), + C = id(-1), + D = id(5), + ATuple = {False,True,Glurf}, + + ?line check(fun() -> if not false -> ok; true -> error end end, ok), + ?line check(fun() -> if not true -> ok; true -> error end end, error), + ?line check(fun() -> if not False -> ok; true -> error end end, ok), + ?line check(fun() -> if not True -> ok; true -> error end end, error), + + ?line check(fun() -> if A > B -> gt; A < B -> lt; A == B -> eq end end, lt), + ?line check(fun() -> if A > C -> gt; A < C -> lt; A == C -> eq end end, gt), + ?line check(fun() -> if A > D -> gt; A < D -> lt; A == D -> eq end end, eq), + + ?line check(fun() -> if not (7 > 453) -> le; not (7 < 453) -> ge; + not (7 == 453) -> ne; true -> eq end end, le), + ?line check(fun() -> if not (7 > -8) -> le; not (7 < -8) -> ge; + not (7 == -8) -> ne; true -> eq end end, ge), + ?line check(fun() -> if not (7 > 7) -> le; not (7 < 7) -> ge; + not (7 == 7) -> ne; true -> eq end end, le), + + ?line check(fun() -> if not (A > B) -> le; not (A < B) -> ge; + not (A == B) -> ne; true -> eq end end, le), + ?line check(fun() -> if not (A > C) -> le; not (A < C) -> ge; + not (A == C) -> ne; true -> eq end end, ge), + ?line check(fun() -> if not (A > D) -> le; not (A < D) -> ge; + not (A == D) -> ne; true -> eq end end, le), + + ?line check(fun() -> if not element(1, ATuple) -> ok; true -> error end end, ok), + ?line check(fun() -> if not element(2, ATuple) -> ok; true -> error end end, error), + ?line check(fun() -> if not element(3, ATuple) -> ok; true -> error end end, error), + + ?line check(fun() -> if not glurf -> ok; true -> error end end, error), + ?line check(fun() -> if not Glurf -> ok; true -> error end end, error), + + ok. + +complex_not(Config) when is_list(Config) -> + ATuple = id({false,true,gurka}), + ?line check(fun() -> if not(element(1, ATuple)) -> ok; true -> error end end, ok), + ?line check(fun() -> if not(element(2, ATuple)) -> ok; true -> error end end, error), + + ?line check(fun() -> if not(element(3, ATuple) == gurka) -> ok; + true -> error end end, error), + ?line check(fun() -> if not(element(3, ATuple) =/= gurka) -> ok; + true -> error end end, ok), + + ?line check(fun() -> if {a,not(element(2, ATuple))} == {a,false} -> ok; + true -> error end end, ok), + ?line check(fun() -> if {a,not(element(1, ATuple))} == {a,false} -> ok; + true -> error end end, error), + + ?line check(fun() -> if not(element(1, ATuple) or element(3, ATuple)) -> ok; + true -> error end end, error), + + %% orelse + ?line check(fun() -> if not(element(1, ATuple) orelse element(3, ATuple)) -> ok; + true -> error end end, error), + + ok. + +semicolon(Config) when is_list(Config) -> + + %% True/false combined using ';' (literal atoms). + + ?line check(fun() -> if true; false -> ok end end, ok), + ?line check(fun() -> if false; true -> ok end end, ok), + ?line check(fun() -> if true; true -> ok end end, ok), + ?line check(fun() -> if false; false -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = (catch if false; false -> ok end), + exit + end, exit), + + %% True/false combined used ';'. + + True = id(true), + False = id(false), + + ?line check(fun() -> if True; False -> ok end end, ok), + ?line check(fun() -> if False; True -> ok end end, ok), + ?line check(fun() -> if True; True -> ok end end, ok), + ?line check(fun() -> if False; False -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = (catch if False; False -> ok end), + exit + end, exit), + + %% Combine true/false with a non-boolean value. + Glurf = id(glurf), + + + ?line check(fun() -> if True; Glurf -> ok end end, ok), + ?line check(fun() -> if Glurf; True -> ok end end, ok), + ?line check(fun() -> if Glurf; Glurf -> ok; true -> error end end, error), + ?line check(fun() -> if False; Glurf -> ok; true -> error end end, error), + ?line check(fun() -> if Glurf; False -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = (catch if Glurf; Glurf -> ok end), + exit + end, exit), + + %% Combine true/false with errors. + + ATuple = id({false,true,gurka}), + + ?line check(fun() -> if True; element(42, ATuple) -> ok end end, ok), + ?line check(fun() -> if element(42, ATuple); True -> ok end end, ok), + ?line check(fun() -> if element(42, ATuple); element(42, ATuple) -> ok; + true -> error end end, error), + ?line check(fun() -> if False; element(42, ATuple) -> ok; + true -> error end end, error), + ?line check(fun() -> if element(42, ATuple); + False -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = + (catch if element(42, ATuple); + element(42, ATuple) -> ok end), + exit + end, exit), + + ok. + +complex_semicolon(Config) when is_list(Config) -> + ?line ok = csemi1(int, {blurf}), + ?line ok = csemi1(string, {blurf}), + ?line ok = csemi1(float, [a]), + ?line error = csemi1(35, 42), + + %% 2 + ?line ok = csemi2({}, {a,b,c}), + ?line ok = csemi2({1,3.5}, {a,b,c}), + ?line ok = csemi2(dum, {a,b,c}), + + ?line ok = csemi2({45,-19.3}, {}), + ?line ok = csemi2({45,-19.3}, {dum}), + ?line ok = csemi2({45,-19.3}, {dum,dum}), + + ?line error = csemi2({45}, {dum}), + ?line error = csemi2([], {dum}), + ?line error = csemi2({dum}, []), + ?line error = csemi2([], []), + + %% 3 + ?line csemi3(fun csemi3a/4), + ?line csemi3(fun csemi3b/4), + ?line csemi3(fun csemi3c/4), + + %% 4 + ?line csemi4(fun csemi4a/4), + ?line csemi4(fun csemi4b/4), + ?line csemi4(fun csemi4c/4), + ?line csemi4(fun csemi4d/4), + + %% 4, 'orelse' instead of 'or' + ?line csemi4_orelse(fun csemi4_orelse_a/4), + ?line csemi4_orelse(fun csemi4_orelse_b/4), + ?line csemi4_orelse(fun csemi4_orelse_c/4), + ?line csemi4_orelse(fun csemi4_orelse_d/4), + + ok. + +csemi1(Type, Val) when is_list(Val), Type == float; + Type == int; Type == string -> ok; +csemi1(_, _) -> error. + +csemi2(A, B) when size(A) > 1; size(B) > 2 -> ok; +csemi2(_, _) -> error. + +csemi3(Csemi3) -> + ok = Csemi3({}, {a,b,c}, [0], [0]), + ok = Csemi3({1,3.5}, {a,b,c}, -1, -1), + ok = Csemi3(dum, {a,b,c}, 0.0, 0.0), + ok = Csemi3(dum, {c}, b, a), + ok = Csemi3(dum, <<1,2,3>>, 0.0, 0.0), + ok = Csemi3(<<3.5/float>>, {a,b,c}, -1, -1), + + ok = Csemi3({45,-19.3}, {}, [], []), + ok = Csemi3({45,-19.3}, {dum}, 42, 42), + ok = Csemi3({45,-19.3}, {dum,dum}, 33, 33), + + ok = Csemi3({45}, {dum}, 1.0, 0), + ok = Csemi3([a], {dum}, 1.0, 0), + ok = Csemi3({dum}, [], 1.0, 0), + ok = Csemi3([], [], 1.0, 0), + ok = Csemi3(blurf, {dum}, 1.0, 0), + ok = Csemi3({a}, blurf, 1.0, 0), + ok = Csemi3([a], [dum], 1.0, 0), + ok = Csemi3({dum}, [], 1.0, 0), + ok = Csemi3([], [], 1.0, 0), + + error = Csemi3({45}, {dum}, 0, 0), + error = Csemi3([a], {dum}, 0, 0), + error = Csemi3({dum}, [], 0, 0), + error = Csemi3([], [], 0, 0), + ok. + +csemi3a(A, B, X, Y) when X > Y; size(A) > 1; size(B) > 2 -> ok; +csemi3a(_, _, _, _) -> error. + +csemi3b(A, B, X, Y) when size(A) > 1; X > Y; size(B) > 2 -> ok; +csemi3b(_, _, _, _) -> error. + +csemi3c(A, B, X, Y) when size(A) > 1; size(B) > 2; X > Y -> ok; +csemi3c(_, _, _, _) -> error. + + +csemi4(Test) -> + ok = Test({a,b}, 2, {c,d}, 2), + ok = Test({1,2,3}, 0, [], 0), + ok = Test({}, 2, blurf, 0), + ok = Test({}, 2, {1}, 2), + + error = Test([], 4, {}, 0), + error = Test({}, 0, [a,b], 4), + error = Test({}, 0, [a,b], 0), + error = Test([], 0, {}, 0), + error = Test({}, 0, {}, 0), + + ok. + +csemi4a(A, X, B, Y) when (size(A) > 1) or (X > 1); + (size(B) > 1) or (Y > 1) -> ok; +csemi4a(_, _, _, _) -> error. + +csemi4b(A, X, B, Y) when (X > 1) or (size(A) > 1); + (size(B) > 1) or (Y > 1) -> ok; +csemi4b(_, _, _, _) -> error. + +csemi4c(A, X, B, Y) when (size(A) > 1) or (X > 1); + (Y > 1) or (size(B) > 1) -> ok; +csemi4c(_, _, _, _) -> error. + +csemi4d(A, X, B, Y) when (X > 1) or (size(A) > 1); + (Y > 1) or (size(B) > 1) -> ok; +csemi4d(_, _, _, _) -> error. + + +csemi4_orelse(Test) -> + ok = Test({a,b}, 2, {c,d}, 2), + ok = Test({1,2,3}, 0, [], 0), + ok = Test({}, 2, blurf, 0), + ok = Test({}, 2, {1}, 2), + + ?line error = Test([], 1, {}, 0), + + ok. + +csemi4_orelse_a(A, X, B, Y) when (size(A) > 1) orelse (X > 1); + (size(B) > 1) orelse (Y > 1) -> ok; +csemi4_orelse_a(_, _, _, _) -> error. + +csemi4_orelse_b(A, X, B, Y) when (X > 1) orelse (size(A) > 1); + (size(B) > 1) orelse (Y > 1) -> ok; +csemi4_orelse_b(_, _, _, _) -> error. + +csemi4_orelse_c(A, X, B, Y) when (size(A) > 1) orelse (X > 1); + (Y > 1) orelse (size(B) > 1) -> ok; +csemi4_orelse_c(_, _, _, _) -> error. + +csemi4_orelse_d(A, X, B, Y) when (X > 1) or (size(A) > 1); + (Y > 1) or (size(B) > 1) -> ok; +csemi4_orelse_d(_, _, _, _) -> error. + + +comma(Config) when is_list(Config) -> + + %% ',' combinations of literal true/false. + + ?line check(fun() -> if true, false -> ok; true -> error end end, error), + ?line check(fun() -> if false, true -> ok; true -> error end end, error), + ?line check(fun() -> if true, true -> ok end end, ok), + ?line check(fun() -> if false, false -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = + (catch if true, false -> ok; + false, true -> ok; + false, false -> ok + end), + exit + end, exit), + + %% ',' combinations of true/false in variables. + + True = id(true), + False = id(false), + + ?line check(fun() -> if True, False -> ok; true -> error end end, error), + ?line check(fun() -> if False, True -> ok; true -> error end end, error), + ?line check(fun() -> if True, True -> ok end end, ok), + ?line check(fun() -> if False, False -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = + (catch if True, False -> ok; + False, True -> ok; + False, False -> ok + end), + exit + end, exit), + + %% ',' combinations of true/false, and non-boolean in variables. + + Glurf = id(glurf), + + ?line check(fun() -> if True, Glurf -> ok; true -> error end end, error), + ?line check(fun() -> if Glurf, True -> ok; true -> error end end, error), + ?line check(fun() -> if True, True -> ok end end, ok), + ?line check(fun() -> if Glurf, Glurf -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = + (catch if True, Glurf -> ok; + Glurf, True -> ok; + Glurf, Glurf -> ok + end), + exit + end, exit), + + %% ',' combinations of true/false with errors. + ATuple = id({a,b,c}), + + ?line check(fun() -> if True, element(42, ATuple) -> ok; + true -> error end end, error), + ?line check(fun() -> if element(42, ATuple), True -> ok; + true -> error end end, error), + ?line check(fun() -> if True, True -> ok end end, ok), + ?line check(fun() -> if element(42, ATuple), element(42, ATuple) -> ok; + true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = + (catch if True, element(42, ATuple) -> ok; + element(42, ATuple), True -> ok; + element(42, ATuple), element(42, ATuple) -> ok + end), + exit + end, exit), + + ok. + +or_guard(Config) when is_list(Config) -> + True = id(true), + False = id(false), + Glurf = id(glurf), + + %% 'or' combinations of literal true/false. + ?line check(fun() -> if true or false -> ok end end, ok), + ?line check(fun() -> if false or true -> ok end end, ok), + ?line check(fun() -> if true or true -> ok end end, ok), + ?line check(fun() -> if false or false -> ok; true -> error end end, error), + + ?line check(fun() -> if glurf or true -> ok; true -> error end end, error), + ?line check(fun() -> if true or glurf -> ok; true -> error end end, error), + ?line check(fun() -> if glurf or glurf -> ok; true -> error end end, error), + + ?line check(fun() -> + {'EXIT',{if_clause,_}} = (catch if false or false -> ok end), + exit + end, exit), + + + %% 'or' combinations using variables containing true/false. + ?line check(fun() -> if True or False -> ok end end, ok), + ?line check(fun() -> if False or True -> ok end end, ok), + ?line check(fun() -> if True or True -> ok end end, ok), + ?line check(fun() -> if False or False -> ok; true -> error end end, error), + + ?line check(fun() -> if True or Glurf -> ok; true -> error end end, error), + ?line check(fun() -> if Glurf or True -> ok; true -> error end end, error), + ?line check(fun() -> if Glurf or Glurf -> ok; true -> error end end, error), + + ?line check(fun() -> + {'EXIT',{if_clause,_}} = (catch if False or False -> ok end), + exit + end, exit), + + ok. + +more_or_guards(Config) when is_list(Config) -> + True = id(true), + False = id(false), + ATuple = id({false,true,gurka}), + + ?line check(fun() -> + if element(42, ATuple) or False -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if False or element(42, ATuple) -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if element(18, ATuple) or element(42, ATuple) -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if True or element(42, ATuple) -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if element(42, ATuple) or True -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if element(1, ATuple) or element(42, ATuple) or True -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if element(1, ATuple) or True or element(42, ATuple) -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if + (<<False:8>> == <<0>>) or element(2, ATuple) -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if + element(2, ATuple) or (<<True:8>> == <<1>>) -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if element(2, ATuple) or element(42, ATuple) -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if + element(1, ATuple) or + element(2, ATuple) or + element(19, ATuple) -> ok; + true -> error end + end, error), + ok. + +complex_or_guards(Config) when is_list(Config) -> + %% complex_or_1/2 + ?line ok = complex_or_1({a,b,c,d}, {1,2,3}), + ?line ok = complex_or_1({a,b,c,d}, {1}), + ?line ok = complex_or_1({a}, {1,2,3}), + ?line error = complex_or_1({a}, {1}), + + ?line error = complex_or_1(1, 2), + ?line error = complex_or_1([], {a,b,c,d}), + ?line error = complex_or_1({a,b,c,d}, []), + + + %% complex_or_2/1 + ?line ok = complex_or_2({true,{}}), + ?line ok = complex_or_2({false,{a}}), + ?line ok = complex_or_2({false,{a,b,c}}), + ?line ok = complex_or_2({true,{a,b,c,d}}), + + ?line error = complex_or_2({blurf,{a,b,c}}), + + ?line error = complex_or_2({true}), + ?line error = complex_or_2({true,no_tuple}), + ?line error = complex_or_2({true,[]}), + + %% complex_or_3/2 + ?line ok = complex_or_3({true}, {}), + ?line ok = complex_or_3({false}, {a}), + ?line ok = complex_or_3({false}, {a,b,c}), + ?line ok = complex_or_3({true}, {a,b,c,d}), + ?line ok = complex_or_3({false}, <<1,2,3>>), + ?line ok = complex_or_3({true}, <<1,2,3,4>>), + + ?line error = complex_or_3(blurf, {a,b,c}), + + ?line error = complex_or_3({false}, <<1,2,3,4>>), + ?line error = complex_or_3([], <<1,2>>), + ?line error = complex_or_3({true}, 45), + ?line error = complex_or_3(<<>>, <<>>), + + %% complex_or_4/2 + ?line ok = complex_or_4(<<1,2,3>>, {true}), + ?line ok = complex_or_4(<<1,2,3>>, {false}), + ?line ok = complex_or_4(<<1,2,3>>, {true}), + ?line ok = complex_or_4({1,2,3}, {true}), + ?line error = complex_or_4({1,2,3,4}, {false}), + + ?line error = complex_or_4(<<1,2,3,4>>, []), + ?line error = complex_or_4([], {true}), + + %% complex_or_5/2 + ?line ok = complex_or_5(<<1>>, {false}), + ?line ok = complex_or_5(<<1,2,3>>, {true}), + ?line ok = complex_or_5(<<1,2,3,4>>, {false}), + ?line ok = complex_or_5({1,2,3}, {false}), + ?line ok = complex_or_5({1,2,3,4}, {false}), + + ?line error = complex_or_5(blurf, {false}), + ?line error = complex_or_5(<<1>>, klarf), + ?line error = complex_or_5(blurf, klarf), + + %% complex_or_6/2 + ?line ok = complex_or_6({true,true}, {1,2,3,4}), + ?line ok = complex_or_6({true,true}, <<1,2,3,4>>), + ?line ok = complex_or_6({false,false}, <<1,2,3,4>>), + ?line ok = complex_or_6({false,true}, <<1>>), + ?line ok = complex_or_6({true,false}, {1}), + ?line ok = complex_or_6({true,true}, {1}), + + ?line error = complex_or_6({false,false}, {1}), + + ?line error = complex_or_6({true}, {1,2,3,4}), + ?line error = complex_or_6({}, {1,2,3,4}), + ?line error = complex_or_6([], {1,2,3,4}), + ?line error = complex_or_6([], {1,2,3,4}), + ?line error = complex_or_6({true,false}, klurf), + + ok. + +complex_or_1(A, B) -> + if + ((3 < size(A)) and (size(A) < 9)) or + ((2 < size(B)) and (size(B) < 7)) -> ok; + true -> error + end. + +complex_or_2(Tuple) -> + if + element(1, Tuple) or not (size(element(2, Tuple)) > 3) -> ok; + true -> error + end. + +complex_or_3(A, B) -> + if + not (size(B) > 3) or element(1, A) -> ok; + true -> error + end. + +complex_or_4(A, B) -> + if + not (is_tuple(A) and (size(A) > 3)) or element(1, B) -> ok; + true -> error + end. + +complex_or_5(A, B) -> + if + not (is_tuple(A) or (size(A) > 3)) or not element(1, B) -> ok; + true -> error + end. + +complex_or_6(A, B) -> + if + not (not element(1, A) and not element(2, A)) or + not (not (size(B) > 3)) -> ok; + true -> error + end. + +and_guard(Config) when is_list(Config) -> + + %% 'and' combinations of literal true/false. + + ?line check(fun() -> if true and false -> ok; true -> error end end, error), + ?line check(fun() -> if false and true -> ok; true -> error end end, error), + ?line check(fun() -> if true and true -> ok end end, ok), + ?line check(fun() -> if false and false -> ok; true -> error end end, error), + + ?line check(fun() -> if glurf and true -> ok; true -> error end end, error), + ?line check(fun() -> if true and glurf -> ok; true -> error end end, error), + ?line check(fun() -> if glurf and glurf -> ok; true -> error end end, error), + + ?line check(fun() -> + {'EXIT',{if_clause,_}} = + (catch if true and false -> ok; + false and true -> ok; + false and false -> ok + end), + exit + end, exit), + + %% 'and' combinations of true/false in variables. + + True = id(true), + False = id(false), + + ?line check(fun() -> if True and False -> ok; true -> error end end, error), + ?line check(fun() -> if False and True -> ok; true -> error end end, error), + ?line check(fun() -> if True and True -> ok end end, ok), + ?line check(fun() -> if False and False -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = + (catch if True and False -> ok; + False and True -> ok; + False and False -> ok + end), + exit + end, exit), + + %% 'and' combinations of true/false and a non-boolean in variables. + + Glurf = id(glurf), + + ?line check(fun() -> if True and Glurf -> ok; true -> error end end, error), + ?line check(fun() -> if Glurf and True -> ok; true -> error end end, error), + ?line check(fun() -> if True and True -> ok end end, ok), + ?line check(fun() -> if Glurf and Glurf -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = + (catch if True and Glurf -> ok; + Glurf and True -> ok; + Glurf and Glurf -> ok + end), + exit + end, exit), + + %% 'and' combinations of true/false with errors. + ATuple = id({a,b,c}), + + ?line check(fun() -> if True and element(42, ATuple) -> ok; + true -> error end end, error), + ?line check(fun() -> if element(42, ATuple) and True -> ok; + true -> error end end, error), + ?line check(fun() -> if True and True -> ok end end, ok), + ?line check(fun() -> if element(42, ATuple) and element(42, ATuple) -> ok; + true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = + (catch if True and element(42, ATuple) -> ok; + element(42, ATuple) and True -> ok; + element(42, ATuple) and element(42, ATuple) -> ok + end), + exit + end, exit), + + ?line ok = relprod({'Set',a,b}, {'Set',a,b}), + + ok. + +relprod(R1, R2) when (erlang:size(R1) =:= 3) and (erlang:element(1,R1) =:= 'Set'), (erlang:size(R2) =:= 3) and (erlang:element(1,R2) =:= 'Set') -> + ok. + + +xor_guard(Config) when is_list(Config) -> + + %% 'xor' combinations of literal true/false. + ?line check(fun() -> if true xor false -> ok end end, ok), + ?line check(fun() -> if false xor true -> ok end end, ok), + ?line check(fun() -> if true xor true -> ok; true -> error end end, error), + ?line check(fun() -> if false xor false -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = (catch if false xor false -> ok end), + exit + end, exit), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = (catch if true xor true -> ok end), + exit + end, exit), + + + %% 'xor' combinations using variables containing true/false. + + True = id(true), + False = id(false), + + ?line check(fun() -> if True xor False -> ok end end, ok), + ?line check(fun() -> if False xor True -> ok end end, ok), + ?line check(fun() -> if True xor True -> ok; true -> error end end, error), + ?line check(fun() -> if False xor False -> ok; true -> error end end, error), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = (catch if False xor False -> ok end), + exit + end, exit), + ?line check(fun() -> + {'EXIT',{if_clause,_}} = (catch if True xor True -> ok end), + exit + end, exit), + + ok. + +more_xor_guards(Config) when is_list(Config) -> + True = id(true), + False = id(false), + ATuple = id({false,true,gurka}), + + ?line check(fun() -> + if element(42, ATuple) xor False -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if False xor element(42, ATuple) xor False -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if element(18, ATuple) xor element(42, ATuple) -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if True xor element(42, ATuple) -> ok; + true -> error end + end, error), + + ?line check(fun() -> + if element(42, ATuple) xor True -> ok; + true -> error end + end, error), + ok. + +build_in_guard(Config) when is_list(Config) -> + SubBin = <<5.0/float>>, + ?line B = <<1,SubBin/binary,3.5/float>>, + ?line if + B =:= <<1,SubBin/binary,3.5/float>> -> ok + end. + +old_guard_tests(Config) when list(Config) -> + %% Check that all the old guard tests are still recognized. + ?line list = og(Config), + ?line atom = og(an_atom), + ?line binary = og(<<1,2>>), + ?line float = og(3.14), + ?line integer = og(43), + ?line a_function = og(fun() -> ok end), + ?line pid = og(self()), + ?line reference = og(make_ref()), + ?line tuple = og({}), + + ?line number = on(45.333), + ?line number = on(-19), + ok. + +og(V) when atom(V) -> atom; +og(V) when binary(V) -> binary; +og(V) when float(V) -> float; +og(V) when integer(V) -> integer; +og(V) when function(V) -> a_function; +og(V) when list(V) -> list; +og(V) when pid(V) -> pid; +og(V) when port(V) -> port; +og(V) when reference(V) -> reference; +og(V) when tuple(V) -> tuple; +og(_) -> what. + +on(V) when number(V) -> number; +on(_) -> not_number. + +gbif(Config) when is_list(Config) -> + ?line error = gbif_1(1, {false,true}), + ?line ok = gbif_1(2, {false,true}), + ok. + +gbif_1(P, T) when element(P, T) -> ok; +gbif_1(_, _) -> error. + + +t_is_boolean(Config) when is_list(Config) -> + ?line true = is_boolean(true), + ?line true = is_boolean(false), + ?line true = is_boolean(id(true)), + ?line true = is_boolean(id(false)), + + ?line false = is_boolean(glurf), + ?line false = is_boolean(id(glurf)), + + ?line false = is_boolean([]), + ?line false = is_boolean(id([])), + ?line false = is_boolean(42), + ?line false = is_boolean(id(-42)), + + ?line false = is_boolean(math:pi()), + ?line false = is_boolean(384793478934378924978439789873478934897), + + ?line false = is_boolean(id(self())), + ?line false = is_boolean(id({x,y,z})), + ?line false = is_boolean(id([a,b,c])), + ?line false = is_boolean(id(make_ref())), + ?line false = is_boolean(id(<<1,2,3>>)), + + ?line ok = bool(true), + ?line ok = bool(false), + ?line ok = bool(id(true)), + ?line ok = bool(id(false)), + + ?line error = bool(glurf), + ?line error = bool(id(glurf)), + + ?line error = bool([]), + ?line error = bool(id([])), + ?line error = bool(42), + ?line error = bool(id(-42)), + + ?line error = bool(math:pi()), + ?line error = bool(384793478934378924978439789873478934897), + + ?line error = bool(id(self())), + ?line error = bool(id({x,y,z})), + ?line error = bool(id([a,b,c])), + ?line error = bool(id(make_ref())), + ?line error = bool(id(<<1,2,3>>)), + + ok. + +bool(X) when is_boolean(X) -> ok; +bool(_) -> error. + + +is_function_2(Config) when is_list(Config) -> + true = is_function(id(fun ?MODULE:all/1), 1), + true = is_function(id(fun() -> ok end), 0), + false = is_function(id(fun ?MODULE:all/1), 0), + false = is_function(id(fun() -> ok end), 1), + + F = fun(_) -> ok end, + if + is_function(F, 1) -> ok + end. + +tricky(Config) when is_list(Config) -> + ?line not_ok = tricky_1(1, 2), + ?line not_ok = tricky_1(1, blurf), + ?line not_ok = tricky_1(foo, 2), + ?line not_ok = tricky_1(a, b), + + ?line false = rb(100000, [1], 42), + ?line true = rb(100000, [], 42), + ?line true = rb(555, [a,b,c], 19), + ok. + +tricky_1(X, Y) when abs((X == 1) or (Y == 2)) -> ok; +tricky_1(_, _) -> not_ok. + +%% From dets_v9:read_buckets/11, simplified. + +rb(Size, ToRead, SoFar) when SoFar + Size < 81920; ToRead == [] -> true; +rb(_, _, _) -> false. + + +-define(T(Op,A,B), + ok = if A Op B -> ok; true -> error end, + ok = if not (A Op B) -> error; true -> ok end, + (fun(X, Y, True, False) -> + ok = if X Op Y -> ok; true -> error end, + ok = if False; X Op Y; False -> ok; true -> error end, + ok = if X Op Y, True -> ok; true -> error end, + ok = if not (X Op Y) -> error; true -> ok end, + ok = if False; not (X Op Y); False -> error; true -> ok end + end)(id(A), id(B), id(true), id(false))). + +-define(F(Op,A,B), + ok = if A Op B -> error; true -> ok end, + ok = if not (A Op B) -> ok; true -> error end, + (fun(X, Y, True, False) -> + ok = if X Op Y -> error; true -> ok end, + ok = if False; X Op Y; False -> error; true -> ok end, + ok = if not (X Op Y); False -> ok; true -> error end, + ok = if not (X Op Y), True -> ok; true -> error end + end)(id(A), id(B), id(true), id(false))). + + +rel_ops(Config) when is_list(Config) -> + ?line ?T(=/=, 1, 1.0), + ?line ?F(=/=, 2, 2), + ?line ?F(=/=, {a}, {a}), + + ?line ?F(/=, a, a), + ?line ?F(/=, 0, 0.0), + ?line ?T(/=, 0, 1), + ?line ?F(/=, {a}, {a}), + + ?line ?T(==, 1, 1.0), + ?line ?F(==, a, {}), + + ?line ?F(=:=, 1, 1.0), + ?line ?T(=:=, 42.0, 42.0), + + ?line ?F(>, a, b), + ?line ?T(>, 42, 1.0), + ?line ?F(>, 42, 42.0), + + ?line ?T(<, a, b), + ?line ?F(<, 42, 1.0), + ?line ?F(<, 42, 42.0), + + ?line ?T(=<, 1.5, 5), + ?line ?F(=<, -9, -100.344), + ?line ?T(=<, 42, 42.0), + + ?line ?T(>=, 42, 42.0), + ?line ?F(>=, a, b), + ?line ?T(>=, 1.0, 0), + + ok. + +-undef(TestOp). + +basic_andalso_orelse(Config) when is_list(Config) -> + ?line T = id({type,integers,23,42}), + ?line 65 = if + ((element(1, T) =:= type) andalso (size(T) =:= 4) andalso + element(2, T) == integers) -> + element(3, T) + element(4, T); + true -> error + end, + ?line 65 = case [] of + [] when ((element(1, T) =:= type) andalso (size(T) =:= 4) andalso + element(2, T) == integers) -> + element(3, T) + element(4, T) + end, + + ?line 42 = basic_rt({type,integers,40,2}), + ?line 5.0 = basic_rt({vector,{3.0,4.0}}), + ?line 20 = basic_rt(['+',3,7]), + ?line {'Set',a,b} = basic_rt({{'Set',a,b},{'Set',a,b}}), + ?line 12 = basic_rt({klurf,4}), + + ?line error = basic_rt({type,integers,40,2,3}), + ?line error = basic_rt({kalle,integers,40,2}), + ?line error = basic_rt({kalle,integers,40,2}), + ?line error = basic_rt({1,2}), + ?line error = basic_rt([]), + + RelProdBody = + fun(R1, R2) -> + if + (erlang:size(R1) =:= 3) andalso (erlang:element(1,R1) =:= 'Set'), + (erlang:size(R2) =:= 3) andalso (erlang:element(1,R2) =:= 'Set') -> + ok + end + end, + + ?line ok = RelProdBody({'Set',a,b}, {'Set',a,b}), + ok. + +basic_rt(T) when is_tuple(T) andalso size(T) =:= 4 andalso element(1, T) =:= type andalso + element(2, T) == integers -> + element(3, T) + element(4, T); +basic_rt(T) when is_tuple(T) andalso size(T) =:= 2 andalso element(1, T) =:= vector -> + {X,Y} = element(2, T), + if + is_float(X), is_float(Y) -> + math:sqrt(X*X+Y*Y) + end; +basic_rt(['+',A,B]) -> + 2*id(A+B); +basic_rt({R1,R2}) when erlang:size(R1) =:= 3 andalso erlang:element(1,R1) =:= 'Set', + erlang:size(R2) =:= 3 andalso erlang:element(1,R2) =:= 'Set' -> + R1 = id(R1), + R2 = id(R2), + R1; +basic_rt(T) when is_tuple(T) andalso size(T) =:= 2 andalso element(1, T) =:= klurf -> + 3*id(element(2, T)); +basic_rt(_) -> + error. + +traverse_dcd(Config) when is_list(Config) -> + L0 = [{log_header,dcd_log,"1.0",a,b,c},{log_header,dcd_log,"2.0",a,b,c}, + {log_header,dcd_log,"0.0",a,b,c},blurf], + {cont,[{log_header,dcd_log,"0.0",a,b,c},blurf],log,funny} = + traverse_dcd({cont,L0}, log, funny), + L1 = [{log_header,dcd_log,"1.0"}], + {cont,L1,log,funny} = traverse_dcd({cont,L1}, log, funny), + L2 = [{a,tuple}], + {cont,L2,log,funny} = traverse_dcd({cont,L2}, log, funny), + ok. + +%% The function starts out with 3 arguments in {x,0}, {x,1}, {x,2}. +%% The outer match of a two tuple will places the first element in {x,3} and +%% second in {x,4}. The guard for the first clause must make ensure that all of those +%% registers are restored befor entering the second clause. +%% +%% (From mnesia_checkpoint.erl, modified.) + +traverse_dcd({Cont,[LogH|Rest]},Log,Fun) + when is_tuple(LogH) andalso size(LogH) =:= 6 andalso element(1, LogH) =:= log_header +andalso erlang:element(2,LogH) == dcd_log, +is_tuple(LogH) andalso size(LogH) =:= 6 andalso element(1, LogH) =:= log_header +andalso erlang:element(3,LogH) >= "1.0" -> + traverse_dcd({Cont,Rest},Log,Fun); +traverse_dcd({Cont,Recs},Log,Fun) -> + {Cont,Recs,Log,Fun}. + + +check_qlc_hrl(Config) when is_list(Config) -> + St = {r1,false,dum}, + ?line foo = cqlc(qlc, q, [{lc,1,2,3}], St), + ?line foo = cqlc(qlc, q, [{lc,1,2,3},b], St), + ?line St = cqlc(qlc, q, [], St), + ?line St = cqlc(qlc, blurf, [{lc,1,2,3},b], St), + ?line St = cqlc(q, q, [{lc,1,2,3},b], St), + ?line St = cqlc(qlc, q, [{lc,1,2,3},b,c], St), + ?line St = cqlc(qlc, q, [a,b], St), + ?line {r1,true,kalle} = cqlc(qlc, q, [{lc,1,2,3},b], {r1,true,kalle}), + ok. + +%% From erl_lint.erl; original name was check_qlc_hrl/4. +cqlc(M, F, As, St) -> + Arity = length(As), + case As of + [{lc,_L,_E,_Qs}|_] when M =:= qlc, F =:= q, + Arity < 3, + not (((element(1, St) =:= r1) orelse fail) and (size(St) =:= 3) and element(2, St)) -> + foo; + _ -> + St + end. + + + +%% Call this function to turn off constant propagation. +id(I) -> I. + +check(F, Result) -> + case F() of + Result -> ok; + Other -> + io:format("Expected: ~p\n", [Result]), + io:format(" Got: ~p\n", [Other]), + test_server:fail() + end. diff --git a/lib/debugger/test/int_SUITE.erl b/lib/debugger/test/int_SUITE.erl new file mode 100644 index 0000000000..0326325888 --- /dev/null +++ b/lib/debugger/test/int_SUITE.erl @@ -0,0 +1,277 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(int_SUITE). +-include("test_server.hrl"). + +%% Test server specific exports +-export([all/1]). +-export([init_per_testcase/2, end_per_testcase/2]). + +%% Test cases +-export([interpret/1, guards/1, list_suite/1, interpretable/1]). +-export([append/1, append_1/1, append_2/1, member/1, reverse/1]). + +%% Default timetrap timeout (set in init_per_testcase) +-define(default_timeout, ?t:minutes(1)). + +init_per_testcase(interpretable, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]; +init_per_testcase(_Case, Config) -> + + %% Interpret some existing and non-existing modules + ?line DataDir = ?config(data_dir, Config), + ?line {module, lists1} = int:i(filename:join([DataDir,lists1])), + ?line {module, guards} = int:i(filename:join([DataDir,guards])), + + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + +end_per_testcase(interpretable, Config) -> + ?line Dog=?config(watchdog, Config), + ?line test_server:timetrap_cancel(Dog), + ok; +end_per_testcase(_Case, Config) -> + + %% Quit interpreting + ?line ok = int:n(lists1), + ?line ok = int:n(guards), + + ?line Dog=?config(watchdog, Config), + ?line test_server:timetrap_cancel(Dog), + ?line ok. + +all(suite)-> + [interpret, guards, list_suite, interpretable]. + +interpret(suite) -> + []; +interpret(doc) -> + ["Interpreting modules"]; +interpret(Config) when is_list(Config) -> + ?line int:n(int:interpreted()), + + %% Interpret some existing and non-existing modules + ?line DataDir = ?config(data_dir, Config), + ?line {module, lists1} = int:i(filename:join([DataDir,lists1])), + ?line {module, ordsets1} = int:i(filename:join([DataDir,ordsets1])), + ?line error = int:i(non_existent_module), + + %% Check that the interpreter has the right view. + ?line ExpectedResult = lists:sort([lists1, ordsets1]), + ?line Result = int:interpreted(), + ?line ExpectedResult = lists:sort(Result), + + %% Uniterpret the modules. + ?line ok = int:n(non_existent_module), + ?line ok = int:n(lists1), + ?line [ordsets1] = int:interpreted(), + ?line ok = int:n("ordsets1"), + ?line [] = int:interpreted(), + + ok. + +guards(suite) -> + []; +guards(doc) -> + "Evaluate guards."; +guards(Config) when is_list(Config) -> + ok = guards:guards(). + + +list_suite(suite) -> + [append, reverse, member]. + +append(doc) -> + ["Tests lists1:append/1 & lists1:append/2"]; +append(suite) -> + [append_1, append_2]. + +append_1(suite) -> + []; +append_1(doc) -> + []; +append_1(Config) when is_list(Config) -> + ?line test_server:format("In append_1~n"), + ?line test_server:format("code:which(lists1)=~p~n", + [code:which(lists1)]), + ?line test_server:format("lists1:append([a],[b])=~p~n", + [spawn_eval(lists1,append,[[a],[b]])]), + + ?line "abcdef"=spawn_eval(lists1,append,[["abc","def"]]), + ?line [hej, du,[glade, [bagare]]]= + spawn_eval(lists1,append,[[[hej], [du], [[glade, [bagare]]]]]), + ?line [10, [elem]]=spawn_eval(lists1,append,[[[10], [[elem]]]]), + ok. + +append_2(suite) -> + []; +append_2(doc) -> + []; +append_2(Config) when is_list(Config) -> + ?line test_server:format("In append_2~n"), + ?line test_server:format("code:which(lists1)=~p~n", + [code:which(lists1)]), + + ?line "abcdef"=spawn_eval(lists1,append,["abc", "def"]), + ?line [hej, du]=spawn_eval(lists1,append,[[hej], [du]]), + ?line [10, [elem]]=spawn_eval(lists1,append,[[10], [[elem]]]), + ok. + +reverse(suite) -> + []; +reverse(doc) -> + []; +reverse(Config) when is_list(Config) -> + ?line ok=reverse_test(0), + ?line ok=reverse_test(1), + ?line ok=reverse_test(2), + ?line ok=reverse_test(537), + ok. + +reverse_test(0) -> + case spawn_eval(lists1,reverse,[[]]) of + [] -> + ok; + _Other -> + error + end; +reverse_test(Num) -> + List=spawn_eval(lists1,reverse, + [['The Element'|lists1:duplicate(Num, 'Ele')]]), + case spawn_eval(lists1,reverse,[List]) of + ['The Element'|_Rest] -> + ok; + _Other -> + error + end. + +member(suite) -> + []; +member(doc) -> + ["Tests the lists1:member() implementation. The function " + "is `non-blocking', and only processes 2000 elements " + "at a time.", + "This test case depends on lists1:reverse() to work, " + "wich is tested in a separate test case."]; +member(Config) when list(Config) -> + ?line ok=member_test(0), + ?line ok=member_test(1), + ?line ok=member_test(100), + ?line ok=member_test(537), + ok. + +member_test(0) -> + case spawn_eval(lists1,member,['The Element', []]) of + false -> + ok; + true -> + {error, 'Found (!?)'} + end; +member_test(Num) -> + List=spawn_eval(lists1,reverse, + [['The Element'|spawn_eval(lists1,duplicate, + [Num, 'Elem'])]]), + case spawn_eval(lists1,member,['The Element', List]) of + true -> + ok; + false -> + {error, not_found} + end. + +spawn_eval(M,F,A) -> + Self = self(), + spawn(fun() -> evaluator(Self, M,F,A) end), + receive + Result -> + Result + end. + +evaluator(Pid, M,F,A) -> + Pid ! (catch apply(M,F,A)). + +interpretable(suite) -> + []; +interpretable(doc) -> + ["Test int:interpretable/1"]; +interpretable(Config) when is_list(Config) -> + + %% First make sure that 'lists1' is not loaded + case code:is_loaded(lists1) of + {file, _Loaded} -> + ?line code:purge(lists1), + ?line code:delete(lists1), + ?line code:purge(lists1); + false -> ignore + end, + + %% true + ?line DataDir = filename:dirname(?config(data_dir, Config)), + ?line true = code:add_patha(DataDir), + ?line true = int:interpretable(lists1), + ?line true = int:interpretable(filename:join([DataDir,lists1])), + ?line true = code:del_path(DataDir), + + %% {error, no_src} + ?line PrivDir = filename:join(?config(priv_dir, Config), ""), + ?line {ok, _} = file:copy(filename:join([DataDir,"lists1.beam"]), + filename:join([PrivDir,"lists1.beam"])), + ?line true = code:add_patha(PrivDir), + + ?line {error, no_src} = int:interpretable(lists1), + ?line ok = file:delete(filename:join([PrivDir,"lists1.beam"])), + + %% {error, no_beam} + Src = filename:join([PrivDir,"lists1.erl"]), + ?line {ok, _} = file:copy(filename:join([DataDir,"lists1.erl"]), + Src), + ?line {error, no_beam} = int:interpretable(Src), + + %% {error, no_debug_info} + ?line {ok, _} = compile:file(Src, [{outdir,PrivDir}]), + ?line {error, no_debug_info} = int:interpretable(Src), + ?line {error, no_debug_info} = int:interpretable(lists1), + ?line ok = file:delete(Src), + ?line true = code:del_path(PrivDir), + + %% {error, badarg} + ?line {error, badarg} = int:interpretable(pride), + ?line {error, badarg} = int:interpretable("prejudice.erl"), + + %% {error, {app,App}} + ?line {error, {app,_}} = int:interpretable(file), + ?line {error, {app,_}} = int:interpretable(lists), + ?line {error, {app,_}} = int:interpretable(gs), + ?line case int:interpretable(dbg_ieval) of + {error, {app,_}} -> + ok; + {error, badarg} -> + case code:which(dbg_ieval) of + cover_compiled -> + ok; + Other1 -> + ?line ?t:fail({unexpected_result, Other1}) + end; + Other2 -> + ?line ?t:fail({unexpected_result, Other2}) + end, + + ok. diff --git a/lib/debugger/test/int_SUITE_data/Makefile.src b/lib/debugger/test/int_SUITE_data/Makefile.src new file mode 100644 index 0000000000..95b96b5d00 --- /dev/null +++ b/lib/debugger/test/int_SUITE_data/Makefile.src @@ -0,0 +1,39 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2000-2010. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +EFLAGS=+debug_info +all: guards.@EMULATOR@ lists1.@EMULATOR@ my_lists.@EMULATOR@ \ + ordsets1.@EMULATOR@ test.@EMULATOR@ test1.@EMULATOR@ + +guards.@EMULATOR@: guards.erl + erlc $(EFLAGS) guards.erl + +lists1.@EMULATOR@: lists1.erl + erlc $(EFLAGS) lists1.erl + +my_lists.@EMULATOR@: my_lists.erl + erlc $(EFLAGS) my_lists.erl + +ordsets1.@EMULATOR@: ordsets1.erl + erlc $(EFLAGS) ordsets1.erl + +test.@EMULATOR@: test.erl + erlc $(EFLAGS) test.erl + +test1.@EMULATOR@: test1.erl + erlc $(EFLAGS) test1.erl diff --git a/lib/debugger/test/int_SUITE_data/guards.erl b/lib/debugger/test/int_SUITE_data/guards.erl new file mode 100644 index 0000000000..c847bb6a8c --- /dev/null +++ b/lib/debugger/test/int_SUITE_data/guards.erl @@ -0,0 +1,108 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(guards). + +-export([guards/0]). + +guards() -> + ok = t(), + ok = f(), + ok = ct(1), + ok = multi(1), + ok = multi(2), + ok = multi(3). + +%% The following tests are always true. +t() when integer(42) -> + ok; +t() when float(2.0) -> + ok; +t() when number(7) -> + ok; +t() when number(3.14) -> + ok; +t() when atom(error) -> + ok; +t() when list([a]) -> + ok; +t() when tuple({}) -> + ok; +t() when tuple({1, 2}) -> + ok. + +%% The following tests are always false. +f() when integer(a) -> + ok; +f() when float(b) -> + ok; +f() when number(c) -> + ok; +f() when atom(42) -> + ok; +f() when list(33) -> + ok; +f() when list({}) -> + ok; +f() when list({1, 2}) -> + ok; +f() when tuple(33) -> + ok; +f() when tuple([a]) -> + ok; +f() when tuple([]) -> + ok; +f() when tuple(35) -> + ok; +f() -> + ok. + +%% The following tests are always true. +ct(X) -> + case X of + Y when integer(42) -> + ok; + Y when float(2.0) -> + ok; + Y when number(7) -> + ok; + Y when number(3.14) -> + ok; + Y when atom(error) -> + ok; + Y when list([a]) -> + ok; + Y when tuple({}) -> + ok; + Y when tuple({1, 2}) -> + ok + end. + +multi(X) -> + case X of + Y when float(Y) ; integer(Y) -> + ok; + Y when Y > 1, Y < 10 ; atom(Y) -> + ok; + Y when Y == 4, number(Y) ; list(Y) -> + pannkaka; + Y when Y==3 ; Y==5 ; Y==6 -> + ok + end. diff --git a/lib/debugger/test/int_SUITE_data/lists1.erl b/lib/debugger/test/int_SUITE_data/lists1.erl new file mode 100644 index 0000000000..0214983c11 --- /dev/null +++ b/lib/debugger/test/int_SUITE_data/lists1.erl @@ -0,0 +1,469 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%% Purpose : Basic lists processing functions. + +-module(lists1). + + +-export([member/2, append/2, append/1, subtract/2, reverse/1, reverse/2, + nth/2, nthtail/2, prefix/2, suffix/2, last/1, + seq/2, seq/3, sum/1, duplicate/2, min/1, max/1, sublist/2, sublist/3, + delete/2, sort/1, merge/2, concat/1, + flatten/1, flatten/2, flat_length/1, flatlength/1, + keymember/3, keysearch/3, keydelete/3, keyreplace/4, + keysort/2, keymerge/3, keymap/3, keymap/4]). + +-export([all/2,any/2,map/2,flatmap/2,foldl/3,foldr/3,filter/2,zf/2, + mapfoldl/3,mapfoldr/3,foreach/2,takewhile/2,dropwhile/2,splitwith/2]). +-export([all/3,any/3,map/3,flatmap/3,foldl/4,foldr/4,filter/3,zf/3, + mapfoldl/4,mapfoldr/4,foreach/3]). + +%% member(X, L) -> (true | false) +%% test if X is a member of the list L + +member(X, [X|_]) -> true; +member(X, [_|Y]) -> + member(X, Y); +member(X, []) -> false. + +%% append(X, Y) appends lists X and Y + +append(L1, L2) -> L1 ++ L2. + +%% append(L) appends the list of lists L + +append([E]) -> E; +append([H|T]) -> H ++ append(T); +append([]) -> []. + +%% subtract(List1, List2) subtract elements in List2 form List1. + +subtract(L1, L2) -> L1 -- L2. + +%% reverse(L) reverse all elements in the list L + +reverse(X) -> reverse(X, []). + +reverse([H|T], Y) -> + reverse(T, [H|Y]); +reverse([], X) -> X. + +%% nth(N, L) returns the N`th element of the list L +%% nthtail(N, L) returns the N`th tail of the list L + +nth(1, [H|T]) -> H; +nth(N, [_|T]) when N > 1 -> + nth(N - 1, T). + +nthtail(1, [H|T]) -> T; +nthtail(N, [H|T]) when N > 1 -> + nthtail(N - 1, T); +nthtail(0, L) when list(L) -> L. + +%% prefix(Prefix, List) -> (true | false) + +prefix([X|PreTail], [X|Tail]) -> + prefix(PreTail, Tail); +prefix([], List) -> true; +prefix(_,_) -> false. + + +%% suffix(Suffix, List) -> (true | false) + +suffix(Suffix, Suffix) -> true; +suffix(Suffix, [_|Tail]) -> + suffix(Suffix, Tail); +suffix(Suffix, []) -> false. + +%% last(List) returns the last element in a list. + +last([E]) -> E; +last([E|Es]) -> + last(Es). + +%% seq(Min, Max) -> [Min,Min+1, ..., Max] +%% seq(Min, Max, Incr) -> [Min,Min+Incr, ..., Max] +%% returns the sequence Min..Max +%% Min <= Max and Min and Max must be integers + +seq(Min, Max) when integer(Min), integer(Max), Min =< Max -> + seq(Min, Max, 1, []). + +seq(Min, Max, Incr) -> + seq(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []). + +seq(Min, Min, I, L) -> [Min|L]; +seq(Min, Max, I, L) -> seq(Min, Max-I, I, [Max|L]). + +%% sum(L) suns the sum of the elements in L + +sum(L) -> sum(L, 0). +sum([H|T], Sum) -> sum(T, Sum + H); +sum([], Sum) -> Sum. + +%% duplicate(N, X) -> [X,X,X,.....,X] (N times) +%% return N copies of X + +duplicate(N, X) when integer(N), N >= 0 -> duplicate(N, X, []). + +duplicate(0, _, L) -> L; +duplicate(N, X, L) -> duplicate(N-1, X, [X|L]). + + +%% min(L) -> returns the minimum element of the list L + +min([H|T]) -> min(T, H). + +min([H|T], Min) when H < Min -> min(T, H); +min([_|T], Min) -> min(T, Min); +min([], Min) -> Min. + +%% max(L) -> returns the maximum element of the list L + +max([H|T]) -> max(T, H). + +max([H|T], Max) when H > Max -> max(T, H); +max([_|T], Max) -> max(T, Max); +max([], Max) -> Max. + +%% sublist(List, Start, Length) +%% Returns the sub-list starting at Start of length Length. + +sublist(List, S, L) when L >= 0 -> + sublist(nthtail(S-1, List), L). + +sublist([H|T], L) when L > 0 -> + [H|sublist(T, L-1)]; +sublist(List, L) -> []. + +%% delete(Item, List) -> List' +%% Delete the first occurance of Item from the list L. + +delete(Item, [Item|Rest]) -> Rest; +delete(Item, [H|Rest]) -> + [H|delete(Item, Rest)]; +delete(Item, []) -> []. + +%% sort(L) -> sorts the list L + +sort([X]) -> [X]; +sort([]) -> []; +sort(X) -> split_and_sort(X, [], []). + +split_and_sort([A,B|T], X, Y) -> + split_and_sort(T, [A|X], [B|Y]); +split_and_sort([H], X, Y) -> + split_and_sort([], [H|X], Y); +split_and_sort([], X, Y) -> + merge(sort(X), sort(Y), []). + +%% merge(X, Y) -> L +%% merges two sorted lists X and Y + +merge(X, Y) -> merge(X, Y, []). + +merge([H1|T1], [H2|T2], L) when H1 < H2 -> + merge(T1, [H2|T2], [H1|L]); +merge(T1, [H2|T2], L) -> + merge(T1, T2, [H2|L]); +merge([H|T], T2, L) -> + merge(T, T2, [H|L]); +merge([], [], L) -> + reverse(L). + +%% concat(L) concatinate the list representation of the elements +%% in L - the elements in L can be atoms, integers of strings. +%% Returns a list of characters. + +concat(List) -> + flatmap(fun thing_to_list/1, List). + +thing_to_list(X) when integer(X) -> integer_to_list(X); +thing_to_list(X) when float(X) -> float_to_list(X); +thing_to_list(X) when atom(X) -> atom_to_list(X); +thing_to_list(X) when list(X) -> X. %Assumed to be a string + +%% flatten(List) +%% flatten(List, Tail) +%% Flatten a list, adding optional tail. + +flatten(List) -> + flatten(List, [], []). + +flatten(List, Tail) -> + flatten(List, [], Tail). + +flatten([H|T], Cont, Tail) when list(H) -> + flatten(H, [T|Cont], Tail); +flatten([H|T], Cont, Tail) -> + [H|flatten(T, Cont, Tail)]; +flatten([], [H|Cont], Tail) -> + flatten(H, Cont, Tail); +flatten([], [], Tail) -> + Tail. + +%% flat_length(List) (undocumented can be rmove later) +%% Calculate the length of a list of lists. + +flat_length(List) -> flatlength(List). + +%% flatlength(List) +%% Calculate the length of a list of lists. + +flatlength(List) -> + flatlength(List, 0). + +flatlength([H|T], L) when list(H) -> + flatlength(H, flatlength(T, L)); +flatlength([H|T], L) -> + flatlength(T, L + 1); +flatlength([], L) -> L. + +%% keymember(Key, Index, [Tuple]) +%% keysearch(Key, Index, [Tuple]) +%% keydelete(Key, Index, [Tuple]) +%% keyreplace(Key, Index, [Tuple], NewTuple) +%% keysort(Index, [Tuple]) +%% keymerge(Index, [Tuple], [Tuple]) +%% keymap(Function, Index, [Tuple]) +%% keymap(Function, ExtraArgs, Index, [Tuple]) + +keymember(Key, N, [T|Ts]) when element(N, T) == Key -> true; +keymember(Key, N, [T|Ts]) -> + keymember(Key, N, Ts); +keymember(Key, N, []) -> false. + +keysearch(Key, N, [H|T]) when element(N, H) == Key -> + {value, H}; +keysearch(Key, N, [H|T]) -> + keysearch(Key, N, T); +keysearch(Key, N, []) -> false. + +keydelete(Key, N, [H|T]) when element(N, H) == Key -> T; +keydelete(Key, N, [H|T]) -> + [H|keydelete(Key, N, T)]; +keydelete(Key, N, []) -> []. + +keyreplace(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key -> + [New|Tail]; +keyreplace(Key, Pos, [H|T], New) -> + [H|keyreplace(Key, Pos, T, New)]; +keyreplace(Key, Pos, [], New) -> []. + +keysort(Index, [X]) -> [X]; +keysort(Index, []) -> []; +keysort(Index, X) -> split_and_keysort(X, [], [], Index). + +split_and_keysort([A,B|T], X, Y, Index) -> + split_and_keysort(T, [A|X], [B|Y], Index); +split_and_keysort([H], X, Y, Index) -> + split_and_keysort([], [H|X], Y, Index); +split_and_keysort([], X, Y, Index) -> + keymerge(Index, keysort(Index, X), keysort(Index, Y), []). + +keymerge(Index, X, Y) -> keymerge(Index, X, Y, []). + +keymerge(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) -> + keymerge(I, T1, [H2|T2], [H1|L]); +keymerge(Index, T1, [H2|T2], L) -> + keymerge(Index,T1, T2, [H2|L]); +keymerge(Index,[H|T], T2, L) -> + keymerge(Index,T, T2, [H|L]); +keymerge(Index, [], [], L) -> + reverse(L). + +keymap(Fun, Index, [Tup|Tail]) -> + [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap(Fun, Index, Tail)]; +keymap( _, _ , []) -> []. + +keymap(Fun, ExtraArgs, Index, [Tup|Tail]) -> + [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| + keymap(Fun, ExtraArgs, Index, Tail)]; +keymap( _, _ , _, []) -> []. + +%% all(Predicate, List) +%% any(Predicate, List) +%% map(Function, List) +%% flatmap(Function, List) +%% foldl(Function, First, List) +%% foldr(Function, Last, List) +%% filter(Predicate, List) +%% zf(Function, List) +%% mapfoldl(Function, First, List) +%% mapfoldr(Function, Last, List) +%% foreach(Function, List) +%% takewhile(Predicate, List) +%% dropwhile(Predicate, List) +%% splitwith(Predicate, List) +%% for list programming. Function here is either a 'fun' or a tuple +%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke! +%% +%% N.B. Unless where the functions actually needs it only foreach/2/3, +%% which is meant to be used for its side effects, has a defined order +%% of evaluation. +%% +%% There are also versions with an extra argument, ExtraArgs, which is a +%% list of extra arguments to each call. + +all(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> all(Pred, Tail); + false -> false + end; +all(Pred, []) -> true. + +any(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> true; + false -> any(Pred, Tail) + end; +any(Pred, []) -> false. + +map(F, List) -> [ F(E) || E <- List ]. + +flatmap(F, [Hd|Tail]) -> + F(Hd) ++ flatmap(F, Tail); +flatmap(F, []) -> []. + +foldl(F, Accu, [Hd|Tail]) -> + foldl(F, F(Hd, Accu), Tail); +foldl(F, Accu, []) -> Accu. + +foldr(F, Accu, [Hd|Tail]) -> + F(Hd, foldr(F, Accu, Tail)); +foldr(F, Accu, []) -> Accu. + +filter(Pred, List) -> [ E || E <- List, Pred(E) ]. + +zf(F, [Hd|Tail]) -> + case F(Hd) of + true -> + [Hd|zf(F, Tail)]; + {true,Val} -> + [Val|zf(F, Tail)]; + false -> + zf(F, Tail) + end; +zf(F, []) -> []. + +foreach(F, [Hd|Tail]) -> + F(Hd), + foreach(F, Tail); +foreach(F, []) -> ok. + +mapfoldl(F, Accu0, [Hd|Tail]) -> + {R,Accu1} = F(Hd, Accu0), + {Rs,Accu2} = mapfoldl(F, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl(F, Accu, []) -> {[],Accu}. + +mapfoldr(F, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr(F, Accu0, Tail), + {R,Accu2} = F(Hd, Accu1), + {[R|Rs],Accu2}; +mapfoldr(F, Accu, []) -> {[],Accu}. + +takewhile(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> [Hd|takewhile(Pred, Tail)]; + false -> [] + end; +takewhile(Pred, []) -> []. + +dropwhile(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> dropwhile(Pred, Tail); + false -> [Hd|Tail] + end; +dropwhile(Pred, []) -> []. + +splitwith(Pred, List) -> splitwith(Pred, List, []). + +splitwith(Pred, [Hd|Tail], Taken) -> + case Pred(Hd) of + true -> splitwith(Pred, Tail, [Hd|Taken]); + false -> {reverse(Taken), [Hd|Tail]} + end; +splitwith(Pred, [], Taken) -> {reverse(Taken),[]}. + +%% Versions of the above functions with extra arguments. + +all(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> all(Pred, Eas, Tail); + false -> false + end; +all(Pred, Eas, []) -> true. + +any(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> true; + false -> any(Pred, Eas, Tail) + end; +any(Pred, Eas, []) -> false. + +map(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ]. + +flatmap(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]) ++ flatmap(F, Eas, Tail); +flatmap(F, Eas, []) -> []. + +foldl(F, Eas, Accu, [Hd|Tail]) -> + foldl(F, Eas, apply(F, [Hd,Accu|Eas]), Tail); +foldl(F, Eas, Accu, []) -> Accu. + +foldr(F, Eas, Accu, [Hd|Tail]) -> + apply(F, [Hd,foldr(F, Eas, Accu, Tail)|Eas]); +foldr(F, Eas, Accu, []) -> + Accu. + +filter(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ]. + +zf(F, Eas, [Hd|Tail]) -> + case apply(F, [Hd|Eas]) of + true -> + [Hd|zf(F, Eas, Tail)]; + {true,Val} -> + [Val|zf(F, Eas, Tail)]; + false -> + zf(F, Eas, Tail) + end; +zf(F, Eas, []) -> []. + +foreach(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]), + foreach(F, Eas, Tail); +foreach(F, Eas, []) -> ok. + +mapfoldl(F, Eas, Accu0, [Hd|Tail]) -> + {R,Accu1} = apply(F, [Hd,Accu0|Eas]), + {Rs,Accu2} = mapfoldl(F, Eas, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl(F, Eas, Accu, []) -> {[],Accu}. + +mapfoldr(F, Eas, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr(F, Eas, Accu0, Tail), + {R,Accu2} = apply(F, [Hd,Accu1|Eas]), + {[R|Rs],Accu2}; +mapfoldr(F, Eas, Accu, []) -> {[],Accu}. + +%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with +%% extra arguments as this going to be discontinued. diff --git a/lib/debugger/test/int_SUITE_data/my_lists.erl b/lib/debugger/test/int_SUITE_data/my_lists.erl new file mode 100644 index 0000000000..98eb4396e3 --- /dev/null +++ b/lib/debugger/test/int_SUITE_data/my_lists.erl @@ -0,0 +1,5681 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%%% A rather large file to test the attach delay. +%%% Use only the ordinary lists commands. + +-module(my_lists). + + +-export([member/2, append/2, append/1, subtract/2, reverse/1, reverse/2, + nth/2, nthtail/2, prefix/2, suffix/2, last/1, + seq/2, seq/3, sum/1, duplicate/2, min/1, max/1, sublist/2, sublist/3, + delete/2, sort/1, merge/2, concat/1, + flatten/1, flatten/2, flat_length/1, flatlength/1, + keymember/3, keysearch/3, keydelete/3, keyreplace/4, + keysort/2, keymerge/3, keymap/3, keymap/4]). + +-export([all/2,any/2,map/2,flatmap/2,foldl/3,foldr/3,filter/2,zf/2, + mapfoldl/3,mapfoldr/3,foreach/2,takewhile/2,dropwhile/2,splitwith/2]). +-export([all/3,any/3,map/3,flatmap/3,foldl/4,foldr/4,filter/3,zf/3, + mapfoldl/4,mapfoldr/4,foreach/3]). + +%% member(X, L) -> (true | false) +%% test if X is a member of the list L + +member(X, [X|_]) -> true; +member(X, [_|Y]) -> + member(X, Y); +member(X, []) -> false. + +%% append(X, Y) appends lists X and Y + +append(L1, L2) -> L1 ++ L2. + +%% append(L) appends the list of lists L + +append([E]) -> E; +append([H|T]) -> H ++ append(T); +append([]) -> []. + +%% subtract(List1, List2) subtract elements in List2 form List1. + +subtract(L1, L2) -> L1 -- L2. + +%% reverse(L) reverse all elements in the list L + +reverse(X) -> reverse(X, []). + +reverse([H|T], Y) -> + reverse(T, [H|Y]); +reverse([], X) -> X. + +%% nth(N, L) returns the N`th element of the list L +%% nthtail(N, L) returns the N`th tail of the list L + +nth(1, [H|T]) -> H; +nth(N, [_|T]) when N > 1 -> + nth(N - 1, T). + +nthtail(1, [H|T]) -> T; +nthtail(N, [H|T]) when N > 1 -> + nthtail(N - 1, T); +nthtail(0, L) when list(L) -> L. + +%% prefix(Prefix, List) -> (true | false) + +prefix([X|PreTail], [X|Tail]) -> + prefix(PreTail, Tail); +prefix([], List) -> true; +prefix(_,_) -> false. + + +%% suffix(Suffix, List) -> (true | false) + +suffix(Suffix, Suffix) -> true; +suffix(Suffix, [_|Tail]) -> + suffix(Suffix, Tail); +suffix(Suffix, []) -> false. + +%% last(List) returns the last element in a list. + +last([E]) -> E; +last([E|Es]) -> + last(Es). + +%% seq(Min, Max) -> [Min,Min+1, ..., Max] +%% seq(Min, Max, Incr) -> [Min,Min+Incr, ..., Max] +%% returns the sequence Min..Max +%% Min <= Max and Min and Max must be integers + +seq(Min, Max) when integer(Min), integer(Max), Min =< Max -> + seq(Min, Max, 1, []). + +seq(Min, Max, Incr) -> + seq(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []). + +seq(Min, Min, I, L) -> [Min|L]; +seq(Min, Max, I, L) -> seq(Min, Max-I, I, [Max|L]). + +%% sum(L) suns the sum of the elements in L + +sum(L) -> sum(L, 0). +sum([H|T], Sum) -> sum(T, Sum + H); +sum([], Sum) -> Sum. + +%% duplicate(N, X) -> [X,X,X,.....,X] (N times) +%% return N copies of X + +duplicate(N, X) when integer(N), N >= 0 -> duplicate(N, X, []). + +duplicate(0, _, L) -> L; +duplicate(N, X, L) -> duplicate(N-1, X, [X|L]). + + +%% min(L) -> returns the minimum element of the list L + +min([H|T]) -> min(T, H). + +min([H|T], Min) when H < Min -> min(T, H); +min([_|T], Min) -> min(T, Min); +min([], Min) -> Min. + +%% max(L) -> returns the maximum element of the list L + +max([H|T]) -> max(T, H). + +max([H|T], Max) when H > Max -> max(T, H); +max([_|T], Max) -> max(T, Max); +max([], Max) -> Max. + +%% sublist(List, Start, Length) +%% Returns the sub-list starting at Start of length Length. + +sublist(List, S, L) when L >= 0 -> + sublist(nthtail(S-1, List), L). + +sublist([H|T], L) when L > 0 -> + [H|sublist(T, L-1)]; +sublist(List, L) -> []. + +%% delete(Item, List) -> List' +%% Delete the first occurance of Item from the list L. + +delete(Item, [Item|Rest]) -> Rest; +delete(Item, [H|Rest]) -> + [H|delete(Item, Rest)]; +delete(Item, []) -> []. + +%% sort(L) -> sorts the list L + +sort([X]) -> [X]; +sort([]) -> []; +sort(X) -> split_and_sort(X, [], []). + +split_and_sort([A,B|T], X, Y) -> + split_and_sort(T, [A|X], [B|Y]); +split_and_sort([H], X, Y) -> + split_and_sort([], [H|X], Y); +split_and_sort([], X, Y) -> + merge(sort(X), sort(Y), []). + +%% merge(X, Y) -> L +%% merges two sorted lists X and Y + +merge(X, Y) -> merge(X, Y, []). + +merge([H1|T1], [H2|T2], L) when H1 < H2 -> + merge(T1, [H2|T2], [H1|L]); +merge(T1, [H2|T2], L) -> + merge(T1, T2, [H2|L]); +merge([H|T], T2, L) -> + merge(T, T2, [H|L]); +merge([], [], L) -> + reverse(L). + +%% concat(L) concatinate the list representation of the elements +%% in L - the elements in L can be atoms, integers of strings. +%% Returns a list of characters. + +concat(List) -> + flatmap(fun thing_to_list/1, List). + +thing_to_list(X) when integer(X) -> integer_to_list(X); +thing_to_list(X) when float(X) -> float_to_list(X); +thing_to_list(X) when atom(X) -> atom_to_list(X); +thing_to_list(X) when list(X) -> X. %Assumed to be a string + +%% flatten(List) +%% flatten(List, Tail) +%% Flatten a list, adding optional tail. + +flatten(List) -> + flatten(List, [], []). + +flatten(List, Tail) -> + flatten(List, [], Tail). + +flatten([H|T], Cont, Tail) when list(H) -> + flatten(H, [T|Cont], Tail); +flatten([H|T], Cont, Tail) -> + [H|flatten(T, Cont, Tail)]; +flatten([], [H|Cont], Tail) -> + flatten(H, Cont, Tail); +flatten([], [], Tail) -> + Tail. + +%% flat_length(List) (undocumented can be rmove later) +%% Calculate the length of a list of lists. + +flat_length(List) -> flatlength(List). + +%% flatlength(List) +%% Calculate the length of a list of lists. + +flatlength(List) -> + flatlength(List, 0). + +flatlength([H|T], L) when list(H) -> + flatlength(H, flatlength(T, L)); +flatlength([H|T], L) -> + flatlength(T, L + 1); +flatlength([], L) -> L. + +%% keymember(Key, Index, [Tuple]) +%% keysearch(Key, Index, [Tuple]) +%% keydelete(Key, Index, [Tuple]) +%% keyreplace(Key, Index, [Tuple], NewTuple) +%% keysort(Index, [Tuple]) +%% keymerge(Index, [Tuple], [Tuple]) +%% keymap(Function, Index, [Tuple]) +%% keymap(Function, ExtraArgs, Index, [Tuple]) + +keymember(Key, N, [T|Ts]) when element(N, T) == Key -> true; +keymember(Key, N, [T|Ts]) -> + keymember(Key, N, Ts); +keymember(Key, N, []) -> false. + +keysearch(Key, N, [H|T]) when element(N, H) == Key -> + {value, H}; +keysearch(Key, N, [H|T]) -> + keysearch(Key, N, T); +keysearch(Key, N, []) -> false. + +keydelete(Key, N, [H|T]) when element(N, H) == Key -> T; +keydelete(Key, N, [H|T]) -> + [H|keydelete(Key, N, T)]; +keydelete(Key, N, []) -> []. + +keyreplace(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key -> + [New|Tail]; +keyreplace(Key, Pos, [H|T], New) -> + [H|keyreplace(Key, Pos, T, New)]; +keyreplace(Key, Pos, [], New) -> []. + +keysort(Index, [X]) -> [X]; +keysort(Index, []) -> []; +keysort(Index, X) -> split_and_keysort(X, [], [], Index). + +split_and_keysort([A,B|T], X, Y, Index) -> + split_and_keysort(T, [A|X], [B|Y], Index); +split_and_keysort([H], X, Y, Index) -> + split_and_keysort([], [H|X], Y, Index); +split_and_keysort([], X, Y, Index) -> + keymerge(Index, keysort(Index, X), keysort(Index, Y), []). + +keymerge(Index, X, Y) -> keymerge(Index, X, Y, []). + +keymerge(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) -> + keymerge(I, T1, [H2|T2], [H1|L]); +keymerge(Index, T1, [H2|T2], L) -> + keymerge(Index,T1, T2, [H2|L]); +keymerge(Index,[H|T], T2, L) -> + keymerge(Index,T, T2, [H|L]); +keymerge(Index, [], [], L) -> + reverse(L). + +keymap(Fun, Index, [Tup|Tail]) -> + [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap(Fun, Index, Tail)]; +keymap( _, _ , []) -> []. + +keymap(Fun, ExtraArgs, Index, [Tup|Tail]) -> + [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| + keymap(Fun, ExtraArgs, Index, Tail)]; +keymap( _, _ , _, []) -> []. + +%% all(Predicate, List) +%% any(Predicate, List) +%% map(Function, List) +%% flatmap(Function, List) +%% foldl(Function, First, List) +%% foldr(Function, Last, List) +%% filter(Predicate, List) +%% zf(Function, List) +%% mapfoldl(Function, First, List) +%% mapfoldr(Function, Last, List) +%% foreach(Function, List) +%% takewhile(Predicate, List) +%% dropwhile(Predicate, List) +%% splitwith(Predicate, List) +%% for list programming. Function here is either a 'fun' or a tuple +%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke! +%% +%% N.B. Unless where the functions actually needs it only foreach/2/3, +%% which is meant to be used for its side effects, has a defined order +%% of evaluation. +%% +%% There are also versions with an extra argument, ExtraArgs, which is a +%% list of extra arguments to each call. + +all(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> all(Pred, Tail); + false -> false + end; +all(Pred, []) -> true. + +any(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> true; + false -> any(Pred, Tail) + end; +any(Pred, []) -> false. + +map(F, List) -> [ F(E) || E <- List ]. + +flatmap(F, [Hd|Tail]) -> + F(Hd) ++ flatmap(F, Tail); +flatmap(F, []) -> []. + +foldl(F, Accu, [Hd|Tail]) -> + foldl(F, F(Hd, Accu), Tail); +foldl(F, Accu, []) -> Accu. + +foldr(F, Accu, [Hd|Tail]) -> + F(Hd, foldr(F, Accu, Tail)); +foldr(F, Accu, []) -> Accu. + +filter(Pred, List) -> [ E || E <- List, Pred(E) ]. + +zf(F, [Hd|Tail]) -> + case F(Hd) of + true -> + [Hd|zf(F, Tail)]; + {true,Val} -> + [Val|zf(F, Tail)]; + false -> + zf(F, Tail) + end; +zf(F, []) -> []. + +foreach(F, [Hd|Tail]) -> + F(Hd), + foreach(F, Tail); +foreach(F, []) -> ok. + +mapfoldl(F, Accu0, [Hd|Tail]) -> + {R,Accu1} = F(Hd, Accu0), + {Rs,Accu2} = mapfoldl(F, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl(F, Accu, []) -> {[],Accu}. + +mapfoldr(F, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr(F, Accu0, Tail), + {R,Accu2} = F(Hd, Accu1), + {[R|Rs],Accu2}; +mapfoldr(F, Accu, []) -> {[],Accu}. + +takewhile(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> [Hd|takewhile(Pred, Tail)]; + false -> [] + end; +takewhile(Pred, []) -> []. + +dropwhile(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> dropwhile(Pred, Tail); + false -> [Hd|Tail] + end; +dropwhile(Pred, []) -> []. + +splitwith(Pred, List) -> splitwith(Pred, List, []). + +splitwith(Pred, [Hd|Tail], Taken) -> + case Pred(Hd) of + true -> splitwith(Pred, Tail, [Hd|Taken]); + false -> {reverse(Taken), [Hd|Tail]} + end; +splitwith(Pred, [], Taken) -> {reverse(Taken),[]}. + +%% Versions of the above functions with extra arguments. + +all(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> all(Pred, Eas, Tail); + false -> false + end; +all(Pred, Eas, []) -> true. + +any(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> true; + false -> any(Pred, Eas, Tail) + end; +any(Pred, Eas, []) -> false. + +map(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ]. + +flatmap(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]) ++ flatmap(F, Eas, Tail); +flatmap(F, Eas, []) -> []. + +foldl(F, Eas, Accu, [Hd|Tail]) -> + foldl(F, Eas, apply(F, [Hd,Accu|Eas]), Tail); +foldl(F, Eas, Accu, []) -> Accu. + +foldr(F, Eas, Accu, [Hd|Tail]) -> + apply(F, [Hd,foldr(F, Eas, Accu, Tail)|Eas]); +foldr(F, Eas, Accu, []) -> + Accu. + +filter(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ]. + +zf(F, Eas, [Hd|Tail]) -> + case apply(F, [Hd|Eas]) of + true -> + [Hd|zf(F, Eas, Tail)]; + {true,Val} -> + [Val|zf(F, Eas, Tail)]; + false -> + zf(F, Eas, Tail) + end; +zf(F, Eas, []) -> []. + +foreach(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]), + foreach(F, Eas, Tail); +foreach(F, Eas, []) -> ok. + +mapfoldl(F, Eas, Accu0, [Hd|Tail]) -> + {R,Accu1} = apply(F, [Hd,Accu0|Eas]), + {Rs,Accu2} = mapfoldl(F, Eas, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl(F, Eas, Accu, []) -> {[],Accu}. + +mapfoldr(F, Eas, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr(F, Eas, Accu0, Tail), + {R,Accu2} = apply(F, [Hd,Accu1|Eas]), + {[R|Rs],Accu2}; +mapfoldr(F, Eas, Accu, []) -> {[],Accu}. + +%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with +%% extra arguments as this going to be discontinued. + + + + + +%%% +++++++++++++++++++++++++++++++++++++++ +%%% +%%% Same as above but with "_1" added to the function names +%%% + + +%% member_1(X, L) -> (true | false) +%% test if X is a member of the list L + +%member_1(X, [X|_]) -> true; +%member_1(X, [_|Y]) -> +% member_1(X, Y); +%member_1(X, []) -> false. + +member_1(X, L) when list(L) -> + case erlang:member_1(X, L) of + L1 when list(L1) -> + receive after 1 -> ok end, + member_1(X, L1); + Boolean -> + Boolean + end. + +%% append_1(X, Y) appends lists X and Y + +append_1(L1, L2) -> L1 ++ L2. + +%% append_1(L) appends the list of lists L + +append_1([E]) -> E; +append_1([H|T]) -> H ++ append_1(T); +append_1([]) -> []. + +%% subtract_1(List1, List2) subtract elements in List2 form List1. + +subtract_1(L1, L2) -> L1 -- L2. + +%% reverse_1(L) reverse all elements in the list L + +reverse_1(X) -> reverse_1(X, []). + +%reverse_1([H|T], Y) -> +% reverse_1(T, [H|Y]); +%reverse_1([], X) -> X. + +reverse_1(List0, Result0) when list(List0) -> + case erlang:reverse_1(List0, Result0) of + {List, Result} -> + receive after 1 -> ok end, + reverse_1(List, Result); + Result -> + Result + end. + + +%% nth_1(N, L) returns the N`th element of the list L +%% nthtail_1(N, L) returns the N`th tail of the list L + +nth_1(1, [H|T]) -> H; +nth_1(N, [_|T]) when N > 1 -> + nth_1(N - 1, T). + +nthtail_1(1, [H|T]) -> T; +nthtail_1(N, [H|T]) when N > 1 -> + nthtail_1(N - 1, T); +nthtail_1(0, L) when list(L) -> L. + +%% prefix_1(Prefix, List) -> (true | false) + +prefix_1([X|PreTail], [X|Tail]) -> + prefix_1(PreTail, Tail); +prefix_1([], List) -> true; +prefix_1(_,_) -> false. + + +%% suffix_1(Suffix, List) -> (true | false) + +suffix_1(Suffix, Suffix) -> true; +suffix_1(Suffix, [_|Tail]) -> + suffix_1(Suffix, Tail); +suffix_1(Suffix, []) -> false. + +%% last(List) returns the last element in a list. + +last_1([E]) -> E; +last_1([E|Es]) -> + last_1(Es). + +%% seq(Min, Max) -> [Min,Min+1, ..., Max] +%% seq(Min, Max, Incr) -> [Min,Min+Incr, ..., Max] +%% returns the sequence Min..Max +%% Min <= Max and Min and Max must be integers + +seq_1(Min, Max) when integer(Min), integer(Max), Min =< Max -> + seq_1(Min, Max, 1, []). + +seq_1(Min, Max, Incr) -> + seq_1(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []). + +seq_1(Min, Min, I, L) -> [Min|L]; +seq_1(Min, Max, I, L) -> seq_1(Min, Max-I, I, [Max|L]). + +%% sum(L) suns the sum of the elements in L + +sum_1(L) -> sum_1(L, 0). +sum_1([H|T], Sum) -> sum_1(T, Sum + H); +sum_1([], Sum) -> Sum. + +%% duplicate(N, X) -> [X,X,X,.....,X] (N times) +%% return N copies of X + +duplicate_1(N, X) when integer(N), N >= 0 -> duplicate_1(N, X, []). + +duplicate_1(0, _, L) -> L; +duplicate_1(N, X, L) -> duplicate_1(N-1, X, [X|L]). + + +%% min(L) -> returns the minimum element of the list L + +min_1([H|T]) -> min_1(T, H). + +min_1([H|T], Min) when H < Min -> min_1(T, H); +min_1([_|T], Min) -> min_1(T, Min); +min_1([], Min) -> Min. + +%% max(L) -> returns the maximum element of the list L + +max_1([H|T]) -> max_1(T, H). + +max_1([H|T], Max) when H > Max -> max_1(T, H); +max_1([_|T], Max) -> max_1(T, Max); +max_1([], Max) -> Max. + +%% sublist(List, Start, Length) +%% Returns the sub-list starting at Start of length Length. + +sublist_1(List, S, L) when L >= 0 -> + sublist_1(nthtail_1(S-1, List), L). + +sublist_1([H|T], L) when L > 0 -> + [H|sublist_1(T, L-1)]; +sublist_1(List, L) -> []. + +%% delete(Item, List) -> List' +%% Delete the first occurance of Item from the list L. + +delete_1(Item, [Item|Rest]) -> Rest; +delete_1(Item, [H|Rest]) -> + [H|delete_1(Item, Rest)]; +delete_1(Item, []) -> []. + +%% sort(L) -> sorts the list L + +sort_1([X]) -> [X]; +sort_1([]) -> []; +sort_1(X) -> split_and_sort_1(X, [], []). + +split_and_sort_1([A,B|T], X, Y) -> + split_and_sort_1(T, [A|X], [B|Y]); +split_and_sort_1([H], X, Y) -> + split_and_sort_1([], [H|X], Y); +split_and_sort_1([], X, Y) -> + merge_1(sort_1(X), sort_1(Y), []). + +%% merge(X, Y) -> L +%% merges two sorted lists X and Y + +merge_1(X, Y) -> merge_1(X, Y, []). + +merge_1([H1|T1], [H2|T2], L) when H1 < H2 -> + merge_1(T1, [H2|T2], [H1|L]); +merge_1(T1, [H2|T2], L) -> + merge_1(T1, T2, [H2|L]); +merge_1([H|T], T2, L) -> + merge_1(T, T2, [H|L]); +merge_1([], [], L) -> + reverse_1(L). + +%% concat(L) concatinate the list representation of the elements +%% in L - the elements in L can be atoms, integers of strings. +%% Returns a list of characters. + +concat_1(List) -> + flatmap_1(fun thing_to_list/1, List). + +thing_to_list_1(X) when integer(X) -> integer_to_list(X); +thing_to_list_1(X) when float(X) -> float_to_list(X); +thing_to_list_1(X) when atom(X) -> atom_to_list(X); +thing_to_list_1(X) when list(X) -> X. %Assumed to be a string + +%% flatten(List) +%% flatten(List, Tail) +%% Flatten a list, adding optional tail. + +flatten_1(List) -> + flatten_1(List, [], []). + +flatten_1(List, Tail) -> + flatten_1(List, [], Tail). + +flatten_1([H|T], Cont, Tail) when list(H) -> + flatten_1(H, [T|Cont], Tail); +flatten_1([H|T], Cont, Tail) -> + [H|flatten_1(T, Cont, Tail)]; +flatten_1([], [H|Cont], Tail) -> + flatten_1(H, Cont, Tail); +flatten_1([], [], Tail) -> + Tail. + +%% flat_length(List) (undocumented can be rmove later) +%% Calculate the length of a list of lists. + +flat_length_1(List) -> flatlength_1(List). + +%% flatlength(List) +%% Calculate the length of a list of lists. + +flatlength_1(List) -> + flatlength_1(List, 0). + +flatlength_1([H|T], L) when list(H) -> + flatlength_1(H, flatlength_1(T, L)); +flatlength_1([H|T], L) -> + flatlength_1(T, L + 1); +flatlength_1([], L) -> L. + +%% keymember(Key, Index, [Tuple]) +%% keysearch(Key, Index, [Tuple]) +%% keydelete(Key, Index, [Tuple]) +%% keyreplace(Key, Index, [Tuple], NewTuple) +%% keysort(Index, [Tuple]) +%% keymerge(Index, [Tuple], [Tuple]) +%% keymap(Function, Index, [Tuple]) +%% keymap(Function, ExtraArgs, Index, [Tuple]) + +keymember_1(Key, N, [T|Ts]) when element(N, T) == Key -> true; +keymember_1(Key, N, [T|Ts]) -> + keymember_1(Key, N, Ts); +keymember_1(Key, N, []) -> false. + +keysearch_1(Key, N, [H|T]) when element(N, H) == Key -> + {value, H}; +keysearch_1(Key, N, [H|T]) -> + keysearch_1(Key, N, T); +keysearch_1(Key, N, []) -> false. + +keydelete_1(Key, N, [H|T]) when element(N, H) == Key -> T; +keydelete_1(Key, N, [H|T]) -> + [H|keydelete_1(Key, N, T)]; +keydelete_1(Key, N, []) -> []. + +keyreplace_1(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key -> + [New|Tail]; +keyreplace_1(Key, Pos, [H|T], New) -> + [H|keyreplace_1(Key, Pos, T, New)]; +keyreplace_1(Key, Pos, [], New) -> []. + +keysort_1(Index, [X]) -> [X]; +keysort_1(Index, []) -> []; +keysort_1(Index, X) -> split_and_keysort_1(X, [], [], Index). + +split_and_keysort_1([A,B|T], X, Y, Index) -> + split_and_keysort_1(T, [A|X], [B|Y], Index); +split_and_keysort_1([H], X, Y, Index) -> + split_and_keysort_1([], [H|X], Y, Index); +split_and_keysort_1([], X, Y, Index) -> + keymerge_1(Index, keysort_1(Index, X), keysort_1(Index, Y), []). + +keymerge_1(Index, X, Y) -> keymerge_1(Index, X, Y, []). + +keymerge_1(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) -> + keymerge_1(I, T1, [H2|T2], [H1|L]); +keymerge_1(Index, T1, [H2|T2], L) -> + keymerge_1(Index,T1, T2, [H2|L]); +keymerge_1(Index,[H|T], T2, L) -> + keymerge_1(Index,T, T2, [H|L]); +keymerge_1(Index, [], [], L) -> + reverse_1(L). + +keymap_1(Fun, Index, [Tup|Tail]) -> + [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap_1(Fun, Index, Tail)]; +keymap_1( _, _ , []) -> []. + +keymap_1(Fun, ExtraArgs, Index, [Tup|Tail]) -> + [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| + keymap_1(Fun, ExtraArgs, Index, Tail)]; +keymap_1( _, _ , _, []) -> []. + +%% all(Predicate, List) +%% any(Predicate, List) +%% map(Function, List) +%% flatmap(Function, List) +%% foldl(Function, First, List) +%% foldr(Function, Last, List) +%% filter(Predicate, List) +%% zf(Function, List) +%% mapfoldl(Function, First, List) +%% mapfoldr(Function, Last, List) +%% foreach(Function, List) +%% takewhile(Predicate, List) +%% dropwhile(Predicate, List) +%% splitwith(Predicate, List) +%% for list programming. Function here is either a 'fun' or a tuple +%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke! +%% +%% N.B. Unless where the functions actually needs it only foreach/2/3, +%% which is meant to be used for its side effects, has a defined order +%% of evaluation. +%% +%% There are also versions with an extra argument, ExtraArgs, which is a +%% list of extra arguments to each call. + +all_1(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> all_1(Pred, Tail); + false -> false + end; +all_1(Pred, []) -> true. + +any_1(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> true; + false -> any_1(Pred, Tail) + end; +any_1(Pred, []) -> false. + +map_1(F, List) -> [ F(E) || E <- List ]. + +flatmap_1(F, [Hd|Tail]) -> + F(Hd) ++ flatmap_1(F, Tail); +flatmap_1(F, []) -> []. + +foldl_1(F, Accu, [Hd|Tail]) -> + foldl_1(F, F(Hd, Accu), Tail); +foldl_1(F, Accu, []) -> Accu. + +foldr_1(F, Accu, [Hd|Tail]) -> + F(Hd, foldr_1(F, Accu, Tail)); +foldr_1(F, Accu, []) -> Accu. + +filter_1(Pred, List) -> [ E || E <- List, Pred(E) ]. + +zF(F, [Hd|Tail]) -> + case F(Hd) of + true -> + [Hd|zF(F, Tail)]; + {true,Val} -> + [Val|zF(F, Tail)]; + false -> + zF(F, Tail) + end; +zF(F, []) -> []. + +foreach_1(F, [Hd|Tail]) -> + F(Hd), + foreach_1(F, Tail); +foreach_1(F, []) -> ok. + +mapfoldl_1(F, Accu0, [Hd|Tail]) -> + {R,Accu1} = F(Hd, Accu0), + {Rs,Accu2} = mapfoldl_1(F, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl_1(F, Accu, []) -> {[],Accu}. + +mapfoldr_1(F, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr_1(F, Accu0, Tail), + {R,Accu2} = F(Hd, Accu1), + {[R|Rs],Accu2}; +mapfoldr_1(F, Accu, []) -> {[],Accu}. + +takewhile_1(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> [Hd|takewhile_1(Pred, Tail)]; + false -> [] + end; +takewhile_1(Pred, []) -> []. + +dropwhile_1(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> dropwhile_1(Pred, Tail); + false -> [Hd|Tail] + end; +dropwhile_1(Pred, []) -> []. + +splitwith_1(Pred, List) -> splitwith_1(Pred, List, []). + +splitwith_1(Pred, [Hd|Tail], Taken) -> + case Pred(Hd) of + true -> splitwith_1(Pred, Tail, [Hd|Taken]); + false -> {reverse_1(Taken), [Hd|Tail]} + end; +splitwith_1(Pred, [], Taken) -> {reverse_1(Taken),[]}. + +%% Versions of the above functions with extra arguments. + +all_1(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> all_1(Pred, Eas, Tail); + false -> false + end; +all_1(Pred, Eas, []) -> true. + +any_1(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> true; + false -> any_1(Pred, Eas, Tail) + end; +any_1(Pred, Eas, []) -> false. + +map_1(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ]. + +flatmap_1(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]) ++ flatmap_1(F, Eas, Tail); +flatmap_1(F, Eas, []) -> []. + +foldl_1(F, Eas, Accu, [Hd|Tail]) -> + foldl_1(F, Eas, apply(F, [Hd,Accu|Eas]), Tail); +foldl_1(F, Eas, Accu, []) -> Accu. + +foldr_1(F, Eas, Accu, [Hd|Tail]) -> + apply(F, [Hd,foldr_1(F, Eas, Accu, Tail)|Eas]); +foldr_1(F, Eas, Accu, []) -> + Accu. + +filter_1(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ]. + +zF(F, Eas, [Hd|Tail]) -> + case apply(F, [Hd|Eas]) of + true -> + [Hd|zF(F, Eas, Tail)]; + {true,Val} -> + [Val|zF(F, Eas, Tail)]; + false -> + zF(F, Eas, Tail) + end; +zF(F, Eas, []) -> []. + +foreach_1(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]), + foreach_1(F, Eas, Tail); +foreach_1(F, Eas, []) -> ok. + +mapfoldl_1(F, Eas, Accu0, [Hd|Tail]) -> + {R,Accu1} = apply(F, [Hd,Accu0|Eas]), + {Rs,Accu2} = mapfoldl_1(F, Eas, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl_1(F, Eas, Accu, []) -> {[],Accu}. + +mapfoldr_1(F, Eas, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr_1(F, Eas, Accu0, Tail), + {R,Accu2} = apply(F, [Hd,Accu1|Eas]), + {[R|Rs],Accu2}; +mapfoldr_1(F, Eas, Accu, []) -> {[],Accu}. + +%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with +%% extra arguments as this going to be discontinued. + + + + + + +%%% +++++++++++++++++++++ +%%% +%%% "_2" + + + + + +%% member_2(X, L) -> _2(true | false) +%% test if X is a member of the list L + +%member_2(X, [X|_]) -> true; +%member_2(X, [_|Y]) -> +% member_2(X, Y); +%member_2(X, []) -> false. + +member_2(X, L) when list(L) -> + case erlang:member_2(X, L) of + L1 when list(L1) -> + receive after 1 -> ok end, + member_2(X, L1); + Boolean -> + Boolean + end. + +%% append_2(X, Y) appends lists X and Y + +append_2(L1, L2) -> L1 ++ L2. + +%% append_2(L) appends the list of lists L + +append_2([E]) -> E; +append_2([H|T]) -> H ++ append_2(T); +append_2([]) -> []. + +%% subtract_2(List1, List2) subtract elements in List2 form List1. + +subtract_2(L1, L2) -> L1 -- L2. + +%% reverse_2(L) reverse all elements in the list L + +reverse_2(X) -> reverse_2(X, []). + +%reverse_2([H|T], Y) -> +% reverse_2(T, [H|Y]); +%reverse_2([], X) -> X. + +reverse_2(List0, Result0) when list(List0) -> + case erlang:reverse_2(List0, Result0) of + {List, Result} -> + receive after 1 -> ok end, + reverse_2(List, Result); + Result -> + Result + end. + + +%% nth_2(N, L) returns the N`th element of the list L +%% nthtail_2(N, L) returns the N`th tail of the list L + +nth_2(1, [H|T]) -> H; +nth_2(N, [_|T]) when N > 1 -> + nth_2(N - 1, T). + +nthtail_2(1, [H|T]) -> T; +nthtail_2(N, [H|T]) when N > 1 -> + nthtail_2(N - 1, T); +nthtail_2(0, L) when list(L) -> L. + +%% prefix_2(Prefix, List) -> _2(true | false) + +prefix_2([X|PreTail], [X|Tail]) -> + prefix_2(PreTail, Tail); +prefix_2([], List) -> true; +prefix_2(_,_) -> false. + + +%% suffix_2(Suffix, List) -> _2(true | false) + +suffix_2(Suffix, Suffix) -> true; +suffix_2(Suffix, [_|Tail]) -> + suffix_2(Suffix, Tail); +suffix_2(Suffix, []) -> false. + +%% last_2(List) returns the last element in a list. + +last_2([E]) -> E; +last_2([E|Es]) -> + last_2(Es). + +%% seq_2(Min, Max) -> [Min,Min+1, ..., Max] +%% seq_2(Min, Max, Incr) -> [Min,Min+Incr, ..., Max] +%% returns the sequence Min..Max +%% Min <= Max and Min and Max must be integers + +seq_2(Min, Max) when integer(Min), integer(Max), Min =< Max -> + seq_2(Min, Max, 1, []). + +seq_2(Min, Max, Incr) -> + seq_2(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []). + +seq_2(Min, Min, I, L) -> [Min|L]; +seq_2(Min, Max, I, L) -> seq_2(Min, Max-I, I, [Max|L]). + +%% sum_2(L) suns the sum of the elements in L + +sum_2(L) -> sum_2(L, 0). +sum_2([H|T], Sum) -> sum_2(T, Sum + H); +sum_2([], Sum) -> Sum. + +%% duplicate_2(N, X) -> [X,X,X,.....,X] _2(N times) +%% return N copies of X + +duplicate_2(N, X) when integer(N), N >= 0 -> duplicate_2(N, X, []). + +duplicate_2(0, _, L) -> L; +duplicate_2(N, X, L) -> duplicate_2(N-1, X, [X|L]). + + +%% min_2(L) -> returns the minimum element of the list L + +min_2([H|T]) -> min_2(T, H). + +min_2([H|T], Min) when H < Min -> min_2(T, H); +min_2([_|T], Min) -> min_2(T, Min); +min_2([], Min) -> Min. + +%% max_2(L) -> returns the maximum element of the list L + +max_2([H|T]) -> max_2(T, H). + +max_2([H|T], Max) when H > Max -> max_2(T, H); +max_2([_|T], Max) -> max_2(T, Max); +max_2([], Max) -> Max. + +%% sublist(List, Start, Length) +%% Returns the sub-list starting at Start of length Length. + +sublist_2(List, S, L) when L >= 0 -> + sublist_2(nthtail_2(S-1, List), L). + +sublist_2([H|T], L) when L > 0 -> + [H|sublist_2(T, L-1)]; +sublist_2(List, L) -> []. + +%% delete_2(Item, List) -> List' +%% Delete the first occurance of Item from the list L. + +delete_2(Item, [Item|Rest]) -> Rest; +delete_2(Item, [H|Rest]) -> + [H|delete_2(Item, Rest)]; +delete_2(Item, []) -> []. + +%% sort_2(L) -> sorts the list L + +sort_2([X]) -> [X]; +sort_2([]) -> []; +sort_2(X) -> split_and_sort_2(X, [], []). + +split_and_sort_2([A,B|T], X, Y) -> + split_and_sort_2(T, [A|X], [B|Y]); +split_and_sort_2([H], X, Y) -> + split_and_sort_2([], [H|X], Y); +split_and_sort_2([], X, Y) -> + merge_2(sort_2(X), sort_2(Y), []). + +%% merge_2(X, Y) -> L +%% merges two sorted lists X and Y + +merge_2(X, Y) -> merge_2(X, Y, []). + +merge_2([H1|T1], [H2|T2], L) when H1 < H2 -> + merge_2(T1, [H2|T2], [H1|L]); +merge_2(T1, [H2|T2], L) -> + merge_2(T1, T2, [H2|L]); +merge_2([H|T], T2, L) -> + merge_2(T, T2, [H|L]); +merge_2([], [], L) -> + reverse_2(L). + +%% concat_2(L) concatinate the list representation of the elements +%% in L - the elements in L can be atoms, integers of strings. +%% Returns a list of characters. + +concat_2(List) -> + flatmap_2(fun thing_to_list/1, List). + +thing_to_list_2(X) when integer(X) -> integer_to_list(X); +thing_to_list_2(X) when float(X) -> float_to_list(X); +thing_to_list_2(X) when atom(X) -> atom_to_list(X); +thing_to_list_2(X) when list(X) -> X. %Assumed to be a string + +%% flatten_2(List) +%% flatten_2(List, Tail) +%% Flatten a list, adding optional tail. + +flatten_2(List) -> + flatten_2(List, [], []). + +flatten_2(List, Tail) -> + flatten_2(List, [], Tail). + +flatten_2([H|T], Cont, Tail) when list(H) -> + flatten_2(H, [T|Cont], Tail); +flatten_2([H|T], Cont, Tail) -> + [H|flatten_2(T, Cont, Tail)]; +flatten_2([], [H|Cont], Tail) -> + flatten_2(H, Cont, Tail); +flatten_2([], [], Tail) -> + Tail. + +%% flat_length_2(List) _2(undocumented can be rmove later) +%% Calculate the length of a list of lists. + +flat_length_2(List) -> flatlength_2(List). + +%% flatlength_2(List) +%% Calculate the length of a list of lists. + +flatlength_2(List) -> + flatlength_2(List, 0). + +flatlength_2([H|T], L) when list(H) -> + flatlength_2(H, flatlength_2(T, L)); +flatlength_2([H|T], L) -> + flatlength_2(T, L + 1); +flatlength_2([], L) -> L. + +%% keymember_2(Key, Index, [Tuple]) +%% keysearch_2(Key, Index, [Tuple]) +%% keydelete_2(Key, Index, [Tuple]) +%% keyreplace_2(Key, Index, [Tuple], NewTuple) +%% keysort_2(Index, [Tuple]) +%% keymerge_2(Index, [Tuple], [Tuple]) +%% keymap_2(Function, Index, [Tuple]) +%% keymap_2(Function, ExtraArgs, Index, [Tuple]) + +keymember_2(Key, N, [T|Ts]) when element(N, T) == Key -> true; +keymember_2(Key, N, [T|Ts]) -> + keymember_2(Key, N, Ts); +keymember_2(Key, N, []) -> false. + +keysearch_2(Key, N, [H|T]) when element(N, H) == Key -> + {value, H}; +keysearch_2(Key, N, [H|T]) -> + keysearch_2(Key, N, T); +keysearch_2(Key, N, []) -> false. + +keydelete_2(Key, N, [H|T]) when element(N, H) == Key -> T; +keydelete_2(Key, N, [H|T]) -> + [H|keydelete_2(Key, N, T)]; +keydelete_2(Key, N, []) -> []. + +keyreplace_2(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key -> + [New|Tail]; +keyreplace_2(Key, Pos, [H|T], New) -> + [H|keyreplace_2(Key, Pos, T, New)]; +keyreplace_2(Key, Pos, [], New) -> []. + +keysort_2(Index, [X]) -> [X]; +keysort_2(Index, []) -> []; +keysort_2(Index, X) -> split_and_keysort_2(X, [], [], Index). + +split_and_keysort_2([A,B|T], X, Y, Index) -> + split_and_keysort_2(T, [A|X], [B|Y], Index); +split_and_keysort_2([H], X, Y, Index) -> + split_and_keysort_2([], [H|X], Y, Index); +split_and_keysort_2([], X, Y, Index) -> + keymerge_2(Index, keysort_2(Index, X), keysort_2(Index, Y), []). + +keymerge_2(Index, X, Y) -> keymerge_2(Index, X, Y, []). + +keymerge_2(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) -> + keymerge_2(I, T1, [H2|T2], [H1|L]); +keymerge_2(Index, T1, [H2|T2], L) -> + keymerge_2(Index,T1, T2, [H2|L]); +keymerge_2(Index,[H|T], T2, L) -> + keymerge_2(Index,T, T2, [H|L]); +keymerge_2(Index, [], [], L) -> + reverse_2(L). + +keymap_2(Fun, Index, [Tup|Tail]) -> + [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap_2(Fun, Index, Tail)]; +keymap_2( _, _ , []) -> []. + +keymap_2(Fun, ExtraArgs, Index, [Tup|Tail]) -> + [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| + keymap_2(Fun, ExtraArgs, Index, Tail)]; +keymap_2( _, _ , _, []) -> []. + +%% all_2(Predicate, List) +%% any_2(Predicate, List) +%% map_2(Function, List) +%% flatmap_2(Function, List) +%% foldl_2(Function, First, List) +%% foldr_2(Function, Last, List) +%% filter_2(Predicate, List) +%% zF(Function, List) +%% mapfoldl_2(Function, First, List) +%% mapfoldr_2(Function, Last, List) +%% foreach_2(Function, List) +%% takewhile_2(Predicate, List) +%% dropwhile_2(Predicate, List) +%% splitwith_2(Predicate, List) +%% for list programming. Function here is either a 'fun' or a tuple +%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke! +%% +%% N.B. Unless where the functions actually needs it only foreach/2/3, +%% which is meant to be used for its side effects, has a defined order +%% of evaluation. +%% +%% There are also versions with an extra argument, ExtraArgs, which is a +%% list of extra arguments to each call. + +all_2(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> all_2(Pred, Tail); + false -> false + end; +all_2(Pred, []) -> true. + +any_2(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> true; + false -> any_2(Pred, Tail) + end; +any_2(Pred, []) -> false. + +map_2(F, List) -> [ F(E) || E <- List ]. + +flatmap_2(F, [Hd|Tail]) -> + F(Hd) ++ flatmap_2(F, Tail); +flatmap_2(F, []) -> []. + +foldl_2(F, Accu, [Hd|Tail]) -> + foldl_2(F, F(Hd, Accu), Tail); +foldl_2(F, Accu, []) -> Accu. + +foldr_2(F, Accu, [Hd|Tail]) -> + F(Hd, foldr_2(F, Accu, Tail)); +foldr_2(F, Accu, []) -> Accu. + +filter_2(Pred, List) -> [ E || E <- List, Pred(E) ]. + +zF_2(F, [Hd|Tail]) -> + case F(Hd) of + true -> + [Hd|zF_2(F, Tail)]; + {true,Val} -> + [Val|zF_2(F, Tail)]; + false -> + zF_2(F, Tail) + end; +zF_2(F, []) -> []. + +foreach_2(F, [Hd|Tail]) -> + F(Hd), + foreach_2(F, Tail); +foreach_2(F, []) -> ok. + +mapfoldl_2(F, Accu0, [Hd|Tail]) -> + {R,Accu1} = F(Hd, Accu0), + {Rs,Accu2} = mapfoldl_2(F, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl_2(F, Accu, []) -> {[],Accu}. + +mapfoldr_2(F, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr_2(F, Accu0, Tail), + {R,Accu2} = F(Hd, Accu1), + {[R|Rs],Accu2}; +mapfoldr_2(F, Accu, []) -> {[],Accu}. + +takewhile_2(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> [Hd|takewhile_2(Pred, Tail)]; + false -> [] + end; +takewhile_2(Pred, []) -> []. + +dropwhile_2(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> dropwhile_2(Pred, Tail); + false -> [Hd|Tail] + end; +dropwhile_2(Pred, []) -> []. + +splitwith_2(Pred, List) -> splitwith_2(Pred, List, []). + +splitwith_2(Pred, [Hd|Tail], Taken) -> + case Pred(Hd) of + true -> splitwith_2(Pred, Tail, [Hd|Taken]); + false -> {reverse_2(Taken), [Hd|Tail]} + end; +splitwith_2(Pred, [], Taken) -> {reverse_2(Taken),[]}. + +%% Versions of the above functions with extra arguments. + +all_2(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> all_2(Pred, Eas, Tail); + false -> false + end; +all_2(Pred, Eas, []) -> true. + +any_2(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> true; + false -> any_2(Pred, Eas, Tail) + end; +any_2(Pred, Eas, []) -> false. + +map_2(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ]. + +flatmap_2(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]) ++ flatmap_2(F, Eas, Tail); +flatmap_2(F, Eas, []) -> []. + +foldl_2(F, Eas, Accu, [Hd|Tail]) -> + foldl_2(F, Eas, apply(F, [Hd,Accu|Eas]), Tail); +foldl_2(F, Eas, Accu, []) -> Accu. + +foldr_2(F, Eas, Accu, [Hd|Tail]) -> + apply(F, [Hd,foldr_2(F, Eas, Accu, Tail)|Eas]); +foldr_2(F, Eas, Accu, []) -> + Accu. + +filter_2(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ]. + +zF_2(F, Eas, [Hd|Tail]) -> + case apply(F, [Hd|Eas]) of + true -> + [Hd|zF_2(F, Eas, Tail)]; + {true,Val} -> + [Val|zF_2(F, Eas, Tail)]; + false -> + zF_2(F, Eas, Tail) + end; +zF_2(F, Eas, []) -> []. + +foreach_2(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]), + foreach_2(F, Eas, Tail); +foreach_2(F, Eas, []) -> ok. + +mapfoldl_2(F, Eas, Accu0, [Hd|Tail]) -> + {R,Accu1} = apply(F, [Hd,Accu0|Eas]), + {Rs,Accu2} = mapfoldl_2(F, Eas, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl_2(F, Eas, Accu, []) -> {[],Accu}. + +mapfoldr_2(F, Eas, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr_2(F, Eas, Accu0, Tail), + {R,Accu2} = apply(F, [Hd,Accu1|Eas]), + {[R|Rs],Accu2}; +mapfoldr_2(F, Eas, Accu, []) -> {[],Accu}. + +%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with +%% extra arguments as this going to be discontinued. + + + + + +%%% +++++++++++++++++++ +%%% +%%% With "_3" + + + + +%% member_3(X, L) -> _3(true | false) +%% test if X is a member of the list L + +%member_3(X, [X|_]) -> true; +%member_3(X, [_|Y]) -> +% member_3(X, Y); +%member_3(X, []) -> false. + +member_3(X, L) when list(L) -> + case erlang:member(X, L) of + L1 when list(L1) -> + receive after 1 -> ok end, + member_3(X, L1); + Boolean -> + Boolean + end. + +%% append_3(X, Y) appends lists X and Y + +append_3(L1, L2) -> L1 ++ L2. + +%% append_3(L) appends the list of lists L + +append_3([E]) -> E; +append_3([H|T]) -> H ++ append_3(T); +append_3([]) -> []. + +%% subtract_3(List1, List2) subtract elements in List2 form List1. + +subtract_3(L1, L2) -> L1 -- L2. + +%% reverse_3(L) reverse all elements in the list L + +reverse_3(X) -> reverse_3(X, []). + +%reverse_3([H|T], Y) -> +% reverse_3(T, [H|Y]); +%reverse_3([], X) -> X. + +reverse_3(List0, Result0) when list(List0) -> + case erlang:reverse_3(List0, Result0) of + {List, Result} -> + receive after 1 -> ok end, + reverse_3(List, Result); + Result -> + Result + end. + + +%% nth_3(N, L) returns the N`th element of the list L +%% nthtail_3(N, L) returns the N`th tail of the list L + +nth_3(1, [H|T]) -> H; +nth_3(N, [_|T]) when N > 1 -> + nth_3(N - 1, T). + +nthtail_3(1, [H|T]) -> T; +nthtail_3(N, [H|T]) when N > 1 -> + nthtail_3(N - 1, T); +nthtail_3(0, L) when list(L) -> L. + +%% prefix_3(Prefix, List) -> _3(true | false) + +prefix_3([X|PreTail], [X|Tail]) -> + prefix_3(PreTail, Tail); +prefix_3([], List) -> true; +prefix_3(_,_) -> false. + + +%% suffix_3(Suffix, List) -> _3(true | false) + +suffix_3(Suffix, Suffix) -> true; +suffix_3(Suffix, [_|Tail]) -> + suffix_3(Suffix, Tail); +suffix_3(Suffix, []) -> false. + +%% last_3(List) returns the last element in a list. + +last_3([E]) -> E; +last_3([E|Es]) -> + last_3(Es). + +%% seq_3(Min, Max) -> [Min,Min+1, ..., Max] +%% seq_3(Min, Max, Incr) -> [Min,Min+Incr, ..., Max] +%% returns the sequence Min..Max +%% Min <= Max and Min and Max must be integers + +seq_3(Min, Max) when integer(Min), integer(Max), Min =< Max -> + seq_3(Min, Max, 1, []). + +seq_3(Min, Max, Incr) -> + seq_3(Min, Min + ((Max-Min) div Incr) * Incr, Incr, []). + +seq_3(Min, Min, I, L) -> [Min|L]; +seq_3(Min, Max, I, L) -> seq_3(Min, Max-I, I, [Max|L]). + +%% sum_3(L) suns the sum of the elements in L + +sum_3(L) -> sum_3(L, 0). +sum_3([H|T], Sum) -> sum_3(T, Sum + H); +sum_3([], Sum) -> Sum. + +%% duplicate_3(N, X) -> [X,X,X,.....,X] _3(N times) +%% return N copies of X + +duplicate_3(N, X) when integer(N), N >= 0 -> duplicate_3(N, X, []). + +duplicate_3(0, _, L) -> L; +duplicate_3(N, X, L) -> duplicate_3(N-1, X, [X|L]). + + +%% min_3(L) -> returns the minimum element of the list L + +min_3([H|T]) -> min_3(T, H). + +min_3([H|T], Min) when H < Min -> min_3(T, H); +min_3([_|T], Min) -> min_3(T, Min); +min_3([], Min) -> Min. + +%% max_3(L) -> returns the maximum element of the list L + +max_3([H|T]) -> max_3(T, H). + +max_3([H|T], Max) when H > Max -> max_3(T, H); +max_3([_|T], Max) -> max_3(T, Max); +max_3([], Max) -> Max. + +%% sublist_3(List, Start, Length) +%% Returns the sub-list starting at Start of length Length. + +sublist_3(List, S, L) when L >= 0 -> + sublist_3(nthtail_3(S-1, List), L). + +sublist_3([H|T], L) when L > 0 -> + [H|sublist_3(T, L-1)]; +sublist_3(List, L) -> []. + +%% delete_3(Item, List) -> List' +%% Delete the first occurance of Item from the list L. + +delete_3(Item, [Item|Rest]) -> Rest; +delete_3(Item, [H|Rest]) -> + [H|delete_3(Item, Rest)]; +delete_3(Item, []) -> []. + +%% sort_3(L) -> sorts the list L + +sort_3([X]) -> [X]; +sort_3([]) -> []; +sort_3(X) -> split_and_sort_3(X, [], []). + +split_and_sort_3([A,B|T], X, Y) -> + split_and_sort_3(T, [A|X], [B|Y]); +split_and_sort_3([H], X, Y) -> + split_and_sort_3([], [H|X], Y); +split_and_sort_3([], X, Y) -> + merge_3(sort_3(X), sort_3(Y), []). + +%% merge_3(X, Y) -> L +%% merges two sorted lists X and Y + +merge_3(X, Y) -> merge_3(X, Y, []). + +merge_3([H1|T1], [H2|T2], L) when H1 < H2 -> + merge_3(T1, [H2|T2], [H1|L]); +merge_3(T1, [H2|T2], L) -> + merge_3(T1, T2, [H2|L]); +merge_3([H|T], T2, L) -> + merge_3(T, T2, [H|L]); +merge_3([], [], L) -> + reverse_3(L). + +%% concat_3(L) concatinate the list representation of the elements +%% in L - the elements in L can be atoms, integers of strings. +%% Returns a list of characters. + +concat_3(List) -> + flatmap_3(fun thing_to_list/1, List). + +thing_to_list_3(X) when integer(X) -> integer_to_list(X); +thing_to_list_3(X) when float(X) -> float_to_list(X); +thing_to_list_3(X) when atom(X) -> atom_to_list(X); +thing_to_list_3(X) when list(X) -> X. %Assumed to be a string + +%% flatten_3(List) +%% flatten_3(List, Tail) +%% Flatten a list, adding optional tail. + +flatten_3(List) -> + flatten_3(List, [], []). + +flatten_3(List, Tail) -> + flatten_3(List, [], Tail). + +flatten_3([H|T], Cont, Tail) when list(H) -> + flatten_3(H, [T|Cont], Tail); +flatten_3([H|T], Cont, Tail) -> + [H|flatten_3(T, Cont, Tail)]; +flatten_3([], [H|Cont], Tail) -> + flatten_3(H, Cont, Tail); +flatten_3([], [], Tail) -> + Tail. + +%% flat_length_3(List) _3(undocumented can be rmove later) +%% Calculate the length of a list of lists. + +flat_length_3(List) -> flatlength_3(List). + +%% flatlength_3(List) +%% Calculate the length of a list of lists. + +flatlength_3(List) -> + flatlength_3(List, 0). + +flatlength_3([H|T], L) when list(H) -> + flatlength_3(H, flatlength_3(T, L)); +flatlength_3([H|T], L) -> + flatlength_3(T, L + 1); +flatlength_3([], L) -> L. + +%% keymember_3(Key, Index, [Tuple]) +%% keysearch_3(Key, Index, [Tuple]) +%% keydelete_3(Key, Index, [Tuple]) +%% keyreplace_3(Key, Index, [Tuple], NewTuple) +%% keysort_3(Index, [Tuple]) +%% keymerge_3(Index, [Tuple], [Tuple]) +%% keymap_3(Function, Index, [Tuple]) +%% keymap_3(Function, ExtraArgs, Index, [Tuple]) + +keymember_3(Key, N, [T|Ts]) when element(N, T) == Key -> true; +keymember_3(Key, N, [T|Ts]) -> + keymember_3(Key, N, Ts); +keymember_3(Key, N, []) -> false. + +keysearch_3(Key, N, [H|T]) when element(N, H) == Key -> + {value, H}; +keysearch_3(Key, N, [H|T]) -> + keysearch_3(Key, N, T); +keysearch_3(Key, N, []) -> false. + +keydelete_3(Key, N, [H|T]) when element(N, H) == Key -> T; +keydelete_3(Key, N, [H|T]) -> + [H|keydelete_3(Key, N, T)]; +keydelete_3(Key, N, []) -> []. + +keyreplace_3(Key, Pos, [Tup|Tail], New) when element(Pos, Tup) == Key -> + [New|Tail]; +keyreplace_3(Key, Pos, [H|T], New) -> + [H|keyreplace_3(Key, Pos, T, New)]; +keyreplace_3(Key, Pos, [], New) -> []. + +keysort_3(Index, [X]) -> [X]; +keysort_3(Index, []) -> []; +keysort_3(Index, X) -> split_and_keysort_3(X, [], [], Index). + +split_and_keysort_3([A,B|T], X, Y, Index) -> + split_and_keysort_3(T, [A|X], [B|Y], Index); +split_and_keysort_3([H], X, Y, Index) -> + split_and_keysort_3([], [H|X], Y, Index); +split_and_keysort_3([], X, Y, Index) -> + keymerge_3(Index, keysort_3(Index, X), keysort_3(Index, Y), []). + +keymerge_3(Index, X, Y) -> keymerge_3(Index, X, Y, []). + +keymerge_3(I, [H1|T1], [H2|T2], L) when element(I, H1) < element(I, H2) -> + keymerge_3(I, T1, [H2|T2], [H1|L]); +keymerge_3(Index, T1, [H2|T2], L) -> + keymerge_3(Index,T1, T2, [H2|L]); +keymerge_3(Index,[H|T], T2, L) -> + keymerge_3(Index,T, T2, [H|L]); +keymerge_3(Index, [], [], L) -> + reverse_3(L). + +keymap_3(Fun, Index, [Tup|Tail]) -> + [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap_3(Fun, Index, Tail)]; +keymap_3( _, _ , []) -> []. + +keymap_3(Fun, ExtraArgs, Index, [Tup|Tail]) -> + [setelement(Index, Tup, apply(Fun, [element(Index, Tup)|ExtraArgs]))| + keymap_3(Fun, ExtraArgs, Index, Tail)]; +keymap_3( _, _ , _, []) -> []. + +%% all_3(Predicate, List) +%% any_3(Predicate, List) +%% map_3(Function, List) +%% flatmap_3(Function, List) +%% foldl_3(Function, First, List) +%% foldr_3(Function, Last, List) +%% filter_3(Predicate, List) +%% zF(Function, List) +%% mapfoldl_3(Function, First, List) +%% mapfoldr_3(Function, Last, List) +%% foreach_3(Function, List) +%% takewhile_3(Predicate, List) +%% dropwhile_3(Predicate, List) +%% splitwith_3(Predicate, List) +%% for list programming. Function here is either a 'fun' or a tuple +%% {Module,Name} and we use apply/2 to evaluate. The name zf is a joke! +%% +%% N.B. Unless where the functions actually needs it only foreach/2/3, +%% which is meant to be used for its side effects, has a defined order +%% of evaluation. +%% +%% There are also versions with an extra argument, ExtraArgs, which is a +%% list of extra arguments to each call. + +all_3(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> all_3(Pred, Tail); + false -> false + end; +all_3(Pred, []) -> true. + +any_3(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> true; + false -> any_3(Pred, Tail) + end; +any_3(Pred, []) -> false. + +map_3(F, List) -> [ F(E) || E <- List ]. + +flatmap_3(F, [Hd|Tail]) -> + F(Hd) ++ flatmap_3(F, Tail); +flatmap_3(F, []) -> []. + +foldl_3(F, Accu, [Hd|Tail]) -> + foldl_3(F, F(Hd, Accu), Tail); +foldl_3(F, Accu, []) -> Accu. + +foldr_3(F, Accu, [Hd|Tail]) -> + F(Hd, foldr_3(F, Accu, Tail)); +foldr_3(F, Accu, []) -> Accu. + +filter_3(Pred, List) -> [ E || E <- List, Pred(E) ]. + +zF_3(F, [Hd|Tail]) -> + case F(Hd) of + true -> + [Hd|zF_3(F, Tail)]; + {true,Val} -> + [Val|zF_3(F, Tail)]; + false -> + zF_3(F, Tail) + end; +zF_3(F, []) -> []. + +foreach_3(F, [Hd|Tail]) -> + F(Hd), + foreach_3(F, Tail); +foreach_3(F, []) -> ok. + +mapfoldl_3(F, Accu0, [Hd|Tail]) -> + {R,Accu1} = F(Hd, Accu0), + {Rs,Accu2} = mapfoldl_3(F, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl_3(F, Accu, []) -> {[],Accu}. + +mapfoldr_3(F, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr_3(F, Accu0, Tail), + {R,Accu2} = F(Hd, Accu1), + {[R|Rs],Accu2}; +mapfoldr_3(F, Accu, []) -> {[],Accu}. + +takewhile_3(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> [Hd|takewhile_3(Pred, Tail)]; + false -> [] + end; +takewhile_3(Pred, []) -> []. + +dropwhile_3(Pred, [Hd|Tail]) -> + case Pred(Hd) of + true -> dropwhile_3(Pred, Tail); + false -> [Hd|Tail] + end; +dropwhile_3(Pred, []) -> []. + +splitwith_3(Pred, List) -> splitwith_3(Pred, List, []). + +splitwith_3(Pred, [Hd|Tail], Taken) -> + case Pred(Hd) of + true -> splitwith_3(Pred, Tail, [Hd|Taken]); + false -> {reverse_3(Taken), [Hd|Tail]} + end; +splitwith_3(Pred, [], Taken) -> {reverse_3(Taken),[]}. + +%% Versions of the above functions with extra arguments. + +all_3(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> all_3(Pred, Eas, Tail); + false -> false + end; +all_3(Pred, Eas, []) -> true. + +any_3(Pred, Eas, [Hd|Tail]) -> + case apply(Pred, [Hd|Eas]) of + true -> true; + false -> any_3(Pred, Eas, Tail) + end; +any_3(Pred, Eas, []) -> false. + +map_3(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ]. + +flatmap_3(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]) ++ flatmap_3(F, Eas, Tail); +flatmap_3(F, Eas, []) -> []. + +foldl_3(F, Eas, Accu, [Hd|Tail]) -> + foldl_3(F, Eas, apply(F, [Hd,Accu|Eas]), Tail); +foldl_3(F, Eas, Accu, []) -> Accu. + +foldr_3(F, Eas, Accu, [Hd|Tail]) -> + apply(F, [Hd,foldr_3(F, Eas, Accu, Tail)|Eas]); +foldr_3(F, Eas, Accu, []) -> + Accu. + +filter_3(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ]. + +zF_3(F, Eas, [Hd|Tail]) -> + case apply(F, [Hd|Eas]) of + true -> + [Hd|zF(F, Eas, Tail)]; + {true,Val} -> + [Val|zF(F, Eas, Tail)]; + false -> + zF(F, Eas, Tail) + end; +zF_3(F, Eas, []) -> []. + +foreach_3(F, Eas, [Hd|Tail]) -> + apply(F, [Hd|Eas]), + foreach_3(F, Eas, Tail); +foreach_3(F, Eas, []) -> ok. + +mapfoldl_3(F, Eas, Accu0, [Hd|Tail]) -> + {R,Accu1} = apply(F, [Hd,Accu0|Eas]), + {Rs,Accu2} = mapfoldl_3(F, Eas, Accu1, Tail), + {[R|Rs],Accu2}; +mapfoldl_3(F, Eas, Accu, []) -> {[],Accu}. + +mapfoldr_3(F, Eas, Accu0, [Hd|Tail]) -> + {Rs,Accu1} = mapfoldr_3(F, Eas, Accu0, Tail), + {R,Accu2} = apply(F, [Hd,Accu1|Eas]), + {[R|Rs],Accu2}; +mapfoldr_3(F, Eas, Accu, []) -> {[],Accu}. + +%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with +%% extra arguments as this going to be discontinued. + + + + +lots_of_atoms () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms1 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms2 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms3 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms4 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms5 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms6 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms7 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms8 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms9 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms10 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms11 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. + + +lots_of_atoms12 () -> + +Aa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Af = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ag = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ah = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aba = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aca = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ada = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aea = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aga = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aha = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aab = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahb = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aac = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aec = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahc = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aad = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Add = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aed = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahd = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aae = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ace = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ade = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aee = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Age = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahe = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + + +Aaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + + +Aaaaaa= 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahaaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aabaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aebaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahbaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aacaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Accaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aecaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahcaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aadaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Acdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Addaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aedaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Agdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ahdaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aaeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Abeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aceaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Adeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aeeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Afeaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Ageaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg', + +Aheaaa = 'rnevgoirnvire iriej iirejgierjg ioegjrigj oiegj oijetig oijtgej oj oiejg iojetijwokfopkewmf irjgo ergjerifjiugnuignuit euhg uieuignuiergnuienrgueringiun uiegniuerngui iugne uegniuetgniuetgnuientg unegngiuethgiueugnieg'. diff --git a/lib/debugger/test/int_SUITE_data/ordsets1.erl b/lib/debugger/test/int_SUITE_data/ordsets1.erl new file mode 100644 index 0000000000..a01d35eb51 --- /dev/null +++ b/lib/debugger/test/int_SUITE_data/ordsets1.erl @@ -0,0 +1,191 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%% Copyright (C) 1991, Ellemtel Telecommunications Systems Laboratories +%% File : ordsets.erl +%% Author : Robert Virding +%% Purpose : Functions for manipulating sets as ordered lists. + +%% As yet some of these are not very efficiently written. + +-module(ordsets1). + +-export([new_set/0,is_set/1,set_to_list/1,list_to_set/1]). +-export([is_element/2,add_element/2,del_element/2]). +-export([union/2,union/1,intersection/2,intersection/1]). +-export([subtract/2,subset/2]). + +%% new_set() +%% Return a new empty ordered set. + +new_set() -> + []. + +%% is_set(Set) +%% Return 'true' if Set is an ordered set of elements, else 'false'. + +is_set([E|Es]) -> + is_set(Es, E); +is_set([]) -> + true. + +is_set([E2|Es], E1) when E1 < E2 -> + is_set(Es, E2); +is_set([E2|Es], E1) -> + false; +is_set([], E1) -> + true. + +%% set_to_list(OrdSet) +%% Return the elements in OrdSet as a list. + +set_to_list(S) -> + S. + +%% list_to_set(List) +%% Build an ordered set from the elements in List. + +list_to_set([E|Es]) -> + add_element(E, list_to_set(Es)); +list_to_set([]) -> + []. + +%% is_element(Element, OrdSet) +%% Return 'true' if Element is an element of OrdSet, else 'false'. + +is_element(E, [H|Es]) when E < H -> + false; +is_element(E, [H|Es]) when E == H -> + true; +is_element(E, [H|Es]) when E > H -> + is_element(E, Es); +is_element(E, []) -> + false. + +%% add_element(Element, OrdSet) +%% Return OrdSet with Element inserted in it. + +add_element(E, [H|Es]) when E < H -> + [E,H|Es]; +add_element(E, [H|Es]) when E == H -> + [H|Es]; +add_element(E, [H|Es]) when E > H -> + [H|add_element(E, Es)]; +add_element(E, []) -> + [E]. + +%% del_element(Element, OrdSet) +%% Return OrdSet but with Element removed. + +del_element(E, [H|Es]) when E < H -> + [H|Es]; +del_element(E, [H|Es]) when E == H -> + Es; +del_element(E, [H|Es]) when E > H -> + [H|del_element(E, Es)]; +del_element(E, []) -> + []. + +%% union(Set1, Set2) +%% Return the union of Set1 and Set2. + +union([H1|Es1], [H2|Es2]) when H1 < H2 -> + [H1|union(Es1, [H2|Es2])]; +union([H1|Es1], [H2|Es2]) when H1 == H2 -> + [H1|union(Es1, Es2)]; +union([H1|Es1], [H2|Es2]) when H1 > H2 -> + [H2|union([H1|Es1], Es2)]; +union([], Es2) -> + Es2; +union(Es1, []) -> + Es1. + +%% union(OrdSets) +%% Return the union of the list of sets. + +union([S1,S2|Ss]) -> + union1(union(S1,S2), Ss); +union([S]) -> + S; +union([]) -> + []. + +union1(S1, [S2|Ss]) -> + union1(union(S1, S2), Ss); +union1(S1, []) -> + S1. + +%% intersection(Set1, Set2) +%% Return the intersection of Set1 and Set2. + +intersection([H1|Es1], [H2|Es2]) when H1 < H2 -> + intersection(Es1, [H2|Es2]); +intersection([H1|Es1], [H2|Es2]) when H1 == H2 -> + [H1|intersection(Es1, Es2)]; +intersection([H1|Es1], [H2|Es2]) when H1 > H2 -> + intersection([H1|Es1], Es2); +intersection([], Es2) -> + []; +intersection(Es1, []) -> + []. + +%% intersection(OrdSets) +%% Return the intersection of the list of sets. + +intersection([S1,S2|Ss]) -> + intersection1(intersection(S1,S2), Ss); +intersection([S]) -> + S; +intersection([]) -> + []. + +intersection1(S1, [S2|Ss]) -> + intersection1(intersection(S1, S2), Ss); +intersection1(S1, []) -> + S1. + +%% subtract(Set1, Set2) +%% Return all and only the elements of Set1 which are not also in Set2. + +subtract([H1|Es1], [H2|Es2]) when H1 < H2 -> + [H1|subtract(Es1, [H2|Es2])]; +subtract([H1|Es1], [H2|Es2]) when H1 == H2 -> + subtract(Es1, Es2); +subtract([H1|Es1], [H2|Es2]) when H1 > H2 -> + subtract([H1|Es1], Es2); +subtract([], Es2) -> + []; +subtract(Es1, []) -> + Es1. + +%% subset(Set1, Set2) +%% Return 'true' when every element of Set1 is also a member of Set2, +%% else 'false'. + +subset([H1|Es1], [H2|Es2]) when H1 < H2 -> %H1 not in Set2 + false; +subset([H1|Es1], [H2|Es2]) when H1 == H2 -> + subset(Es1, Es2); +subset([H1|Es1], [H2|Es2]) when H1 > H2 -> + subset([H1|Es1], Es2); +subset([], Es2) -> + true; +subset(Es1, []) -> + false. diff --git a/lib/debugger/test/int_SUITE_data/test.erl b/lib/debugger/test/int_SUITE_data/test.erl new file mode 100644 index 0000000000..679b266380 --- /dev/null +++ b/lib/debugger/test/int_SUITE_data/test.erl @@ -0,0 +1,152 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% + +-module(test). + +%%-compile(export_all). +-export([test1/0, + test2/0, + test3/0, + test4/0, + test5/0, + test6/1, + test7/0, + test8/1, + test9/0, + test10/0, + test11/0 + ]). + + +-export([test9_server/1]). + + +test1() -> + R1 = lists1:reverse("retep"), + R2 = ordsets1:list_to_set([b,c,a,2,4,1]), + R3 = lists1:reverse("nilo"), + {R1,R2, R3}. + +test2() -> + R1 = spawn(lists1,reverse,["retep"]), + R2 = spawn(ordsets1,list_to_set,[[b,c,a,2,4,1]]), + R3 = spawn(lists1,reverse,["nilo"]), + {R1,R2, R3}. + + +test3() -> + A = a, + Pid = spawn(?MODULE, test1,[]), + B = b, + {A, B, Pid}. + +test4() -> + Pid = spawn(?MODULE, test1,[]), + A = a, + B = b, + {A, B, Pid}. +test5() -> + L1 = [a,b,c], + L = length(L1), + A = a, + B = b, + {A, B, L, L1}. + + + +test6(0) -> + ok; +test6(N) when N>0 -> + spawn(lists1,reverse,["adolfiparisrorsirapifloda"]), + test6(N-1). + + +test7() -> + CurDirReturn = file:get_cwd(), + {ok, CurDir} = CurDirReturn, + DirListReturn = file:list_dir(CurDir), + {ok, DirList} = DirListReturn, + io:format("~w~n",[DirList]). + + +test8(List) -> + %% foo + %%bar + %% foo + %%bar + %% foo + %%bar + %% foo + %%bar + + L2 = [gamma|List], + {L2, List}. + +test9() -> + S1 = spawn(?MODULE, test9_server,[self()]), + S2 = spawn(?MODULE, test9_server,[bongo]), + S3 = spawn(?MODULE, test9_server,[42]), + + test9_loop(S1,S2,S3). + +test9_loop(S1,S2,S3) -> + receive + {S1, hej} -> + io:format("S1 ~n"), + test9_loop(S1,S2,S3); + {S2, hej} -> + io:format("S2 ~n"), + test9_loop(S1,S2,S3); + {S3, hej} -> + io:format("S3 ~n"), + test9_loop(S1,S2,S3) + end. + + +test9_server(Pid) -> + io:format("started server: ~p~n",[Pid]), + test9_server1(Pid). + +test9_server1(Pid) -> + Pad = {pad, Pid}, + test9_server2(Pad). + +test9_server2(Pad) -> + {pad, Pid} = Pad, + Pid ! {self(), hej}. + + + + + +test10() -> + receive + X -> + done + after 20000 -> + timeout + end. + +test11() -> + receive + X -> + done + end. diff --git a/lib/debugger/test/int_SUITE_data/test1.erl b/lib/debugger/test/int_SUITE_data/test1.erl new file mode 100644 index 0000000000..a93416cbac --- /dev/null +++ b/lib/debugger/test/int_SUITE_data/test1.erl @@ -0,0 +1,34 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(test1). + +-compile(export_all). + + +foo() -> + A = [1,2,3], + B = [a,b,c], + C = [d,e,f], + D = my_lists:append(A,B), + E = my_lists:append(D,C), + F = [1], + G = my_lists:append(E,F), + {A,B,C,D,E,F,G}. diff --git a/lib/debugger/test/int_break_SUITE.erl b/lib/debugger/test/int_break_SUITE.erl new file mode 100644 index 0000000000..b7b3c5598a --- /dev/null +++ b/lib/debugger/test/int_break_SUITE.erl @@ -0,0 +1,92 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(int_break_SUITE). + +%% Test break points. + +-include("test_server.hrl"). + +-export([all/1,init_per_testcase/2,fin_per_testcase/2, + basic/1,cleanup/1]). + +-export([auto_attach/1]). + +all(suite) -> + [basic,cleanup]. + +init_per_testcase(_Case, Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line Mod = ordsets1, + ?line {module,Mod} = int:i(filename:join(DataDir, Mod)), + ?line ok = io:format("Interpreted modules: ~p", [int:interpreted()]), + ?line Dog = test_server:timetrap(?t:minutes(0.5)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + ?line ok = io:format("Interpreted modules: ~p", [int:interpreted()]), + ?line Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +basic(doc) -> "Tests setting a few break points."; +basic(suite) -> []; +basic(Config) when list(Config) -> + ?line int:auto_attach([init], {?MODULE,auto_attach}), + ?line S1 = [] = ordsets1:new_set(), + ?line ok = i:ib(ordsets1, 86), + ?line S2 = [xxx] = ordsets1:add_element(xxx, S1), + ?line S3 = [xxx,y] = ordsets1:add_element(y, S2), + ?line ok = i:ib(ordsets1, union, 2), + ?line [xxx,y,z] = ordsets1:union(S3, [z]), + ok. + +cleanup(doc) -> "Make sure that the auto-attach flag is turned off."; +cleanup(suite) -> []; +cleanup(Config) when list(Config) -> + ?line int:auto_attach(false), + ok. + +auto_attach(Pid) -> + {ok, Meta} = int:attached(Pid), + io:format("Pid = ~p; Meta = ~p", [Pid,Meta]), + link(Meta), + attach_loop(Pid, Meta). + +attach_loop(Pid, Meta) -> + receive + Msg -> + io:format("attached: ~p", [Msg]), + attach_cmd(Msg, Pid, Meta), + attach_loop(Pid, Meta) + end. + +attach_cmd({Meta,{break_at,ordsets1,36,2}}, _Pid, Meta) -> + int:meta(Meta, continue); +attach_cmd({Meta,{break_at,ordsets1,87,_}}, _Pid, Meta) -> + int:meta(Meta, continue); +attach_cmd({Meta,{break_at,ordsets1,89,_}}, _Pid, Meta) -> + int:meta(Meta, continue); +attach_cmd({Meta,{break_at,ordsets1,Line,_}}, _Pid, Meta) when 107 =< Line, Line =< 115 -> + int:meta(Meta, finish); +attach_cmd({Meta,{break_at,_Mod,_Line,_Other}}=Cmd, _Pid, Meta) -> + io:format("attached: no action for ~p", [Cmd]); +attach_cmd(_, _Pid, _Meta) -> + ok. diff --git a/lib/debugger/test/int_break_SUITE_data/Makefile.src b/lib/debugger/test/int_break_SUITE_data/Makefile.src new file mode 100644 index 0000000000..0d1ee35a67 --- /dev/null +++ b/lib/debugger/test/int_break_SUITE_data/Makefile.src @@ -0,0 +1,25 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2000-2010. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# + +EFLAGS=+debug_info + +all: ordsets1.@EMULATOR@ + +ordsets1.@EMULATOR@: ordsets1.erl + erlc $(EFLAGS) ordsets1.erl diff --git a/lib/debugger/test/int_break_SUITE_data/ordsets1.erl b/lib/debugger/test/int_break_SUITE_data/ordsets1.erl new file mode 100644 index 0000000000..6300c6097c --- /dev/null +++ b/lib/debugger/test/int_break_SUITE_data/ordsets1.erl @@ -0,0 +1,188 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%% Purpose : Functions for manipulating sets as ordered lists. + +%% As yet some of these are not very efficiently written. + +-module(ordsets1). + +-export([new_set/0,is_set/1,set_to_list/1,list_to_set/1]). +-export([is_element/2,add_element/2,del_element/2]). +-export([union/2,union/1,intersection/2,intersection/1]). +-export([subtract/2,subset/2]). + +%% new_set() +%% Return a new empty ordered set. + +new_set() -> + []. + +%% is_set(Set) +%% Return 'true' if Set is an ordered set of elements, else 'false'. + +is_set([E|Es]) -> + is_set(Es, E); +is_set([]) -> + true. + +is_set([E2|Es], E1) when E1 < E2 -> + is_set(Es, E2); +is_set([E2|Es], E1) -> + false; +is_set([], E1) -> + true. + +%% set_to_list(OrdSet) +%% Return the elements in OrdSet as a list. + +set_to_list(S) -> + S. + +%% list_to_set(List) +%% Build an ordered set from the elements in List. + +list_to_set([E|Es]) -> + add_element(E, list_to_set(Es)); +list_to_set([]) -> + []. + +%% is_element(Element, OrdSet) +%% Return 'true' if Element is an element of OrdSet, else 'false'. + +is_element(E, [H|Es]) when E < H -> + false; +is_element(E, [H|Es]) when E == H -> + true; +is_element(E, [H|Es]) when E > H -> + is_element(E, Es); +is_element(E, []) -> + false. + +%% add_element(Element, OrdSet) +%% Return OrdSet with Element inserted in it. + +add_element(E, [H|_]=Es) when E < H -> + [E|Es]; +add_element(E, [H|_]=Es) when E == H -> + Es; +add_element(E, [H|Es]) when E > H -> + [H|add_element(E, Es)]; +add_element(E, []) -> + [E]. + +%% del_element(Element, OrdSet) +%% Return OrdSet but with Element removed. + +del_element(E, [H|_]=Es) when E < H -> + Es; +del_element(E, [H|Es]) when E == H -> + Es; +del_element(E, [H|Es]) when E > H -> + [H|del_element(E, Es)]; +del_element(E, []) -> + []. + +%% union(Set1, Set2) +%% Return the union of Set1 and Set2. + +union([H1|Es1], [H2|_]=Es2) when H1 < H2 -> + [H1|union(Es1, Es2)]; +union([H1|Es1], [H2|Es2]) when H1 == H2 -> + [H1|union(Es1, Es2)]; +union([H1|_]=Es1, [H2|Es2]) when H1 > H2 -> + [H2|union(Es1, Es2)]; +union([], Es2) -> + Es2; +union(Es1, []) -> + Es1. + +%% union(OrdSets) +%% Return the union of the list of sets. + +union([S1,S2|Ss]) -> + union1(union(S1,S2), Ss); +union([S]) -> + S; +union([]) -> + []. + +union1(S1, [S2|Ss]) -> + union1(union(S1, S2), Ss); +union1(S1, []) -> + S1. + +%% intersection(Set1, Set2) +%% Return the intersection of Set1 and Set2. + +intersection([H1|Es1], [H2|_]=Es2) when H1 < H2 -> + intersection(Es1, Es2); +intersection([H1|Es1], [H2|Es2]) when H1 == H2 -> + [H1|intersection(Es1, Es2)]; +intersection([H1|_]=Es1, [H2|Es2]) when H1 > H2 -> + intersection(Es1, Es2); +intersection([], Es2) -> + []; +intersection(Es1, []) -> + []. + +%% intersection(OrdSets) +%% Return the intersection of the list of sets. + +intersection([S1,S2|Ss]) -> + intersection1(intersection(S1,S2), Ss); +intersection([S]) -> + S; +intersection([]) -> + []. + +intersection1(S1, [S2|Ss]) -> + intersection1(intersection(S1, S2), Ss); +intersection1(S1, []) -> + S1. + +%% subtract(Set1, Set2) +%% Return all and only the elements of Set1 which are not also in Set2. + +subtract([H1|Es1], [H2|_]=Es2) when H1 < H2 -> + [H1|subtract(Es1, Es2)]; +subtract([H1|Es1], [H2|Es2]) when H1 == H2 -> + subtract(Es1, Es2); +subtract([H1|_]=Es1, [H2|Es2]) when H1 > H2 -> + subtract(Es1, Es2); +subtract([], Es2) -> + []; +subtract(Es1, []) -> + Es1. + +%% subset(Set1, Set2) +%% Return 'true' when every element of Set1 is also a member of Set2, +%% else 'false'. + +subset([H1|Es1], [H2|Es2]) when H1 < H2 -> %H1 not in Set2 + false; +subset([H1|Es1], [H2|Es2]) when H1 == H2 -> + subset(Es1, Es2); +subset([H1|Es1], [H2|Es2]) when H1 > H2 -> + subset([H1|Es1], Es2); +subset([], Es2) -> + true; +subset(Es1, []) -> + false. diff --git a/lib/debugger/test/int_eval_SUITE.erl b/lib/debugger/test/int_eval_SUITE.erl new file mode 100644 index 0000000000..19b006e750 --- /dev/null +++ b/lib/debugger/test/int_eval_SUITE.erl @@ -0,0 +1,277 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(int_eval_SUITE). + +%% Purpose: Deeper test of the evaluator. + +-export([all/1,init_per_testcase/2, fin_per_testcase/2, + bifs_outside_erlang/1, spawning/1, applying/1, + catch_and_throw/1, external_call/1, test_module_info/1, + apply_interpreted_fun/1, apply_uninterpreted_fun/1, + interpreted_exit/1, otp_8310/1]). + +%% Helpers. +-export([applier/3]). + +-define(IM, my_int_eval_module). + +-include("test_server.hrl"). + +all(suite) -> + [bifs_outside_erlang,spawning,applying,catch_and_throw, + external_call,test_module_info, + apply_interpreted_fun,apply_uninterpreted_fun, + interpreted_exit, otp_8310]. + +init_per_testcase(_Case, Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {module,?IM} = int:i(filename:join(DataDir, ?IM)), + ?line ok = io:format("Interpreted modules: ~p",[int:interpreted()]), + {ok, Dog} = timer:apply_after(timer:minutes(1), + erlang, exit, [self(), kill]), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + ok = io:format("Interpreted modules: ~p", [int:interpreted()]), + Dog = ?config(watchdog, Config), + timer:cancel(Dog), + ok. + +bifs_outside_erlang(doc) -> + "Test that BIFs outside the erlang module are correctly evaluated."; +bifs_outside_erlang(suite) -> + []; +bifs_outside_erlang(Config) when is_list(Config) -> + Fun = fun() -> + Id = ?IM:ets_new(), + Self = self(), + ok = io:format("Self: ~p", [Self]), + Info = ets:info(Id), + {owner,Self} = lists:nth(2, Info), + %% Was + %% {owner,Self} = element(2, Info), + %% in R10B. + ?IM:ets_delete(Id), + ok + end, + ?line ok = spawn_eval(Fun), + ok. + +spawning(doc) -> + "Try evalutate spawn_link/3."; +spawning(suite) -> + []; +spawning(Config) when is_list(Config) -> + ?line ok = spawn_eval(fun() -> ?IM:spawn_test() end). + +applying(doc) -> + "Try various sorts of applies."; +applying(suite) -> + []; +applying(Config) when is_list(Config) -> + Fun = fun({number,X}, {number,Y}) -> X+Y end, + ?line ok = spawn_eval(fun() -> ?IM:apply_test(Fun) end). + +catch_and_throw(doc) -> + "Test catch and throw/1."; +catch_and_throw(suite) -> + []; +catch_and_throw(Config) when is_list(Config) -> + {a,ball} = spawn_eval(fun() -> ok = ?IM:catch_a_ball(), + catch ?IM:throw_a_ball() end), + + %% Throw and catch without any extra outer catch. + + ?line process_flag(trap_exit, true), + ?line Pid1 = spawn_link(fun() -> exit(?IM:catch_a_ball()) end), + receive + {'EXIT',Pid1,ok} -> ok; + {'EXIT',Pid1,Bad1} -> ?line ?t:fail({bad_message,Bad1}) + after 5000 -> + ?line ?t:fail(timeout) + end, + + + %% Throw without catch. + + ?line Pid2 = spawn_link(fun() -> ?IM:throw_a_ball() end), + receive + {'EXIT',Pid2,{{nocatch,{a,ball}},[_|_]}} -> ok; + {'EXIT',Pid2,Bad2} -> ?line ?t:fail({bad_message,Bad2}) + after 5000 -> + ?line ?t:fail(timeout) + end, + + ?line ok = ?IM:more_catch(fun(_) -> ?IM:exit_me() end), + ?line ok = ?IM:more_catch(fun(_) -> exit({unint, exit}) end), + ?line {a, ball} = ?IM:more_catch(fun(_) -> ?IM:throw_a_ball() end), + ?line {b, ball} = ?IM:more_catch(fun(_) -> throw({b,ball}) end), + + ExitInt = {'EXIT',{int,exit}}, + ExitU = {'EXIT',{unint,exit}}, + + ?line ExitInt = (catch ?IM:more_nocatch(fun(_) -> ?IM:exit_me() end)), + ?line ExitU = (catch ?IM:more_nocatch(fun(_) -> exit({unint, exit}) end)), + ?line {a, ball} = (catch {error, ?IM:more_nocatch(fun(_) -> ?IM:throw_a_ball() end)}), + ?line {b, ball} = (catch {error, ?IM:more_nocatch(fun(_) -> throw({b,ball}) end)}), + ok. + +external_call(doc) -> + "Test external calls."; +external_call(suite) -> + []; +external_call(Config) when is_list(Config) -> + ?line ok = spawn_eval(fun() -> ?IM:external_call_test({some,stupid,data}) end). + +test_module_info(doc) -> + "Test the module_info/0,1 functions."; +test_module_info(suite) -> + []; +test_module_info(Config) when is_list(Config) -> + ?line ModInfo = ?IM:module_info(), + ?line {value,{exports,Exp}} = lists:keysearch(exports, 1, ModInfo), + ?line {value,{attributes,Attr}} = lists:keysearch(attributes, 1, ModInfo), + ?line Exp = ?IM:module_info(exports), + ?line Attr = ?IM:module_info(attributes), + ?line {value,{stupid_attribute,[{a,b}]}} = + lists:keysearch(stupid_attribute, 1, Attr), + + %% Check exports using a list comprehension in the module itself. + + ?line ok = ?IM:check_exports(Exp), + + %% Call module_info/0,1 from the module itself. + + ?line ok = ?IM:check_module_info(ModInfo, Exp), + + ok. + +apply_interpreted_fun(doc) -> + "Apply a fun defined in interpreted code."; +apply_interpreted_fun(suite) -> []; +apply_interpreted_fun(Config) when is_list(Config) -> + + %% Called from uninterpreted code + ?line F1 = spawn_eval(fun() -> ?IM:give_me_a_fun_0() end), + ?line perfectly_alright = spawn_eval(fun() -> F1() end), + ?line ATerm = {a,term}, + ?line F2 = spawn_eval(fun() -> ?IM:give_me_a_fun_0(ATerm) end), + ?line {ok,ATerm} = spawn_eval(fun() -> F2() end), + + %% Called from uninterpreted code, badarity + ?line {'EXIT',{{badarity,{F1,[snape]}},[{?MODULE,_,_}|_]}} = + spawn_eval(fun() -> F1(snape) end), + + %% Called from uninterpreted code, error in fun + ?line F3 = spawn_eval(fun() -> ?IM:give_me_a_bad_fun() end), + ?line {'EXIT',{snape,[{?IM,_FunName,_}|_]}} = + spawn_eval(fun() -> F3(snape) end), + + %% Called from within interpreted code + ?line perfectly_alright = spawn_eval(fun() -> ?IM:do_apply(F1) end), + + %% Called from within interpreted code, badarity + ?line {'EXIT',{{badarity,{F1,[snape]}},[{?IM,do_apply,_}|_]}} = + spawn_eval(fun() -> ?IM:do_apply(F1, snape) end), + + %% Called from within interpreted code, error in fun + ?line {'EXIT',{snape,[{?IM,_FunName,_}|_]}} = + spawn_eval(fun() -> ?IM:do_apply(F3, snape) end), + + %% Try some more complex funs. + ?line F4 = ?IM:give_me_a_fun_1(14, 42), + ?line {false,yes,yeah,false} = + F4({{1,nope},{14,yes},{42,yeah},{100,forget_it}}), + ?line [this_is_ok,me_too] = + F4([{-24,no_way},{15,this_is_ok},{1333,forget_me},{37,me_too}]), + + %% OTP-5837 + %% Try fun with guard containing variable bound in environment + ?line [yes,no,no,no] = ?IM:otp_5837(1), + + ok. + +apply_uninterpreted_fun(doc) -> + "Apply a fun defined outside interpreted code."; +apply_uninterpreted_fun(suite) -> []; +apply_uninterpreted_fun(Config) when is_list(Config) -> + + ?line F1 = fun(snape) -> + erlang:error(snape); + (_Arg) -> + perfectly_alright + end, + + %% Ok + ?line perfectly_alright = + spawn_eval(fun() -> ?IM:do_apply(F1, any_arg) end), + + %% Badarity (evaluated in dbg_debugged, which calls erlang:apply/2) + ?line {'EXIT',{{badarity,{F1,[]}},[{erlang,apply,_}|_]}} = + spawn_eval(fun() -> ?IM:do_apply(F1) end), + + %% Error in fun + ?line {'EXIT',{snape,[{?MODULE,_FunName,_}|_]}} = + spawn_eval(fun() -> ?IM:do_apply(F1, snape) end), + + ok. + +%% +%% Try executing an interpreted exit/1 call. +%% + +interpreted_exit(Config) when is_list(Config) -> + ?line process_flag(trap_exit, true), + ?line Reason = make_ref(), + ?line Pid = spawn_link(fun() -> ?IM:please_call_exit(Reason) end), + ?line receive + {'EXIT',Pid,Reason} -> + ok; + {'EXIT',Pid,BadReason} -> + ?line ?t:fail({bad_message,BadReason}) + after 10000 -> + ?line ?t:fail(timeout) + end, + ok. + +otp_8310(doc) -> + "OTP-8310. Bugfixes lc/bc and andalso/orelse."; +otp_8310(Config) when is_list(Config) -> + ?line ok = ?IM:otp_8310(), + ok. + +applier(M, F, A) -> + Res = apply(M, F, A), + io:format("~p:~p(~p) => ~p\n", [M,F,A,Res]), + Res. + +%% +%% Evaluate in another process, to prevent the test_case process to become +%% interpreted. +%% + +spawn_eval(Fun) -> + Self = self(), + spawn_link(fun() -> Self ! (catch Fun()) end), + receive + Result -> + Result + end. diff --git a/lib/debugger/test/int_eval_SUITE_data/Makefile.src b/lib/debugger/test/int_eval_SUITE_data/Makefile.src new file mode 100644 index 0000000000..28a1432157 --- /dev/null +++ b/lib/debugger/test/int_eval_SUITE_data/Makefile.src @@ -0,0 +1,26 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2000-2010. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# + + +EFLAGS=+debug_info + +all: my_int_eval_module.@EMULATOR@ + +my_int_eval_module.@EMULATOR@: my_int_eval_module.erl + erlc $(EFLAGS) my_int_eval_module.erl diff --git a/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl b/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl new file mode 100644 index 0000000000..997ee6e17d --- /dev/null +++ b/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl @@ -0,0 +1,245 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(my_int_eval_module). +-stupid_attribute({a,b}). + +-export([ets_new/0,ets_delete/1,spawn_test/0,apply_test/1,external_call_test/1]). +-export([check_exports/1,check_module_info/2]). +-export([give_me_a_fun_0/0,give_me_a_fun_0/1,give_me_a_fun_1/2, + give_me_a_bad_fun/0, do_apply/1, do_apply/2]). +-export([please_call_exit/1,i_will_do_the_exit/1]). +-export([more_catch/1,more_nocatch/1,exit_me/0]). +-export([f/1, f_try/1, f_catch/1]). +-export([otp_5837/1, otp_8310/0]). + +%% Internal exports. +-export([echo/2,my_subtract/2,catch_a_ball/0,throw_a_ball/0]). +-export([i_am_exported/1]). + +-import(lists, [member/2]). + +-define(line,put(test_server_loc,{?MODULE,?LINE}),). +-define(t,test_server). +-define(m,test_server:match). +-define(config,test_server:lookup_config). + +ets_new() -> + Id = ets:new(my_int_eval_table, [private]), + Id. + +ets_delete(Tab) -> + ets:delete(Tab). + +%% Spawning. + +spawn_test() -> + Term = {a,tuple}, + Pid = spawn_link(?MODULE, echo, [self(),Term]), + receive + {result,Pid,Term} -> ok; + Other -> {bad_response,Other} + after 5000 -> + timeout + end. + +echo(Parent, Term) -> + Parent ! {result,self(),Term}. + +%% Applying. + +apply_test(Fun) -> + 42 = Fun(number(2), number(40)), + 12 = apply(Fun, [number(7),number(5)]), + + Mod = module(), + Func = func(), + [a] = Mod:my_subtract(same([a,b,c]), same([b,c])), + [a,b] = Mod:Func(same([a,b,c]), same([c])), + [a,b,d] = ?MODULE:Func(same([a,b,c,d]), same([c])), + [d,e] = apply(Mod, Func, [same([d,e,f]), same([f])]), + [3] = apply(?MODULE, Func, [same([3,4]),same([4])]), + + %% This is obsolete, but it should work anyway. + HomeMadeFun = {?MODULE,my_subtract}, + [a] = HomeMadeFun(same([a,x,c]), same([x,c])), + [x] = apply(HomeMadeFun, [[x,y],[y,z]]), + + ok. + +number(X) -> {number,X}. +module() -> ?MODULE. +func() -> my_subtract. +same(X) -> X. + +my_subtract(X, Y) -> X -- Y. + +%% Catch and throw. + +catch_a_ball() -> + {a,ball} = (catch throw_a_ball()), + ok. + +throw_a_ball() -> + throw({a,ball}), + not_ok. + +exit_me() -> + exit({int,exit}). + +more_catch(Fun) -> + case catch lists:filter(Fun, [a]) of + {'EXIT', {_, exit}} -> + ok; + Else -> Else + end. + +more_nocatch(Fun) -> + lists:filter(Fun, [a]). + +%% External calls. + +external_call_test(Data) -> + {'EXIT',{undef,[{?MODULE,not_exported,[42,Data]}|_]}} = + (catch ?MODULE:not_exported(42, Data)), + {yes,Data} = i_am_exported(Data), + {yes,Data} = ?MODULE:i_am_exported(Data), + + %% Excercise the function cache in the interpreter. + + {ok,Data,[a,b]} = not_exported(Data, [a,b]), + {yes,Data} = i_am_exported(Data), + {ok,Data,[a,b]} = not_exported(Data, [a,b]), + {'EXIT',{undef,[{?MODULE,not_exported,[7,Data]}|_]}} = + (catch ?MODULE:not_exported(7, Data)), + {yes,Data} = ?MODULE:i_am_exported(Data), + ok. + +not_exported(N, D) -> + {ok,N,D}. + +i_am_exported(D) -> + {yes,D}. + +%% The module_info/0,1 functions and list comprehensions (funs). + +check_exports(Exp) -> + %% Check the structure of the export list and that there are more + %% than 4 elements. + + Exp = [{F,A} || {F,A} <- Exp, erlang:is_atom(F), erlang:is_integer(A)], + case length(Exp) of + Len when Len > 4 -> ok + end. + +check_module_info(ModInfo, Exports) -> + ModInfo = module_info(), + Exports = module_info(exports), + ok. + +%% Testcase apply_interpreted_fun/1. + +give_me_a_fun_0() -> + fun() -> perfectly_alright end. + +give_me_a_fun_0(Term) -> + fun() -> {ok,Term} end. + +give_me_a_fun_1(Min, Max) -> + Seq = lists:seq(Min, Max), + fun (L) when list(L) -> + [Info || {Key,Info} <- L, lists:member(Key, Seq)]; + (T) when tuple(T) -> + L = tuple_to_list(T), + F = fun({Key,Info}) -> + case lists:member(Key, Seq) of + true -> Info; + false -> false + end + end, + list_to_tuple(lists:map(F, L)) + end. + +give_me_a_bad_fun() -> + fun(Arg) -> erlang:error(Arg) end. + +do_apply(Fun) -> + Fun(). +do_apply(Fun, Arg) -> + Fun(Arg). + + +please_call_exit(Reason) -> + put(asked_to_call_exit, Reason), + put(will_call_my_good_friend, ''), + Res = int_eval_SUITE:applier(?MODULE, i_will_do_the_exit, [Reason]), + + %% We don't want a tail-recursive call above. + io:format("Returned from exit/1 -- how strange\n"). + +i_will_do_the_exit(Reason) -> + exit(Reason). + +f(Arg) -> + g(Arg). + +f_try(Arg) -> + try g(Arg) + catch + Class:Reason -> + {Class, Reason} + end. + +f_catch(Arg) -> + catch g(Arg). + +g({error, Reason}) -> + erlang:error(Reason); +g({exit, Reason}) -> + erlang:exit(Reason); +g({throw, Reason}) -> + erlang:throw(Reason); +g(Value) -> + Value. + +otp_5837(N) -> + n(N). + +n(N) -> + lists:map(fun(X) when N==X -> + yes; + (_) -> + no + end, + [1,2,3,4]). + +otp_8310() -> + a = if (false orelse a) =:= a -> a; true -> b end, + F1 = fun() -> a end, + {'EXIT',{{bad_filter,a},_}} = + (catch {a, [X || X <- [1,2,3], _ = F1()]}), + F2 = fun() -> << 3:8 >> end, + {'EXIT',{{bad_filter,<<3>>},_}} = + (catch {a, << << X >> || << X >> <= << 7:8 >>,_ = F2() >>}), + {'EXIT',{{bad_generator,a},_}} = + (catch {a, [X || X <- a]}), + {'EXIT',{{bad_generator,b},_}} = + (catch {a, << <<X>> || << X >> <= b >>}), + ok. diff --git a/lib/debugger/test/lc_SUITE.erl b/lib/debugger/test/lc_SUITE.erl new file mode 100644 index 0000000000..a22a689ec8 --- /dev/null +++ b/lib/debugger/test/lc_SUITE.erl @@ -0,0 +1,74 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(lc_SUITE). + +-author('[email protected]'). +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + basic/1]). + +-include("test_server.hrl"). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [basic]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +basic(Config) when list(Config) -> + ?line L0 = lists:seq(1, 10), + ?line L1 = my_map(fun(X) -> {x,X} end, L0), + ?line L1 = [{x,X} || X <- L0], + ?line L0 = my_map(fun({x,X}) -> X end, L1), + ?line [1,2,3,4,5] = [X || X <- L0, X < 6], + ?line [4,5,6] = [X || X <- L0, X > 3, X < 7], + ?line [] = [X || X <- L0, X > 32, X < 7], + ?line [1,3,5,7,9] = [X || X <- L0, odd(X)], + + %% Error cases. + ?line [] = [X || X <- L1, X+1 < 2], + ?line [] = [{xx,X} || X <- L0, element(2, X) == no_no_no], + ?line {'EXIT',_} = (catch [X || X <- L1, odd(X)]), + + ok. + +my_map(F, L) -> + [F(X) || X <- L]. + +odd(X) -> + X rem 2 == 1. diff --git a/lib/debugger/test/record_SUITE.erl b/lib/debugger/test/record_SUITE.erl new file mode 100644 index 0000000000..06fd01555e --- /dev/null +++ b/lib/debugger/test/record_SUITE.erl @@ -0,0 +1,252 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%%% Purpose : Test records. + +-module(record_SUITE). + +-include("test_server.hrl"). + +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + errors/1,record_test/1,eval_once/1]). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [errors,record_test,eval_once]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +-record(foo, {a,b,c,d}). +-record(bar, {a,b,c,d}). +-record(barf, {a,b,c,d,e}). + +errors(Config) when is_list(Config) -> + Foo = #foo{a=1,b=2,c=3,d=4}, + ?line #foo{a=19,b=42,c=3,d=4} = update_foo(Foo, 19, 42), + + ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19)), + ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19, 35)), + ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19, 35, 17)), + ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19, 35, 17, 42)), + + ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19)), + ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19, 35)), + ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19, 35, 17)), + ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19, 35, 17, 42)), + ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19, + 35, 17, 42, -2)), + + ok. + +update_foo(#foo{}=R, A, B) -> + R#foo{a=A,b=B}. + +update_foo_bar(#foo{}=R, A) -> + R#bar{a=A}. + +update_foo_bar(#foo{}=R, A, _B) -> + R#bar{a=A,b=A}. + +update_foo_bar(#foo{}=R, A, _B, C) -> + R#bar{a=A,b=A,c=C}. + +update_foo_bar(#foo{}=R, A, _B, C, D) -> + R#bar{a=A,b=A,c=C,d=D}. + +update_foo_barf(#foo{}=R, A) -> + R#barf{a=A}. + +update_foo_barf(#foo{}=R, A, _B) -> + R#barf{a=A,b=A}. + +update_foo_barf(#foo{}=R, A, _B, C) -> + R#barf{a=A,b=A,c=C}. + +update_foo_barf(#foo{}=R, A, _B, C, D) -> + R#barf{a=A,b=A,c=C,d=D}. + +update_foo_barf(#foo{}=R, A, _B, C, D, E) -> + R#barf{a=A,b=A,c=C,d=D,e=E}. + + +-define(TrueGuard(Expr), if Expr -> ok; true -> ?t:fail() end). +-define(FalseGuard(Expr), if Expr -> ?t:fail(); true -> ok end). + +record_test(Config) when is_list(Config) -> + ?line true = is_record(#foo{}, foo), + ?line false = is_record(#foo{}, barf), + ?line false = is_record({foo}, foo), + + ?line true = erlang:is_record(#foo{}, foo), + ?line false = erlang:is_record(#foo{}, barf), + ?line false = erlang:is_record({foo}, foo), + + ?line false = is_record([], foo), + ?line false = is_record(Config, foo), + + ?line ?TrueGuard(is_record(#foo{}, foo)), + ?line ?FalseGuard(is_record(#foo{}, barf)), + ?line ?FalseGuard(is_record({foo}, foo)), + + ?line ?TrueGuard(erlang:is_record(#foo{}, foo)), + ?line ?FalseGuard(erlang:is_record(#foo{}, barf)), + ?line ?FalseGuard(erlang:is_record({foo}, foo)), + + ?line ?FalseGuard(is_record([], foo)), + ?line ?FalseGuard(is_record(Config, foo)), + + %% 'not is_record/2' to test guard optimization. + + ?line ?FalseGuard(not is_record(#foo{}, foo)), + ?line ?TrueGuard(not is_record(#foo{}, barf)), + ?line ?TrueGuard(not is_record({foo}, foo)), + + ?line ?FalseGuard(not erlang:is_record(#foo{}, foo)), + ?line ?TrueGuard(not erlang:is_record(#foo{}, barf)), + ?line ?TrueGuard(not erlang:is_record({foo}, foo)), + + Foo = id(#foo{}), + ?line ?FalseGuard(not erlang:is_record(Foo, foo)), + ?line ?TrueGuard(not erlang:is_record(Foo, barf)), + + ?line ?TrueGuard(not is_record(Config, foo)), + + ?line ?TrueGuard(not is_record(a, foo)), + ?line ?TrueGuard(not is_record([], foo)), + + %% Pass non-literal first argument. + + ?line true = is_record(id(#foo{}), foo), + ?line false = is_record(id(#foo{}), barf), + ?line false = is_record(id({foo}), foo), + + ?line true = erlang:is_record(id(#foo{}), foo), + ?line false = erlang:is_record(id(#foo{}), barf), + ?line false = erlang:is_record(id({foo}), foo), + + NoRec1 = id(blurf), + NoRec2 = id([]), + + ?line ?TrueGuard(not is_record(NoRec1, foo)), + ?line ?TrueGuard(not is_record(NoRec2, foo)), + + %% Force the use of guard bifs by using the 'xor' operation. + + False = id(false), + ?line ?TrueGuard(is_record(#foo{}, foo) xor False), + ?line ?FalseGuard(is_record(#foo{}, barf) xor False), + ?line ?FalseGuard(is_record({foo}, foo) xor False ), + + ?line ?TrueGuard(is_record(Foo, foo) xor False), + ?line ?FalseGuard(is_record(Foo, barf) xor False), + + + %% Implicit guards by using a list comprehension. + + List = id([1,#foo{a=2},3,#bar{d=4},5,#foo{a=6},7]), + + ?line [#foo{a=2},#foo{a=6}] = [X || X <- List, is_record(X, foo)], + ?line [#bar{d=4}] = [X || X <- List, is_record(X, bar)], + ?line [1,#foo{a=2},3,5,#foo{a=6},7] = + [X || X <- List, not is_record(X, bar)], + ?line [1,3,5,7] = + [X || X <- List, ((not is_record(X, bar)) and (not is_record(X, foo)))], + ?line [#foo{a=2},#bar{d=4},#foo{a=6}] = + [X || X <- List, ((is_record(X, bar)) or (is_record(X, foo)))], + ?line [1,3,#bar{d=4}] = + [X || X <- List, ((is_record(X, bar)) or (X < 5))], + + ?line MyList = [#foo{a=3},x,[],{a,b}], + ?line [#foo{a=3}] = [X || X <- MyList, is_record(X, foo)], + ?line [x,[],{a,b}] = [X || X <- MyList, not is_record(X, foo)], + ?line [#foo{a=3}] = [X || X <- MyList, begin is_record(X, foo) end], + ?line [x,[],{a,b}] = [X || X <- MyList, begin not is_record(X, foo) end], + ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList, is_record(X, foo) or + not is_binary(X)], + ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList, not is_record(X, foo) or + not is_binary(X)], + ?line [#foo{a=3}] = [X || X <- MyList, is_record(X, foo) or is_reference(X)], + ?line [x,[],{a,b}] = [X || X <- MyList, not is_record(X, foo) or + is_reference(X)], + ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList, + begin is_record(X, foo) or + not is_binary(X) end], + ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList, + begin not is_record(X, foo) or + not is_binary(X) end], + ?line [#foo{a=3}] = [X || X <- MyList, + begin is_record(X, foo) or is_reference(X) end], + ?line [x,[],{a,b}] = [X || X <- MyList, + begin not is_record(X, foo) or + is_reference(X) end], + ok. + +eval_once(Config) when is_list(Config) -> + ?line once(fun(GetRec) -> + true = erlang:is_record(GetRec(), foo) + end, #foo{}), + ?line once(fun(GetRec) -> + (GetRec())#foo{a=1} + end, #foo{}), + ?line once(fun(GetRec) -> + (GetRec())#foo{a=1,b=2} + end, #foo{}), + ?line once(fun(GetRec) -> + (GetRec())#foo{a=1,b=2,c=3} + end, #foo{}), + ?line once(fun(GetRec) -> + (GetRec())#foo{a=1,b=2,c=3,d=4} + end, #foo{}), + ok. + +once(Test, Record) -> + put(?MODULE, 0), + GetRec = fun() -> + put(?MODULE, 1+get(?MODULE)), + Record + end, + Result = Test(GetRec), + case get(?MODULE) of + 1 -> ok; + N -> + io:format("Evaluated ~w times\n", [N]), + ?t:fail() + end, + Result. + +id(I) -> I. diff --git a/lib/debugger/test/test_lib.erl b/lib/debugger/test/test_lib.erl new file mode 100644 index 0000000000..541375e64a --- /dev/null +++ b/lib/debugger/test/test_lib.erl @@ -0,0 +1,29 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + + +-module(test_lib). + +-export([interpret/1]). + +interpret(Mod) when atom(Mod) -> + case lists:member(Mod, int:interpreted()) of + true -> ok; + false -> {module,Mod} = i:ii(Mod) + end. diff --git a/lib/debugger/test/trycatch_SUITE.erl b/lib/debugger/test/trycatch_SUITE.erl new file mode 100644 index 0000000000..5901cdc9e5 --- /dev/null +++ b/lib/debugger/test/trycatch_SUITE.erl @@ -0,0 +1,796 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(trycatch_SUITE). + +-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1, + basic/1,lean_throw/1,try_of/1,try_after/1,%after_bind/1, + catch_oops/1,after_oops/1,eclectic/1,rethrow/1, + nested_of/1,nested_catch/1,nested_after/1]). + +-include("test_server.hrl"). + +all(suite) -> + [{conf,init_all,cases(),finish_all}]. + +cases() -> + [basic,lean_throw,try_of,try_after,%after_bind, + catch_oops,after_oops,eclectic,rethrow, + nested_of,nested_catch,nested_after]. + +init_per_testcase(_Case, Config) -> + test_lib:interpret(?MODULE), + Dog = test_server:timetrap(?t:minutes(1)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + ?line test_lib:interpret(?MODULE), + ?line true = lists:member(?MODULE, int:interpreted()), + ok. + +finish_all(Config) when is_list(Config) -> + ok. + +basic(Conf) when is_list(Conf) -> + ?line 2 = + try my_div(4, 2) + catch + Class:Reason -> {Class,Reason} + end, + ?line error = + try my_div(1, 0) + catch + error:badarith -> error + end, + ?line error = + try 1/0 + catch + error:badarith -> error + end, + ?line ok = + try my_add(53, atom) + catch + error:badarith -> ok + end, + ?line exit_nisse = + try exit(nisse) + catch + exit:nisse -> exit_nisse + end, + ?line ok = + try throw(kalle) + catch + kalle -> ok + end, + + %% Try some stuff where the compiler will optimize away the try. + + V = id({a,variable}), + ?line V = try V catch nisse -> error end, + ?line 42 = try 42 catch nisse -> error end, + ?line [V] = try [V] catch nisse -> error end, + ?line {ok,V} = try {ok,V} catch nisse -> error end, + + %% Same idea, but use an after too. + + ?line V = try V catch nisse -> error after after_call() end, + ?line after_clean(), + ?line 42 = try 42 after after_call() end, + ?line after_clean(), + ?line [V] = try [V] catch nisse -> error after after_call() end, + ?line after_clean(), + ?line {ok,V} = try {ok,V} after after_call() end, + + %% Try/of + ?line ok = try V of + {a,variable} -> ok + catch nisse -> erro + end, + + ok. + +after_call() -> + put(basic, after_was_called). + +after_clean() -> + after_was_called = erase(basic). + +lean_throw(Conf) when is_list(Conf) -> + ?line {throw,kalle} = + try throw(kalle) + catch + Kalle -> {throw,Kalle} + end, + ?line {exit,kalle} = + try exit(kalle) + catch + Throw1 -> {throw,Throw1}; + exit:Reason1 -> {exit,Reason1} + end, + ?line {exit,kalle} = + try exit(kalle) + catch + exit:Reason2 -> {exit,Reason2}; + Throw2 -> {throw,Throw2} + end, + ?line {exit,kalle} = + try try exit(kalle) + catch + Throw3 -> {throw,Throw3} + end + catch + exit:Reason3 -> {exit,Reason3} + end, + ok. + +try_of(Conf) when is_list(Conf) -> + ?line {ok,{some,content}} = + try_of_1({value,{good,{some,content}}}), + ?line {error,[other,content]} = + try_of_1({value,{bad,[other,content]}}), + ?line {caught,{exit,{ex,it,[reason]}}} = + try_of_1({exit,{ex,it,[reason]}}), + ?line {caught,{throw,[term,{in,a,{tuple}}]}} = + try_of_1({throw,[term,{in,a,{tuple}}]}), + ?line {caught,{error,[bad,arg]}} = + try_of_1({error,[bad,arg]}), + ?line {caught,{error,badarith}} = + try_of_1({'div',{1,0}}), + ?line {caught,{error,badarith}} = + try_of_1({'add',{a,0}}), + ?line {caught,{error,badarg}} = + try_of_1({'abs',x}), + ?line {caught,{error,function_clause}} = + try_of_1(illegal), + ?line {error,{try_clause,{some,other_garbage}}} = + try try_of_1({value,{some,other_garbage}}) + catch error:Reason -> {error,Reason} + end, + ok. + +try_of_1(X) -> + try foo(X) of + {good,Y} -> {ok,Y}; + {bad,Y} -> {error,Y} + catch + Class:Reason -> + {caught,{Class,Reason}} + end. + +try_after(Conf) when is_list(Conf) -> + ?line {{ok,[some,value],undefined},finalized} = + try_after_1({value,{ok,[some,value]}},finalized), + ?line {{error,badarith,undefined},finalized} = + try_after_1({'div',{1,0}},finalized), + ?line {{error,badarith,undefined},finalized} = + try_after_1({'add',{1,a}},finalized), + ?line {{error,badarg,undefined},finalized} = + try_after_1({'abs',a},finalized), + ?line {{error,[the,{reason}],undefined},finalized} = + try_after_1({error,[the,{reason}]},finalized), + ?line {{throw,{thrown,[reason]},undefined},finalized} = + try_after_1({throw,{thrown,[reason]}},finalized), + ?line {{exit,{exited,{reason}},undefined},finalized} = + try_after_1({exit,{exited,{reason}}},finalized), + ?line {{error,function_clause,undefined},finalized} = + try_after_1(function_clause,finalized), + ?line ok = + try try_after_1({'add',{1,1}}, finalized) + catch + error:{try_clause,2} -> ok + end, + ?line finalized = erase(try_after), + ?line ok = + try try foo({exit,[reaso,{n}]}) + after put(try_after, finalized) + end + catch + exit:[reaso,{n}] -> ok + end, + ok. + +try_after_1(X, Y) -> + erase(try_after), + Try = + try foo(X) of + {ok,Value} -> {ok,Value,get(try_after)} + catch + Reason -> {throw,Reason,get(try_after)}; + error:Reason -> {error,Reason,get(try_after)}; + exit:Reason -> {exit,Reason,get(try_after)} + after + put(try_after, Y) + end, + {Try,erase(try_after)}. + +-ifdef(begone). + +after_bind(Conf) when is_list(Conf) -> + V = [make_ref(),self()|value], + ?line {value,{value,V}} = + after_bind_1({value,V}, V, {value,V}), + ok. + +after_bind_1(X, V, Y) -> + try + Try = + try foo(X) of + V -> value + catch + C1:V -> {caught,C1} + after + After = foo(Y) + end, + {Try,After} + of + V -> {value,V} + catch + C:D -> {caught,{C,D}} + end. + +-endif. + +catch_oops(Conf) when is_list(Conf) -> + V = {v,[a,l|u],{e},self()}, + ?line {value,V} = catch_oops_1({value,V}), + ?line {value,1} = catch_oops_1({'div',{1,1}}), + ?line {error,badarith} = catch_oops_1({'div',{1,0}}), + ?line {error,function_clause} = catch_oops_1(function_clause), + ?line {throw,V} = catch_oops_1({throw,V}), + ?line {exit,V} = catch_oops_1({exit,V}), + ok. + +catch_oops_1(X) -> + Ref = make_ref(), + try try foo({error,Ref}) + catch + error:Ref -> + foo(X) + end of + Value -> {value,Value} + catch + Class:Data -> {Class,Data} + end. + + + +after_oops(Conf) when is_list(Conf) -> + V = {self(),make_ref()}, + ?line {{value,V},V} = after_oops_1({value,V}, {value,V}), + ?line {{exit,V},V} = after_oops_1({exit,V}, {value,V}), + ?line {{error,V},undefined} = after_oops_1({value,V}, {error,V}), + ?line {{error,function_clause},undefined} = + after_oops_1({exit,V}, function_clause), + ok. + +after_oops_1(X, Y) -> + erase(after_oops), + Try = + try try foo(X) + after + put(after_oops, foo(Y)) + end of + V -> {value,V} + catch + C:D -> {C,D} + end, + {Try,erase(after_oops)}. + + + +eclectic(Conf) when is_list(Conf) -> + V = {make_ref(),3.1415926535,[[]|{}]}, + ?line {{value,{value,V},V},V} = + eclectic_1({foo,{value,{value,V}}}, undefined, {value,V}), + ?line {{'EXIT',{V,[{?MODULE,foo,_}|_]}},V} = + eclectic_1({catch_foo,{error,V}}, undefined, {value,V}), + ?line {{error,{exit,V},{'EXIT',V}},V} = + eclectic_1({foo,{error,{exit,V}}}, error, {value,V}), + ?line {{value,{value,V},V},{'EXIT',{badarith,[{?MODULE,my_add,_}|_]}}} = + eclectic_1({foo,{value,{value,V}}}, undefined, {'add',{0,a}}), + ?line {{'EXIT',V},V} = + eclectic_1({catch_foo,{exit,V}}, undefined, {throw,V}), + ?line {{error,{'div',{1,0}},{'EXIT',{badarith,[{?MODULE,my_div,_}|_]}}}, {'EXIT',V}} = + eclectic_1({foo,{error,{'div',{1,0}}}}, error, {exit,V}), + ?line {{{error,V},{'EXIT',{V,[{?MODULE,foo,_}|_]}}},{'EXIT',V}} = + eclectic_1({catch_foo,{throw,{error,V}}}, undefined, {exit,V}), + %% + ?line {{value,{value,{value,V},V}},V} = + eclectic_2({value,{value,V}}, undefined, {value,V}), + ?line {{value,{throw,{value,V},V}},V} = + eclectic_2({throw,{value,V}}, throw, {value,V}), + ?line {{caught,{'EXIT',V}},undefined} = + eclectic_2({value,{value,V}}, undefined, {exit,V}), + ?line {{caught,{'EXIT',{V,[{?MODULE,foo,_}|_]}}},undefined} = + eclectic_2({error,{value,V}}, throw, {error,V}), + ?line {{caught,{'EXIT',{badarg,[{erlang,abs,[V]}|_]}}},V} = + eclectic_2({value,{'abs',V}}, undefined, {value,V}), + ?line {{caught,{'EXIT',{badarith,[{?MODULE,my_add,_}|_]}}},V} = + eclectic_2({exit,{'add',{0,a}}}, exit, {value,V}), + ?line {{caught,{'EXIT',V}},undefined} = + eclectic_2({value,{error,V}}, undefined, {exit,V}), + ?line {{caught,{'EXIT',{V,[{?MODULE,foo,_}|_]}}},undefined} = + eclectic_2({throw,{'div',{1,0}}}, throw, {error,V}), + ok. + +eclectic_1(X, C, Y) -> + erase(eclectic), + Done = make_ref(), + Try = + try case X of + {catch_foo,V} -> catch {Done,foo(V)}; + {foo,V} -> {Done,foo(V)} + end of + {Done,D} -> {value,D,catch foo(D)}; + {'EXIT',_}=Exit -> Exit; + D -> {D,catch foo(D)} + catch + C:D -> {C,D,catch foo(D)} + after + put(eclectic, catch foo(Y)) + end, + {Try,erase(eclectic)}. + +eclectic_2(X, C, Y) -> + Done = make_ref(), + erase(eclectic), + Catch = + case + catch + {Done, + try foo(X) of + V -> {value,V,foo(V)} + catch + C:D -> {C,D,foo(D)} + after + put(eclectic, foo(Y)) + end} of + {Done,Z} -> {value,Z}; + Z -> {caught,Z} + end, + {Catch,erase(eclectic)}. + +rethrow(Conf) when is_list(Conf) -> + V = {a,[b,{c,self()},make_ref]}, + ?line {value2,value1} = + rethrow_1({value,V}, V), + ?line {caught2,{error,V}} = + rethrow_2({error,V}, undefined), + ?line {caught2,{exit,V}} = + rethrow_1({exit,V}, error), + ?line {caught2,{throw,V}} = + rethrow_1({throw,V}, undefined), + ?line {caught2,{throw,V}} = + rethrow_2({throw,V}, undefined), + ?line {caught2,{error,badarith}} = + rethrow_1({'add',{0,a}}, throw), + ?line {caught2,{error,function_clause}} = + rethrow_2(function_clause, undefined), + ?line {caught2,{error,{try_clause,V}}} = + rethrow_1({value,V}, exit), + ?line {value2,{caught1,V}} = + rethrow_1({error,V}, error), + ?line {value2,{caught1,V}} = + rethrow_1({exit,V}, exit), + ?line {value2,caught1} = + rethrow_2({throw,V}, V), + ok. + +rethrow_1(X, C1) -> + try try foo(X) of + C1 -> value1 + catch + C1:D1 -> {caught1,D1} + end of + V2 -> {value2,V2} + catch + C2:D2 -> {caught2,{C2,D2}} + end. + +rethrow_2(X, C1) -> + try try foo(X) of + C1 -> value1 + catch + C1 -> caught1 % Implicit class throw: + end of + V2 -> {value2,V2} + catch + C2:D2 -> {caught2,{C2,D2}} + end. + + + +nested_of(Conf) when is_list(Conf) -> + V = {[self()|make_ref()],1.4142136}, + ?line {{value,{value1,{V,x2}}}, + {V,x3}, + {V,x4}, + finalized} = + nested_of_1({{value,{V,x1}},void,{V,x1}}, + {value,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{throw,{V,x2}}}, + {V,x3}, + {V,x4}, + finalized} = + nested_of_1({{value,{V,x1}},void,{V,x1}}, + {throw,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{error,badarith}}, + undefined, + {V,x4}, + finalized} = + nested_of_1({{value,{V,x1}},void,{V,x1}}, + {throw,{V,x2}}, {'div',{1,0}}, {value,{V,x4}}), + ?line {{caught,{error,badarith}}, + undefined, + undefined, + finalized} = + nested_of_1({{value,{V,x1}},void,{V,x1}}, + {throw,{V,x2}}, {'div',{1,0}}, {'add',{0,b}}), + %% + ?line {{caught,{error,{try_clause,{V,x1}}}}, + {V,x3}, + {V,x4}, + finalized} = + nested_of_1({{value,{V,x1}},void,try_clause}, + void, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{exit,{V,x3}}}, + undefined, + {V,x4}, + finalized} = + nested_of_1({{value,{V,x1}},void,try_clause}, + void, {exit,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{throw,{V,x4}}}, + undefined, + undefined, + finalized} = + nested_of_1({{value,{V,x1}},void,try_clause}, + void, {exit,{V,x3}}, {throw,{V,x4}}), + %% + ?line {{value,{caught1,{V,x2}}}, + {V,x3}, + {V,x4}, + finalized} = + nested_of_1({{error,{V,x1}},error,{V,x1}}, + {value,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{error,badarith}}, + {V,x3}, + {V,x4}, + finalized} = + nested_of_1({{error,{V,x1}},error,{V,x1}}, + {'add',{1,c}}, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{error,badarith}}, + undefined, + {V,x4}, + finalized} = + nested_of_1({{error,{V,x1}},error,{V,x1}}, + {'add',{1,c}}, {'div',{17,0}}, {value,{V,x4}}), + ?line {{caught,{error,badarg}}, + undefined, + undefined, + finalized} = + nested_of_1({{error,{V,x1}},error,{V,x1}}, + {'add',{1,c}}, {'div',{17,0}}, {'abs',V}), + %% + ?line {{caught,{error,badarith}}, + {V,x3}, + {V,x4}, + finalized} = + nested_of_1({{'add',{2,c}},rethrow,void}, + void, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{error,badarg}}, + undefined, + {V,x4}, + finalized} = + nested_of_1({{'add',{2,c}},rethrow,void}, + void, {'abs',V}, {value,{V,x4}}), + ?line {{caught,{error,function_clause}}, + undefined, + undefined, + finalized} = + nested_of_1({{'add',{2,c}},rethrow,void}, + void, {'abs',V}, function_clause), + ok. + +nested_of_1({X1,C1,V1}, + X2, X3, X4) -> + erase(nested3), + erase(nested4), + erase(nested), + Self = self(), + Try = + try + try self() + of + Self -> + try + foo(X1) + of + V1 -> {value1,foo(X2)} + catch + C1:V1 -> {caught1,foo(X2)} + after + put(nested3, foo(X3)) + end + after + put(nested4, foo(X4)) + end + of + V -> {value,V} + catch + C:D -> {caught,{C,D}} + after + put(nested, finalized) + end, + {Try,erase(nested3),erase(nested4),erase(nested)}. + + + +nested_catch(Conf) when is_list(Conf) -> + V = {[make_ref(),1.4142136,self()]}, + ?line {{value,{value1,{V,x2}}}, + {V,x3}, + {V,x4}, + finalized} = + nested_catch_1({{value,{V,x1}},void,{V,x1}}, + {value,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{throw,{V,x2}}}, + {V,x3}, + {V,x4}, + finalized} = + nested_catch_1({{value,{V,x1}},void,{V,x1}}, + {throw,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{error,badarith}}, + undefined, + {V,x4}, + finalized} = + nested_catch_1({{value,{V,x1}},void,{V,x1}}, + {throw,{V,x2}}, {'div',{1,0}}, {value,{V,x4}}), + ?line {{caught,{error,badarith}}, + undefined, + undefined, + finalized} = + nested_catch_1({{value,{V,x1}},void,{V,x1}}, + {throw,{V,x2}}, {'div',{1,0}}, {'add',{0,b}}), + %% + ?line {{caught,{error,{try_clause,{V,x1}}}}, + {V,x3}, + {V,x4}, + finalized} = + nested_catch_1({{value,{V,x1}},void,try_clause}, + void, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{exit,{V,x3}}}, + undefined, + {V,x4}, + finalized} = + nested_catch_1({{value,{V,x1}},void,try_clause}, + void, {exit,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{throw,{V,x4}}}, + undefined, + undefined, + finalized} = + nested_catch_1({{value,{V,x1}},void,try_clause}, + void, {exit,{V,x3}}, {throw,{V,x4}}), + %% + ?line {{value,{caught1,{V,x2}}}, + {V,x3}, + {V,x4}, + finalized} = + nested_catch_1({{error,{V,x1}},error,{V,x1}}, + {value,{V,x2}}, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{error,badarith}}, + {V,x3}, + {V,x4}, + finalized} = + nested_catch_1({{error,{V,x1}},error,{V,x1}}, + {'add',{1,c}}, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{error,badarith}}, + undefined, + {V,x4}, + finalized} = + nested_catch_1({{error,{V,x1}},error,{V,x1}}, + {'add',{1,c}}, {'div',{17,0}}, {value,{V,x4}}), + ?line {{caught,{error,badarg}}, + undefined, + undefined, + finalized} = + nested_catch_1({{error,{V,x1}},error,{V,x1}}, + {'add',{1,c}}, {'div',{17,0}}, {'abs',V}), + %% + ?line {{caught,{error,badarith}}, + {V,x3}, + {V,x4}, + finalized} = + nested_catch_1({{'add',{2,c}},rethrow,void}, + void, {value,{V,x3}}, {value,{V,x4}}), + ?line {{caught,{error,badarg}}, + undefined, + {V,x4}, + finalized} = + nested_catch_1({{'add',{2,c}},rethrow,void}, + void, {'abs',V}, {value,{V,x4}}), + ?line {{caught,{error,function_clause}}, + undefined, + undefined, + finalized} = + nested_catch_1({{'add',{2,c}},rethrow,void}, + void, {'abs',V}, function_clause), + ok. + +nested_catch_1({X1,C1,V1}, + X2, X3, X4) -> + erase(nested3), + erase(nested4), + erase(nested), + Throw = make_ref(), + Try = + try + try throw(Throw) + catch + Throw -> + try + foo(X1) + of + V1 -> {value1,foo(X2)} + catch + C1:V1 -> {caught1,foo(X2)} + after + put(nested3, foo(X3)) + end + after + put(nested4, foo(X4)) + end + of + V -> {value,V} + catch + C:D -> {caught,{C,D}} + after + put(nested, finalized) + end, + {Try,erase(nested3),erase(nested4),erase(nested)}. + +nested_after(Conf) when is_list(Conf) -> + V = [{make_ref(),1.4142136,self()}], + ?line {value, + {V,x3}, + {value1,{V,x2}}, + finalized} = + nested_after_1({{value,{V,x1}},void,{V,x1}}, + {value,{V,x2}}, {value,{V,x3}}), + ?line {{caught,{error,{V,x2}}}, + {V,x3}, + undefined, + finalized} = + nested_after_1({{value,{V,x1}},void,{V,x1}}, + {error,{V,x2}}, {value,{V,x3}}), + ?line {{caught,{exit,{V,x3}}}, + undefined, + undefined, + finalized} = + nested_after_1({{value,{V,x1}},void,{V,x1}}, + {error,{V,x2}}, {exit,{V,x3}}), + %% + ?line {{caught,{error,{try_clause,{V,x1}}}}, + {V,x3}, + undefined, + finalized} = + nested_after_1({{value,{V,x1}},void,try_clause}, + void, {value,{V,x3}}), + ?line {{caught,{error,badarith}}, + undefined, + undefined, + finalized} = + nested_after_1({{value,{V,x1}},void,try_clause}, + void, {'div',{17,0}}), + %% + ?line {value, + {V,x3}, + {caught1,{V,x2}}, + finalized} = + nested_after_1({{throw,{V,x1}},throw,{V,x1}}, + {value,{V,x2}}, {value,{V,x3}}), + ?line {{caught,{error,badarith}}, + {V,x3}, + undefined, + finalized} = + nested_after_1({{throw,{V,x1}},throw,{V,x1}}, + {'add',{a,b}}, {value,{V,x3}}), + ?line {{caught,{error,badarg}}, + undefined, + undefined, + finalized} = + nested_after_1({{throw,{V,x1}},throw,{V,x1}}, + {'add',{a,b}}, {'abs',V}), + %% + ?line {{caught,{throw,{V,x1}}}, + {V,x3}, + undefined, + finalized} = + nested_after_1({{throw,{V,x1}},rethrow,void}, + void, {value,{V,x3}}), + ?line {{caught,{error,badarith}}, + undefined, + undefined, + finalized} = + nested_after_1({{throw,{V,x1}},rethrow,void}, + void, {'div',{1,0}}), + ok. + +nested_after_1({X1,C1,V1}, + X2, X3) -> + erase(nested3), + erase(nested4), + erase(nested), + Self = self(), + Try = + try + try self() + after + After = + try + foo(X1) + of + V1 -> {value1,foo(X2)} + catch + C1:V1 -> {caught1,foo(X2)} + after + put(nested3, foo(X3)) + end, + put(nested4, After) + end + of + Self -> value + catch + C:D -> {caught,{C,D}} + after + put(nested, finalized) + end, + {Try,erase(nested3),erase(nested4),erase(nested)}. + +foo({value,Value}) -> Value; +foo({'div',{A,B}}) -> + my_div(A, B); +foo({'add',{A,B}}) -> + my_add(A, B); +foo({'abs',X}) -> + my_abs(X); +foo({error,Error}) -> + erlang:error(Error); +foo({throw,Throw}) -> + erlang:throw(Throw); +foo({exit,Exit}) -> + erlang:exit(Exit); +foo({raise,{Class,Reason}}) -> + erlang:raise(Class, Reason). +%%foo(function_clause) -> % must not be defined! + +my_div(A, B) -> + A div B. + +my_add(A, B) -> + A + B. + +my_abs(X) -> abs(X). + +id(I) -> I. diff --git a/lib/ic/test/Makefile b/lib/ic/test/Makefile new file mode 100644 index 0000000000..1142159d19 --- /dev/null +++ b/lib/ic/test/Makefile @@ -0,0 +1,277 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1998-2010. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(IC_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/ic_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = ic.spec ic.spec.vxworks + + +IDL_FILES = + +COMPILER_TEST_FILES = \ + ic_SUITE_data/Corba.idl \ + ic_SUITE_data/Coss.idl \ + ic_SUITE_data/attr.idl \ + ic_SUITE_data/c_err1.idl \ + ic_SUITE_data/c_err2.idl \ + ic_SUITE_data/c_err3.idl \ + ic_SUITE_data/c_norm.idl \ + ic_SUITE_data/enum.idl \ + ic_SUITE_data/forward.idl \ + ic_SUITE_data/include.idl \ + ic_SUITE_data/include2.idl \ + ic_SUITE_data/include3.idl \ + ic_SUITE_data/inherit.idl \ + ic_SUITE_data/inherit_err.idl \ + ic_SUITE_data/inherit_warn.idl \ + ic_SUITE_data/mult_ids.idl \ + ic_SUITE_data/nasty.idl \ + ic_SUITE_data/one.idl \ + ic_SUITE_data/one_out.idl \ + ic_SUITE_data/one_raises.idl \ + ic_SUITE_data/one_followed.idl \ + ic_SUITE_data/one_void.idl \ + ic_SUITE_data/raises_reg.idl \ + ic_SUITE_data/struct.idl \ + ic_SUITE_data/syntax1.idl \ + ic_SUITE_data/syntax2.idl \ + ic_SUITE_data/syntax3.idl \ + ic_SUITE_data/syntax4.idl \ + ic_SUITE_data/syntax5.idl \ + ic_SUITE_data/syntax6.idl \ + ic_SUITE_data/type.idl \ + ic_SUITE_data/typeid.idl \ + ic_SUITE_data/u_case_mult.idl \ + ic_SUITE_data/u_mult.idl \ + ic_SUITE_data/u_norm.idl \ + ic_SUITE_data/u_type.idl \ + ic_SUITE_data/u_default.idl \ + ic_SUITE_data/undef_id.idl + + +COMPILER_TEST_FILES2 = \ + ic_register_SUITE_data/reg_m8.idl \ + ic_register_SUITE_data/reg_m9.idl \ + ic_register_SUITE_data/reg_m10.idl \ + ic_register_SUITE_data/reg_m11.idl \ + ic_register_SUITE_data/reg_m12.idl + + +COMPILER_TEST_FILES3 = \ + ic_pragma_SUITE_data/reg_m0.idl \ + ic_pragma_SUITE_data/reg_m1.idl \ + ic_pragma_SUITE_data/reg_m2.idl \ + ic_pragma_SUITE_data/reg_m3.idl \ + ic_pragma_SUITE_data/reg_m4.idl \ + ic_pragma_SUITE_data/reg_m5.idl \ + ic_pragma_SUITE_data/reg_m6.idl \ + ic_pragma_SUITE_data/reg_m7.idl \ + ic_pragma_SUITE_data/uggly.idl + + +COMPILER_TEST_FILES4 = \ + ic_be_SUITE_data/plain.idl + + +PREPROCESSOR_TEST_FILES = \ + ic_pp_SUITE_data/arg.idl \ + ic_pp_SUITE_data/cascade.idl \ + ic_pp_SUITE_data/comment.idl \ + ic_pp_SUITE_data/concat.idl \ + ic_pp_SUITE_data/define.idl \ + ic_pp_SUITE_data/if.idl \ + ic_pp_SUITE_data/if_zero.idl \ + ic_pp_SUITE_data/improp_nest_constr.idl \ + ic_pp_SUITE_data/inc.idl \ + ic_pp_SUITE_data/line.idl \ + ic_pp_SUITE_data/misc.idl \ + ic_pp_SUITE_data/nopara.idl \ + ic_pp_SUITE_data/predef.idl \ + ic_pp_SUITE_data/predef_time.idl \ + ic_pp_SUITE_data/self_ref.idl \ + ic_pp_SUITE_data/separate.idl \ + ic_pp_SUITE_data/swallow_sc.idl \ + ic_pp_SUITE_data/unintended_grp.idl + +C_CLIENT_ERL_SERVER_TEST_FILES = \ + c_client_erl_server_SUITE_data/Makefile.src \ + c_client_erl_server_SUITE_data/c_erl_test.idl \ + c_client_erl_server_SUITE_data/c_client.c \ + c_client_erl_server_SUITE_data/m_i_impl.erl + +C_CLIENT_ERL_SERVER_PROTO_TEST_FILES = \ + c_client_erl_server_proto_SUITE_data/Makefile.src \ + c_client_erl_server_proto_SUITE_data/c_erl_test.idl \ + c_client_erl_server_proto_SUITE_data/c_client.c \ + c_client_erl_server_proto_SUITE_data/my.c \ + c_client_erl_server_proto_SUITE_data/m_i_impl.erl + +C_CLIENT_ERL_SERVER_PROTO_TMO_TEST_FILES = \ + c_client_erl_server_proto_tmo_SUITE_data/Makefile.src \ + c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl \ + c_client_erl_server_proto_tmo_SUITE_data/c_client.c \ + c_client_erl_server_proto_tmo_SUITE_data/my.c \ + c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl + +ERL_CLIENT_C_SERVER_TEST_FILES = \ + erl_client_c_server_SUITE_data/Makefile.src \ + erl_client_c_server_SUITE_data/erl_c_test.idl \ + erl_client_c_server_SUITE_data/erl_client.erl \ + erl_client_c_server_SUITE_data/c_server.c \ + erl_client_c_server_SUITE_data/callbacks.c + +ERL_CLIENT_C_SERVER_PROTO_TEST_FILES = \ + erl_client_c_server_proto_SUITE_data/Makefile.src \ + erl_client_c_server_proto_SUITE_data/erl_c_test.idl \ + erl_client_c_server_proto_SUITE_data/erl_client.erl \ + erl_client_c_server_proto_SUITE_data/c_server.c \ + erl_client_c_server_proto_SUITE_data/callbacks.c + +JAVA_CLIENT_ERL_SERVER_TEST_FILES = \ + java_client_erl_server_SUITE_data/Makefile.src \ + java_client_erl_server_SUITE_data/java_erl_test.idl \ + java_client_erl_server_SUITE_data/JavaClient.java \ + java_client_erl_server_SUITE_data/m_i_impl.erl + +MODULES = \ + ic_SUITE \ + ic_register_SUITE \ + ic_pragma_SUITE \ + ic_pp_SUITE \ + ic_be_SUITE \ + c_client_erl_server_SUITE \ + c_client_erl_server_proto_SUITE \ + c_client_erl_server_proto_tmo_SUITE \ + erl_client_c_server_SUITE \ + erl_client_c_server_proto_SUITE \ + java_client_erl_server_SUITE + +GEN_MODULES = + +ERL_FILES = $(MODULES:%=%.erl) + +HRL_FILES = + +GEN_HRL_FILES = + + +GEN_FILES = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES=:%=$(IDLOUTDIR)/%.erl) + +GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR)) + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(GEN_TARGET_FILES) \ + $(SUITE_TARGET_FILES) + +# ---------------------------------------------------- +# PROGRAMS +# ---------------------------------------------------- + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_LOCAL_FLAGS += -pa $(ERL_TOP)/lib/orber/ebin -pa $(ERL_TOP)/lib/ic/ebin + +ERL_COMPILE_FLAGS += \ + $(ERL_LOCAL_FLAGS) \ + -pa $(ERL_TOP)/lib/test_server/ebin \ + -pa $(ERL_TOP)/lib/orber/ebin \ + -I$(ERL_TOP)/lib/orber \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +tests debug opt: $(TARGET_FILES) + +clean: + rm -f $(TARGET_FILES) + rm -f errs core *~ + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) $(RELSYSDIR)/ic_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/ic_register_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/ic_pragma_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/ic_pp_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/ic_be_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_proto_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_proto_tmo_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/erl_client_c_server_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/erl_client_c_server_proto_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/java_client_erl_server_SUITE_data + $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) $(ERL_FILES) \ + $(RELSYSDIR) + $(INSTALL_DATA) $(COMPILER_TEST_FILES) $(RELSYSDIR)/ic_SUITE_data + $(INSTALL_DATA) $(COMPILER_TEST_FILES2) \ + $(RELSYSDIR)/ic_register_SUITE_data + $(INSTALL_DATA) $(COMPILER_TEST_FILES3) \ + $(RELSYSDIR)/ic_pragma_SUITE_data + $(INSTALL_DATA) $(COMPILER_TEST_FILES4) \ + $(RELSYSDIR)/ic_be_SUITE_data + $(INSTALL_DATA) $(PREPROCESSOR_TEST_FILES) \ + $(RELSYSDIR)/ic_pp_SUITE_data + $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_TEST_FILES) \ + $(RELSYSDIR)/c_client_erl_server_SUITE_data + $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_PROTO_TEST_FILES) \ + $(RELSYSDIR)/c_client_erl_server_proto_SUITE_data + $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_PROTO_TMO_TEST_FILES) \ + $(RELSYSDIR)/c_client_erl_server_proto_tmo_SUITE_data + $(INSTALL_DATA) $(ERL_CLIENT_C_SERVER_TEST_FILES) \ + $(RELSYSDIR)/erl_client_c_server_SUITE_data + $(INSTALL_DATA) $(ERL_CLIENT_C_SERVER_PROTO_TEST_FILES) \ + $(RELSYSDIR)/erl_client_c_server_proto_SUITE_data + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(JAVA_CLIENT_ERL_SERVER_TEST_FILES) \ + $(RELSYSDIR)/java_client_erl_server_SUITE_data diff --git a/lib/ic/test/c_client_erl_server_SUITE.erl b/lib/ic/test/c_client_erl_server_SUITE.erl new file mode 100644 index 0000000000..40c1395d10 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE.erl @@ -0,0 +1,315 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +%%---------------------------------------------------------------------- +%% Purpose : Test suite for c-client/erl-server +%%---------------------------------------------------------------------- + + +-module(c_client_erl_server_SUITE). +-include("test_server.hrl"). + +-export([init_per_testcase/2, fin_per_testcase/2, + all/1, void_test/1, long_test/1, long_long_test/1, + unsigned_short_test/1, unsigned_long_test/1, + unsigned_long_long_test/1, double_test/1, char_test/1, + wchar_test/1, octet_test/1, bool_test/1, struct_test/1, + struct2_test/1, seq1_test/1, seq2_test/1, seq3_test/1, + seq4_test/1, seq5_test/1, array1_test/1, array2_test/1, + enum_test/1, string1_test/1, string2_test/1, string3_test/1, + string4_test/1, pid_test/1, port_test/1, ref_test/1, term_test/1, + typedef_test/1, inline_sequence_test/1, term_sequence_test/1, + term_struct_test/1, wstring1_test/1]). + +-define(DEFAULT_TIMEOUT, 20000). +-define(PORT_TIMEOUT, 15000). +-define(ERLANG_SERVER_NAME, idl_erlang_server). +-define(C_CLIENT_NODE_NAME, c_client_idl_test). + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i, we have + %% to make sure we are using the right m_i module. + code:purge(m_i), + code:load_file(m_i), + + WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + +all(doc) -> + "Test of IC with a C-client and an Erlang generic server. " + "The communication is via Erlang distribution."; +all(suite) -> + [void_test, long_test, long_long_test, unsigned_short_test, + unsigned_long_test, unsigned_long_long_test, double_test, + char_test, wchar_test, octet_test, bool_test, struct_test, + struct2_test, seq1_test, seq2_test, seq3_test, seq4_test, + seq5_test, array1_test, array2_test, enum_test, string1_test, + string2_test, string3_test, string4_test, pid_test, port_test, + ref_test, term_test, typedef_test, inline_sequence_test, + term_sequence_test, term_struct_test, wstring1_test]. + + +array1_test(doc) -> ""; +array1_test(suite) -> []; +array1_test(Config) -> + do_test(array1_test, Config). + +array2_test(doc) -> ""; +array2_test(suite) -> []; +array2_test(Config) -> + do_test(array2_test, Config). + +bool_test(doc) -> ""; +bool_test(suite) -> []; +bool_test(Config) -> + do_test(bool_test, Config). + +char_test(doc) -> ""; +char_test(suite) -> []; +char_test(Config) -> + do_test(char_test, Config). + +double_test(doc) -> ""; +double_test(suite) -> []; +double_test(Config) -> + do_test(double_test, Config). + +enum_test(doc) -> ""; +enum_test(suite) -> []; +enum_test(Config) -> + do_test(enum_test, Config). + +inline_sequence_test(doc) -> ""; +inline_sequence_test(suite) -> []; +inline_sequence_test(Config) -> + do_test(inline_sequence_test, Config). + +long_long_test(doc) -> ""; +long_long_test(suite) -> []; +long_long_test(Config) -> + do_test(long_long_test, Config). + +long_test(doc) -> ""; +long_test(suite) -> []; +long_test(Config) -> + do_test(long_test, Config). + +octet_test(doc) -> ""; +octet_test(suite) -> []; +octet_test(Config) -> + do_test(octet_test, Config). + +pid_test(doc) -> ""; +pid_test(suite) -> []; +pid_test(Config) -> + do_test(pid_test, Config). + +port_test(doc) -> ""; +port_test(suite) -> []; +port_test(Config) -> + do_test(port_test, Config). + +ref_test(doc) -> ""; +ref_test(suite) -> []; +ref_test(Config) -> + do_test(ref_test, Config). + +seq1_test(doc) -> ""; +seq1_test(suite) -> []; +seq1_test(Config) -> + do_test(seq1_test, Config). + +seq2_test(doc) -> ""; +seq2_test(suite) -> []; +seq2_test(Config) -> + do_test(seq2_test, Config). + +seq3_test(doc) -> ""; +seq3_test(suite) -> []; +seq3_test(Config) -> + do_test(seq3_test, Config). + +seq4_test(doc) -> ""; +seq4_test(suite) -> []; +seq4_test(Config) -> + do_test(seq4_test, Config). + +seq5_test(doc) -> ""; +seq5_test(suite) -> []; +seq5_test(Config) -> + do_test(seq5_test, Config). + +string1_test(doc) -> ""; +string1_test(suite) -> []; +string1_test(Config) -> + do_test(string1_test, Config). + +string2_test(doc) -> ""; +string2_test(suite) -> []; +string2_test(Config) -> + do_test(string2_test, Config). + +string3_test(doc) -> ""; +string3_test(suite) -> []; +string3_test(Config) -> + do_test(string3_test, Config). + +string4_test(doc) -> ""; +string4_test(suite) -> []; +string4_test(Config) -> + do_test(string4_test, Config). + +struct2_test(doc) -> ""; +struct2_test(suite) -> []; +struct2_test(Config) -> + do_test(struct2_test, Config). + +struct_test(doc) -> ""; +struct_test(suite) -> []; +struct_test(Config) -> + do_test(struct_test, Config). + +term_sequence_test(doc) -> ""; +term_sequence_test(suite) -> []; +term_sequence_test(Config) -> + do_test(term_sequence_test, Config). + +term_struct_test(doc) -> ""; +term_struct_test(suite) -> []; +term_struct_test(Config) -> + do_test(term_struct_test, Config). + +term_test(doc) -> ""; +term_test(suite) -> []; +term_test(Config) -> + do_test(term_test, Config). + +typedef_test(doc) -> ""; +typedef_test(suite) -> []; +typedef_test(Config) -> + do_test(typedef_test, Config). + +unsigned_long_long_test(doc) -> ""; +unsigned_long_long_test(suite) -> []; +unsigned_long_long_test(Config) -> + do_test(unsigned_long_long_test, Config). + +unsigned_long_test(doc) -> ""; +unsigned_long_test(suite) -> []; +unsigned_long_test(Config) -> + do_test(unsigned_long_test, Config). + +unsigned_short_test(doc) -> ""; +unsigned_short_test(suite) -> []; +unsigned_short_test(Config) -> + do_test(unsigned_short_test, Config). + +void_test(doc) -> ""; +void_test(suite) -> []; +void_test(Config) -> + do_test(void_test, Config). + +wchar_test(doc) -> ""; +wchar_test(suite) -> []; +wchar_test(Config) -> + do_test(wchar_test, Config). + +wstring1_test(doc) -> ""; +wstring1_test(suite) -> []; +wstring1_test(Config) -> + do_test(wstring1_test, Config). + + +%% It is here that all tests really are done. +%% + +do_test(Case, Config) -> + %% Trap exits + process_flag(trap_exit, true), + %% Start the server + {ok, _Pid} = m_i:oe_create_link([], {local, ?ERLANG_SERVER_NAME}), + Node = atom_to_list(node()), + DataDir = ?config(data_dir, Config), + %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]), + Cookie = atom_to_list(erlang:get_cookie()), + %% Start C-client node as a port program. + Cmd = filename:join([DataDir, "c_client"]) ++ + " -this-node-name " ++ atom_to_list(?C_CLIENT_NODE_NAME) ++ + " -peer-node " ++ Node ++ + " -peer-process-name " ++ atom_to_list(?ERLANG_SERVER_NAME) ++ + " -cookie " ++ Cookie ++ + " -test-case " ++ atom_to_list(Case), + Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]), + Res = wait_for_completion(Port), + %% Kill off node if there was timeout + case Res of + {error, timeout} -> + catch rpc:cast(?C_CLIENT_NODE_NAME, erlang, halt, [1]); + _ -> + ok + end, + process_flag(trap_exit, false), + catch m_i:stop(?ERLANG_SERVER_NAME), + ok = Res. + + +%% Wait for eof *and* exit status, but return if exit status indicates +%% an error, or we have been waiting more than PORT_TIMEOUT seconds. +%% +wait_for_completion(Port) -> + wait_for_completion(Port, 0). + +wait_for_completion(Port, N) when N < 2 -> + receive + {Port, {data, Bytes}} -> + %% Relay output + io:format("~s", [Bytes]), + wait_for_completion(Port, N); + {Port, {exit_status, 0}} -> + wait_for_completion(Port, N + 1); + {Port, {exit_status, Status}} -> + {error, Status}; + {Port, eof} -> + wait_for_completion(Port, N + 1); + {'EXIT', Port, Reason} -> + io:format("Port exited with reason: ~w~n", [Reason]), + wait_for_completion(Port, N); + {'EXIT', From, Reason} -> + io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]), + wait_for_completion(Port, N) + after ?PORT_TIMEOUT -> + {error, timeout} + end; +wait_for_completion(_, _) -> + ok. + + + diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src new file mode 100644 index 0000000000..6516e699bd --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src @@ -0,0 +1,145 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +# Makefile.src for c_client_erl_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@ + + +# Variables from ts: +# + +ERL_INCLUDE = @erl_include@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_LIB = @ic_libpath@@DS@@ic_lib@ + +ERL_INTERFACE_INCLUDE = @erl_interface_include@ +ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@ +ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@ +ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@ +ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@ + +CC = @CC@ +## XXX Should set warning flag with a DEBUG_FLAG +CFLAGS = @CFLAGS@ @DEFS@ -I@erl_include@ \ + -I@ic_include_path@ -I@erl_interface_include@ + +LD = @LD@ +LDFLAGS = @CROSSLDFLAGS@ +LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \ + $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS) +ERLC = erlc + +# Generated C header files +GEN_H_FILES = \ + m.h \ + m_i.h \ + oe_c_erl_test.h + +# Generated C files +GEN_C_FILES = \ + m.c \ + m_i.c \ + oe_c_erl_test.c \ + oe_code_m_a.c \ + oe_code_m_arr1.c \ + oe_code_m_arr2.c \ + oe_code_m_arr3.c \ + oe_code_m_aseq.c \ + oe_code_m_b.c \ + oe_code_m_bseq.c \ + oe_code_m_dd.c \ + oe_code_m_dyn.c \ + oe_code_m_dyn_sl.c \ + oe_code_m_es.c \ + oe_code_m_et.c \ + oe_code_m_etseq.c \ + oe_code_m_fruit.c \ + oe_code_m_lseq.c \ + oe_code_m_s.c \ + oe_code_m_s_sl.c \ + oe_code_m_sarr3.c \ + oe_code_m_simple.c \ + oe_code_m_ssarr3.c \ + oe_code_m_sseq.c \ + oe_code_m_ssstr3.c \ + oe_code_m_sstr3.c \ + oe_code_m_str1.c \ + oe_code_m_str3.c \ + oe_code_m_strRec.c \ + oe_code_m_strRec_str5.c \ + oe_code_m_strRec_str7.c + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_c_erl_test.hrl + +GEN_ERL_FILES = \ + m.erl \ + m_arr2.erl \ + m_arr3.erl \ + m_i.erl \ + m_str3.erl \ + oe_c_erl_test.erl + +C_FILES = $(GEN_C_FILES) c_client.c + +OBJS = $(C_FILES:.c=@obj@) + +PGMS = c_client@exe@ + +ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl + +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(PGMS) $(EBINS) + +clean: + -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + +$(PGMS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(GEN_C_FILES) $(GEN_H_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_client}" c_erl_test.idl + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" c_erl_test.idl + +.c@obj@: + $(CC) -c -o $*@obj@ $(CFLAGS) $< + +.erl.@EMULATOR@: + $(ERLC) -I $(IC_INCLUDE_PATH) $< + diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c new file mode 100644 index 0000000000..e4f9cfdece --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c @@ -0,0 +1,1760 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2001-2010. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ +/* C-client for test of IC. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __WIN32__ +# include <unistd.h> +#endif + +#include <string.h> + +#ifdef __WIN32__ +# include <time.h> +# include <sys/timeb.h> +#elif defined VXWORKS +#include <time.h> +#include <sys/times.h> +#else +#include <sys/time.h> +#endif + +#include <ctype.h> + +#ifdef __WIN32__ +# include <winsock2.h> +# include <windows.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "ei.h" +#include "erl_interface.h" +#include "m_i.h" + +#define HOSTNAMESZ 256 +#define NODENAMESZ 512 + +#define INBUFSZ 10 +#define OUTBUFSZ 0 + +#define MAXTRIES 5 + +#define CHECK_EXCEPTION(x) \ + if ((x)->_major != CORBA_NO_EXCEPTION) { \ + fprintf(stderr,"\n\nException: %s\n\n", \ + (char *)CORBA_exception_value((x))); \ + CORBA_exception_free((x)); \ + return -1; \ + } \ + +/* XXX Should free things here too! */ +#define RETURN_IF_OK(x) \ + if ((x)) {\ + fprintf(stdout, "ok\n");\ + return 0;\ + }\ + +#define cmp_str(x,y) (!strcmp((x),(y))) +#define cmp_wstr(x,y) (!ic_wstrcmp((x),(y))) + +typedef CORBA_Environment IC_Env; + +typedef int (*TestFunc)(IC_Env *); +typedef struct { + char *name; + TestFunc func; +} TestCase; + +static char longtext[] = +"Introduction The IC application is an IDL compiler implemented in Erlang." +" The IDL compiler generates client stubs and server skeletons." +" Several back-ends are supported, and they fall into three main groups." +" For more details on IC compiler options consult the ic(3) manual page." +" Argument passing cases 1 Caller allocates all necessary storage," +" except that which may be encapsulated and managed within the parameter itself." +" 2 The caller allocates a pointer and passes it by reference to the callee." +" The callee sets the pointer to point to a valid instance of the parameter's type." +" The caller is responsible for releasing the returned storage." +" Following completion of a request, the caller is not allowed to modify any values" +" in the returned storage. To do so the caller must first copy the returned instance" +" into a new instance, then modify the new instance. 3 The caller allocates a" +" pointer to an array slice which has all the same dimensions of the original" +" array except the first, and passes it by reference to the callee. The callee sets" +" the pointer to point to a valid instance of the array. The caller is responsible for" +" releasing the returned storage. Following completion of a request, the caller is not" +" allowed to modify any values in the returned storage. To do so the caller must first" +" copy the returned instance into a new instance, then modify the new instance." +" Generated Files Two files will be generated for each scope. One set of files will be" +" generated for each module and each interface scope. An extra set is generated for" +" those definitions at top level scope. One of the files is a header file(.h), and the" +" other file is a C source code file (.c). In addition to these files a number of C" +" source files will be generated for type encodings, they are named according to the " +"following template: oe_code_<type>.c."; +static char this_node[NODENAMESZ + 1]; +static char *progname; + +/* Test function prototypes */ + +static int void_test(IC_Env *env); +static int long_test(IC_Env *env); +static int long_long_test(IC_Env *env); +static int unsigned_short_test(IC_Env *env); +static int unsigned_long_test(IC_Env *env); +static int unsigned_long_long_test(IC_Env *env); +static int double_test(IC_Env *env); +static int char_test(IC_Env *env); +static int wchar_test(IC_Env *env); +static int octet_test(IC_Env *env); +static int bool_test(IC_Env *env); +static int struct_test(IC_Env *env); +static int struct2_test(IC_Env *env); +static int seq1_test(IC_Env *env); +static int seq2_test(IC_Env *env); +static int seq3_test(IC_Env *env); +static int seq4_test(IC_Env *env); +static int seq5_test(IC_Env *env); +static int array1_test(IC_Env *env); +static int array2_test(IC_Env *env); +static int enum_test(IC_Env *env); +static int string1_test(IC_Env *env); +static int string2_test(IC_Env *env); +static int string3_test(IC_Env *env); +static int string4_test(IC_Env *env); +static int pid_test(IC_Env *env); +static int port_test(IC_Env *env); +static int ref_test(IC_Env *env); +static int term_test(IC_Env *env); +static int typedef_test(IC_Env *env); +static int inline_sequence_test(IC_Env *env); +static int term_sequence_test(IC_Env *env); +static int term_struct_test(IC_Env *env); +static int wstring1_test(IC_Env *env); + +static TestCase test_cases[] = { + {"void_test", void_test}, + {"long_test", long_test}, + {"long_long_test", long_long_test}, + {"unsigned_short_test", unsigned_short_test}, + {"unsigned_long_test", unsigned_long_test}, + {"unsigned_long_long_test", unsigned_long_long_test}, + {"double_test", double_test}, + {"char_test", char_test}, + {"wchar_test", wchar_test}, + {"octet_test", octet_test}, + {"bool_test", bool_test}, + {"struct_test", struct_test}, + {"struct2_test", struct2_test}, + {"seq1_test", seq1_test}, + {"seq2_test", seq2_test}, + {"seq3_test", seq3_test}, + {"seq4_test", seq4_test}, + {"seq5_test", seq5_test}, + {"array1_test", array1_test}, + {"array2_test", array2_test}, + {"enum_test", enum_test}, + {"string1_test", string1_test}, + {"string2_test", string2_test}, + {"string3_test", string3_test}, + {"string4_test", string4_test}, + {"pid_test", pid_test}, + {"port_test", port_test}, + {"ref_test", ref_test}, + {"term_test", term_test}, + {"typedef_test", typedef_test}, + {"inline_sequence_test", inline_sequence_test}, + {"term_sequence_test", term_sequence_test}, + {"term_struct_test", term_struct_test}, + {"wstring1_test", wstring1_test}, + {"", NULL} +}; + +/* Other prototypes */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2); +static int cmp_a(m_a *a1, m_a *a2); +static int cmp_bseq(m_bseq *b1, m_bseq *b2); +static int cmp_b(m_b *b1, m_b *b2); +static int cmp_lseq(m_lseq *b1, m_lseq *b2); +static int cmp_etseq(m_etseq *b1, m_etseq *b2); +static int cmp_et(m_et* b1, m_et *b2); +static int cmp_es(m_es *b1, m_es *b2); +static int cmp_arr1(m_arr1 b1, m_arr1 b2); +static int cmp_dd(m_dd b1, m_dd b2); +static int cmp_strRec(m_strRec *b1, m_strRec *b2); +static int cmp_sseq(m_sseq *b1, m_sseq *b2); +static int cmp_pid(erlang_pid *p1, erlang_pid *p2); +static int cmp_port(erlang_port *p1, erlang_port *p2); +static int cmp_ref(erlang_ref *p1, erlang_ref *p2); +static int cmp_s(m_s *b1, m_s *b2); +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2); +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2); +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2); +static int cmp_arr3(m_arr3 b1, m_arr3 b2); + +static void print_aseq(m_aseq *a); +static void print_a(m_a *a); +static void print_bseq(m_bseq *b); +static void print_lseq(m_lseq *b); +static void print_b(m_b *b); +static void print_etseq(m_etseq *b); +static void print_et(m_et* b); +static void print_es(m_es *b); +static void print_arr1(long a[500]); +static void print_dd(long a[2][3]); +static void print_strRec(m_strRec* sr); +static void print_sseq(m_sseq *b); +static void print_pid(erlang_pid *p); +static void print_port(erlang_port *p); +static void print_ref(erlang_ref *p); +static void print_term(ETERM *t); +static void print_s(m_s *p); +static void print_ssstr3(m_ssstr3 *b1); +static void print_ssarr3(m_ssarr3 *b1); +static void print_sarr3(m_sarr3 *b1); +static void print_arr3(m_arr3 b1); +static void print_wstr(CORBA_wchar *ws); + +static void free_etseq_buf(m_etseq *b); +static void free_et(m_et* b); + +#ifdef __WIN32__ +typedef struct { + long tv_sec; + long tv_usec; +} MyTimeval; +#else +typedef struct timeval MyTimeval; +#endif +static void my_gettimeofday(MyTimeval *tv); +static void showtime(MyTimeval *start, MyTimeval *stop); +static void usage(void); +static void done(int r); + + + +/* main */ + +#ifdef VXWORKS +int client(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + struct hostent *hp; + erlang_pid pid; + MyTimeval start, stop; + int i, fd, ires, tres; + IC_Env *env; + int tries = 0; + char *this_node_name = NULL; + char *peer_node = NULL; + char *peer_process_name = NULL; + char *cookie = NULL; + char host[HOSTNAMESZ + 1]; + TestFunc test_func = NULL; + TestCase *test_case; + char *test_case_name = NULL; + +#ifdef __WIN32__ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); + exit(1); + } +#endif + + progname = argv[0]; + host[HOSTNAMESZ] = '\0'; + if (gethostname(host, HOSTNAMESZ) < 0) { + fprintf(stderr, "Can't find own hostname\n"); + done(1); + } + if ((hp = gethostbyname(host)) == 0) { + fprintf(stderr, "Can't get ip address for host %s\n", host); + done(1); + } + for (i = 1; i < argc; i++) { + if (cmp_str(argv[i], "-help")) { + usage(); + done(0); + } else if (cmp_str(argv[i], "-this-node-name")) { + i++; + this_node_name = argv[i]; + } else if (cmp_str(argv[i], "-peer-node")) { + i++; + peer_node = argv[i]; + } else if (cmp_str(argv[i], "-peer-process-name")) { + i++; + peer_process_name = argv[i]; + } else if (cmp_str(argv[i], "-cookie")) { + i++; + cookie = argv[i]; + } else if (cmp_str(argv[i], "-test-case")) { + i++; + test_case_name = argv[i]; + } else { + fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); + usage(); + done(1); + } + } + + if (this_node_name == NULL || peer_node == NULL || test_case_name == NULL + || peer_process_name == NULL || cookie == NULL) { + fprintf(stderr, "Error: missing option\n"); + usage(); + done(1); + } + + test_case = test_cases; + while (test_case->func) { + if (cmp_str(test_case->name, test_case_name)) { + test_func = test_case->func; + break; + } + test_case++; + } + if (test_func == NULL) { + fprintf(stderr, "Error: illegal test case: \"%s\"\n", test_case_name); + done(1); + } + + /* Behead hostname at first dot */ + for (i=0; host[i] != '\0'; i++) { + if (host[i] == '.') { host[i] = '\0'; break; } + } + sprintf(this_node, "%s@%s", this_node_name, host); + fprintf(stderr, "c_client: this node: \"%s\"\n", this_node); + fprintf(stderr, "c_client: peer node: \"%s\"\n", peer_node); + fprintf(stderr, "c_client: test case: \"%s\"\n", test_case_name); + + fprintf(stderr, "c_client: starting\n"); + + /* initialize erl_interface */ + erl_init(NULL, 0); + + for (tries = 0; tries < MAXTRIES; tries++) { + + /* connect to erlang node */ + + ires = erl_connect_xinit(host, this_node_name, this_node, + (struct in_addr *)*hp->h_addr_list, + cookie, 0); + + fprintf(stderr, "c_client: erl_connect_xinit(): %d\n", ires); + + fd = erl_connect(peer_node); + fprintf(stderr, "c_client: erl_connect(): %d\n", fd); + + if (fd >= 0) + break; + fprintf(stderr, "c_client: cannot connect, retrying\n"); + } + if (fd < 0) { + fprintf(stderr, "c_client: cannot connect, exiting\n"); + done(1); + } + env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); + env->_fd = fd; + strcpy(env->_regname, peer_process_name); + env->_to_pid = NULL; + env->_from_pid = &pid; + + strcpy(pid.node, this_node); + pid.num = fd; + pid.serial = 0; + pid.creation = 0; + + my_gettimeofday(&start); + tres = test_func(env); /* Call test case */ + my_gettimeofday(&stop); + showtime(&start, &stop); + erl_close_connection(fd); + + printf("c_client: env->_inbuf before : %d\n", INBUFSZ); + printf("c_client: env->_outbuf before : %d\n", OUTBUFSZ); + printf("c_client: env->_inbuf after : %d\n", env->_inbufsz); + printf("c_client: env->_outbuf after : %d\n", env->_outbufsz); + + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + done(tres); +} + +static void usage() +{ + fprintf(stderr, "Usage: %s [-help] -this-node-name <name> " + "-peer-node <nodename> -peer-process-name <name> " + "-cookie <cookie> -test-case <test case name>\n", progname); + fprintf(stderr, "Example:\n %s -this-node-name kalle " + "-peer-node olle@home -peer-process-name idltest " + "-cookie oa678er -test-case octet_test\n", progname); +} + +static void done(int r) +{ +#ifdef __WIN32__ + WSACleanup(); +#endif + exit(r); +} + + +/* TESTS */ + +static int void_test(IC_Env *env) +{ + fprintf(stdout, "\n======== m_i_void test ======\n\n"); + m_i_void_test(NULL,env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(1); +} + +static int long_test(IC_Env *env) +{ + long l = 4711, lo, lr; + + fprintf(stdout, "\n======== m_i_long test ======\n\n"); + lr = m_i_long_test(NULL, l, &lo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(l == lo && l == lr); + if (l != lo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", l, lo); + if (l != lr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", l, lr); + return -1; +} + +static int long_long_test(IC_Env *env) +{ + CORBA_long_long ll = 4711, llo, llr; + + fprintf(stdout, "\n======== m_i_longlong test ======\n\n"); + llr = m_i_longlong_test(NULL, ll, &llo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ll == llo && ll == llr); + if (ll != llo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", + ll, llo); + if (ll != llr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", ll, llr); + return -1; +} + +static int unsigned_short_test(IC_Env *env) +{ + unsigned short x, y = 2, z; + + fprintf(stdout, "\n======== m_i_ushort test ======\n\n"); + x = m_i_ushort_test(NULL, y, &z, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(y == z && y == x); + if (y != z) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", y, z); + if (y != x) + fprintf(stdout, " result error, sent: %d, got: %d\n", y, x); + return -1; +} + + +static int unsigned_long_test(IC_Env *env) +{ + unsigned long ul = 5050, ulo, ulr; + + fprintf(stdout, "\n======== m_i_ulong test ======\n\n"); + ulr = m_i_ulong_test(NULL, ul, &ulo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ul == ulo && ul == ulr); + if (ul != ulo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ul, ulo); + if (ul != ulr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", ul, ulr); + return -1; +} + +/* + * Note: CORBA_unsigned_long_long is in fact a plain long. + */ +static int unsigned_long_long_test(IC_Env *env) +{ + CORBA_unsigned_long_long ull = 5050, ullo, ullr; + + fprintf(stdout, "\n======== m_i_ulonglong test ======\n\n"); + ullr = m_i_ulonglong_test(NULL, ull, &ullo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ull == ullo && ull == ullr); + if (ull != ullo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ull, ullo); + if (ull != ullr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + ull, ullr); + return -1; +} + +static int double_test(IC_Env *env) +{ + double d = 12.1212, db, dr; + + fprintf(stdout, "\n======== m_i_double test ======\n\n"); + dr = m_i_double_test(NULL, d, &db, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(d == db && d == dr); + if (d != db) + fprintf(stdout, " out parameter error, sent: %f, got: %f\n", d, db); + if (d != dr) + fprintf(stdout, " result error, sent: %f, got: %f\n", d, dr); + return -1; +} + +static int char_test(IC_Env *env) +{ + char c = 'g', co, cr; + + /* char test */ + fprintf(stdout, "\n======== m_i_char test ======\n\n"); + cr = m_i_char_test(NULL, c, &co, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(c == co && c == cr); + if (c !=co) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", c, co); + if (c != cr) + fprintf(stdout, " result error, sent: %c, got: %c\n", c, cr); + return -1; +} + +static int wchar_test(IC_Env *env) +{ + CORBA_wchar wc = 103, wco, wcr; + + fprintf(stdout, "\n======== m_i_wchar test ======\n\n"); + wcr = m_i_wchar_test(NULL, wc, &wco, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(wc == wco && wc == wcr); + if (wc != wco) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + wc, wco); + if (wc != wcr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + wc, wcr); + return -1; +} + +static int octet_test(IC_Env *env) +{ + char o ='r', oo, or; + + fprintf(stdout, "\n======== m_i_octet test ======\n\n"); + or = m_i_octet_test(NULL, o, &oo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(o == oo && o == or); + if (o != oo) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", o, oo); + if (o != or) + fprintf(stdout, " result error, sent: %c, got: %c\n", o, or); + return -1; +} + +static int bool_test(IC_Env *env) +{ + unsigned char i = 0, io, ir; + + fprintf(stdout, "\n======== m_i_bool test ======\n\n"); + ir = m_i_bool_test(NULL, i, &io, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(i == io && i == ir); + if (i != io) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", i, io); + if (i != ir) + fprintf(stdout, " result error, sent: %d, got: %d\n", i, ir); + return -1; +} + +static int struct_test(IC_Env *env) +{ + m_b b = {4711, 'a'}, bo, br; + + fprintf(stdout, "\n======== m_i_struct test ======\n\n"); + br = m_i_struct_test(NULL, &b, &bo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_b(&b, &bo) && cmp_b(&b, &br)); + if (!cmp_b(&b, &bo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&bo); + fprintf(stdout, "\n"); + } + if (!cmp_b(&b, &br)) { + fprintf(stdout, " result error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&br); + fprintf(stdout, "\n"); + } + return -1; +} + +static int struct2_test(IC_Env *env) +{ + m_es esi = {m_peach, 5050}, eso, esr; + + fprintf(stdout, "\n======== m_i_struct2 test ======\n\n"); + esr = m_i_struct2_test(NULL, &esi, &eso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_es(&esi, &eso) && cmp_es(&esi, &esr)); + if (!cmp_es(&esi, &eso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&eso); + fprintf(stdout, "\n"); + } + if (!cmp_es(&esi, &esr)) { + fprintf(stdout, " result error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&esr); + fprintf(stdout, "\n"); + } + return -1; +} + + +static int seq1_test(IC_Env *env) +{ + m_bseq bs, *bso, *bsr; + + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + bs._length = 3; + bs._buffer = ba; + + fprintf(stdout, "\n======== m_i_seq1 test ======\n\n"); + bsr = m_i_seq1_test(NULL, &bs, &bso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_bseq(&bs, bso) && cmp_bseq(&bs, bsr)); + if (!cmp_bseq(&bs, bso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bso); + fprintf(stdout, "\n"); + } + if (!cmp_bseq(&bs, bsr)) { + fprintf(stdout, " result error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bsr); + fprintf(stdout, "\n"); + } + CORBA_free(bso); + CORBA_free(bsr); + return -1; +} + +static int seq2_test(IC_Env *env) +{ + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + m_a a; + m_a aa[2]; + m_aseq as, *aso, *asr; + + a.l = 9999; + a.y._length = 3; + a.y._buffer = ba; + a.d = 66.89898989; + + aa[0] = a; + aa[1] = a; + as._length = 2; + as._buffer = aa; + + fprintf(stdout, "\n======== m_i_seq2 test ======\n\n"); + asr = m_i_seq2_test(NULL, &as, &aso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_aseq(&as, aso) && cmp_aseq(&as, asr)); + if (!cmp_aseq(&as, aso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(aso); + fprintf(stdout, "\n"); + } + if (!cmp_aseq(&as, asr)) { + fprintf(stdout, " result error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(asr); + fprintf(stdout, "\n"); + } + CORBA_free(aso); + CORBA_free(asr); + return -1; +} + +static int seq3_test(IC_Env *env) +{ + m_lseq lsi, *lso, *lsr; + long al[500]; + int i=0; + + for (i = 0; i < 500; i++) + al[i]=i; + lsi._length = 500; + lsi._buffer = al; + + fprintf(stdout, "\n======== m_i_seq3 test ======\n\n"); + lsr = m_i_seq3_test(NULL, &lsi, &lso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_lseq(&lsi, lso) && cmp_lseq(&lsi, lsr)); + if (!cmp_lseq(&lsi, lso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lso); + fprintf(stdout, "\n"); + } + if (!cmp_lseq(&lsi, lsr)) { + fprintf(stdout, " result error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lsr); + fprintf(stdout, "\n"); + } + CORBA_free(lso); + CORBA_free(lsr); + return -1; +} + +static int seq4_test(IC_Env *env) +{ + char *stra0[3] = {"a", "long", "time"}; + char *stra1[3] = {"ago", "there", "was"}; + char *stra2[3] = {"a", "buggy", "compiler"}; + m_sstr3 str3s[3] = {{3, 3, stra0}, {3, 3, stra1}, {3, 3, stra2}}; + m_ssstr3 str3ssi = {3, 3, str3s}; + m_ssstr3 *str3sso, *str3ssr; + + fprintf(stdout, "\n======== m_i_seq4 test ======\n\n"); + str3ssr = m_i_seq4_test(NULL, &str3ssi, &str3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssstr3(&str3ssi, str3sso) && + cmp_ssstr3(&str3ssi, str3ssr)); + if (!cmp_ssstr3(&str3ssi, str3sso)){ + fprintf(stdout, " out parameter error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssstr3(&str3ssi, str3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(str3sso); + CORBA_free(str3ssr); + return -1; +} + +static int seq5_test(IC_Env *env) +{ + m_arr3 arr3a[3] = { + {4711, 18931947, 3}, + {4711, 18931947, 3}, + {4711, 18931947, 3}}; + m_sarr3 arr3sa[3] = {{3, 3, arr3a}, {3, 3, arr3a}, {3, 3, arr3a}}; + m_ssarr3 arr3ssi = {3, 3, arr3sa}; + m_ssarr3 *arr3sso; + m_ssarr3 *arr3ssr; + + fprintf(stdout, "\n======== m_i_seq5 test ======\n\n"); + arr3ssr = m_i_seq5_test(NULL, &arr3ssi, &arr3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssarr3(&arr3ssi, arr3sso) && + cmp_ssarr3(&arr3ssi, arr3ssr)); + if (!cmp_ssarr3(&arr3ssi, arr3sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssarr3(&arr3ssi, arr3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(arr3sso); + CORBA_free(arr3ssr); + return -1; +} + +static int array1_test(IC_Env *env) +{ + int i; + long al[500]; + m_arr1 alo; + m_arr1_slice* alr; + + for (i = 0; i < 500; i++) + al[i]=i; + + fprintf(stdout, "\n======== m_i_array1 test ======\n\n"); + alr = m_i_array1_test(NULL, al, alo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_arr1(al, alo) && cmp_arr1(al, alr)); + if (!cmp_arr1(al, alo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alo); + fprintf(stdout, "\n"); + } + if (!cmp_arr1(al,alr)) { + fprintf(stdout, " result error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alr); + fprintf(stdout, "\n"); + } + free(alo); + free(alr); + return -1; +} + +static int array2_test(IC_Env *env) +{ + long dl[2][3] = {{11, 2, 7}, {22, 8 ,13}}; + m_dd dlo; + m_dd_slice* dlr; + + fprintf(stdout, "\n======== m_i_array2 test ======\n\n"); + dlr = m_i_array2_test(NULL, dl, dlo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_dd(dl,dlo) && cmp_dd(dl,dlr)); + if (!cmp_dd(dl,dlo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlo); + fprintf(stdout, "\n"); + } + if (!cmp_dd(dl,dlr)) { + fprintf(stdout, " result error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlr); + fprintf(stdout, "\n"); + } + free(*dlr); + return -1; +} + +static int enum_test(IC_Env *env) +{ + m_fruit ei = m_banana, eo, er; + + fprintf(stdout, "\n======== m_i_enum test ======\n\n"); + er = m_i_enum_test(NULL, ei, &eo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ei == eo && ei == er); + if (ei != eo) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", ei, eo); + if (ei != er) + fprintf(stdout, " result error, sent: %d, got: %d\n", ei, er); + return -1; +} + +static int string1_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string1 test ======\n\n"); + sr = m_i_string1_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, sr)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string2_test(IC_Env *env) +{ + char* sa[3] = {"hello", "foo", "bar"}; + m_sseq ssi = {3, 3, sa}; + m_sseq *sso, *ssr; + + fprintf(stdout, "\n======== m_i_string2 test ======\n\n"); + ssr = m_i_string2_test(NULL, &ssi, &sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_sseq(&ssi, sso) && cmp_sseq(&ssi, sso)); + if (!cmp_sseq(&ssi, sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(sso); + } + if (!cmp_sseq(&ssi, ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(ssr); + } + CORBA_free(sso); + CORBA_free(ssr); + return -1; +} + +static int string3_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string3 test ======\n\n"); + sr = m_i_string3_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, so)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string4_test(IC_Env *env) +{ + char as1[100] = "a string", as2[200] = "help", as3[200] = "hello there"; + m_strRec stri = { 1, /* dd */ + as1, /* str4 */ + {{'a', 'k'}, {'z', 'g'}, {'n', 'q'}}, /* str7 */ + {3, 3, "buf"}, /* str5 */ + as2, /* str6 */ + {'m', 'f', 'o'}, /* str8 */ + as3, /* str9 */ + {3, 3, "stu"} /* str10 */ + }; + m_strRec *stro, *strr; + + fprintf(stdout, "\n======== m_i_string4 test ======\n\n"); + strr = m_i_string4_test(NULL, &stri, &stro, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_strRec(&stri,stro) && cmp_strRec(&stri,strr)); + if (!cmp_strRec(&stri,stro)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(stro); + fprintf(stdout, "\n"); + } + if (!cmp_strRec(&stri,strr)) { + fprintf(stdout, " result error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(strr); + fprintf(stdout, "\n"); + } + CORBA_free(stro); + CORBA_free(strr); + return -1; +} + + +static int pid_test(IC_Env *env) +{ + erlang_pid pid = {"", 7, 0, 0}, pido, pidr; + + strcpy(pid.node, this_node), /* this currently running node */ + fprintf(stdout, "\n======== m_i_pid test ======\n\n"); + pidr = m_i_pid_test(NULL, &pid, &pido, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_pid(&pid, &pido) && cmp_pid(&pid, &pidr)); + if (!cmp_pid(&pid, &pido)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pido); + } + if (!cmp_pid(&pid, &pidr)) { + fprintf(stdout, " result error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pidr); + } + return -1; +} + +static int port_test(IC_Env *env) +{ + erlang_port porti = {"node", 5, 1}, porto, portr; + + fprintf(stdout, "\n======== m_i_port test ======\n\n"); + portr = m_i_port_test(NULL, &porti, &porto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_port(&porti, &porto) && cmp_port(&porti, &portr)); + if (!cmp_port(&porti, &porto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&porto); + } + if (!cmp_port(&porti, &portr)) { + fprintf(stdout, " result error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&portr); + } + return -1; +} + +static int ref_test(IC_Env *env) +{ + erlang_ref refi = { "node1", 3, {1, 2, 3}, 1}, + refo, refr; + + fprintf(stdout, "\n======== m_i_ref test ======\n\n"); + refr = m_i_ref_test(NULL, &refi, &refo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ref(&refi, &refo) && cmp_ref(&refi, &refr)); + if (!cmp_ref(&refi, &refo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refo); + } + if (!cmp_ref(&refi, &refr)) { + fprintf(stdout, " result error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refr); + } + return -1; +} + +static int term_test(IC_Env *env) +{ + ETERM *ti, *to, *tr; + + ti = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + + fprintf(stdout, "\n======== m_i_term test ======\n\n"); + tr = m_i_term_test(NULL, ti, &to, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(ti, to) && erl_match(ti, tr)); + if (!erl_match(ti, to)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(to); + } + if (!erl_match(ti, tr)) { + fprintf(stdout, " result error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(tr); + } + erl_free_term(ti); + erl_free_term(to); + erl_free_term(tr); + return -1; +} + +static int typedef_test(IC_Env *env) +{ + m_banan mbi, mbo; /* erlang_port */ + m_apa mai; /* ETERM* */ + m_apa mao = NULL; + long tl; + + strcpy(mbi.node,"node"); + mbi.id = 15; + mbi.creation = 1; + + fprintf(stdout, "\n======== m_i_typedef test ======\n\n"); + mai = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + tl = m_i_typedef_test(NULL, mai, &mbi, &mao, &mbo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(mai, mao) && cmp_port(&mbi, &mbo) && tl == 4711); + if (!erl_match(mai, mao)) { + fprintf(stdout, " out parameter error (term), sent:\n"); + print_term(mai); + fprintf(stdout, "got:\n"); + print_term(mao); + } + if (!cmp_port(&mbi, &mbo)) { + fprintf(stdout, " out parameter error (port), sent:\n"); + print_port(&mbi); + fprintf(stdout, "got:\n"); + print_port(&mbo); + } + if (tl != 4711) { + fprintf(stdout, " result error, sent: 4711, got %ld\n", tl); + } + erl_free_term(mai); + erl_free_term(mao); + return -1; +} + +static int inline_sequence_test(IC_Env *env) +{ + int i; + long al[500]; + m_s isi = {4711, {500, 10, al}}, + *iso, *isr; + + for (i = 0; i < 500; i++) + al[i]=i; + fprintf(stdout, "\n======== m_i_inline_sequence test ======\n\n"); + isr = m_i_inline_sequence_test(NULL, &isi, &iso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_s(&isi, iso) && cmp_s(&isi, isr)); + if (!cmp_s(&isi, iso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(iso); + } + if (!cmp_s(&isi, isr)) { + fprintf(stdout, " result error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(isr); + } + CORBA_free(iso); + CORBA_free(isr); + return -1; +} + +static int term_sequence_test(IC_Env *env) +{ + ETERM* et_array[4] = { + erl_format("[{apa, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{banan, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{apelsin, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{mango, 1, 23}, \"string\", {1.23, 45}]")}; + m_etseq etsi = {4, 4, et_array}, *etso, *etsr; + + fprintf(stdout, "\n======== m_i_term_sequence test ======\n\n"); + etsr = m_i_term_sequence_test(NULL, &etsi, &etso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_etseq(&etsi, etso) && cmp_etseq(&etsi, etsr)); + if (!cmp_etseq(&etsi, etso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etso); + } + if (!cmp_etseq(&etsi, etsr)) { + fprintf(stdout, " result error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etsr); + } + free_etseq_buf(&etsi); + free_etseq_buf(etso); + free_etseq_buf(etsr); + CORBA_free(etso); + CORBA_free(etsr); + return -1; +} + +static int term_struct_test(IC_Env *env) +{ + m_et eti = { erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"), + 121212 }; + m_et eto, etr; + + fprintf(stdout, "\n======== m_i_term_struct test ======\n\n"); + etr = m_i_term_struct_test(NULL, &eti, &eto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_et(&eti, &eto) && cmp_et(&eti, &etr)); + if (!cmp_et(&eti, &eto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&eto); + } + if (!cmp_et(&eti, &etr)) { + fprintf(stdout, " result error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&etr); + } + free_et(&eti); + free_et(&eto); + free_et(&etr); + return -1; +} + +static int wstring1_test(IC_Env *env) +{ + CORBA_wchar wsi[] = {100, 101, 102, 103, 104, 0}, *wso, *wsr; + + fprintf(stdout, "\n======== m_i_wstring1 test ======\n\n"); + wsr = m_i_wstring1_test(NULL, wsi, &wso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_wstr(wsi, wso) && cmp_wstr(wsi, wsr)); + if (!cmp_wstr(wsi, wso)) { + fprintf(stdout, " out parameter error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wso); + } + if (!cmp_wstr(wsi, wsr)) { + fprintf(stdout, " result error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wsr); + } + CORBA_free(wso); + CORBA_free(wsr); + return -1; +} + +/* Compare functions */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2) +{ + int i; + + if (a1->_length != a2->_length) + return 0; + for (i = 0; i < a1->_length; i++) + if (cmp_a(&(a1->_buffer[i]), &(a2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_a(m_a *a1, m_a *a2) +{ + return a1->l == a2->l && + a1->d == a2->d && + cmp_bseq(&a1->y, &a2->y); +} + +static int cmp_bseq(m_bseq *b1, m_bseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (cmp_b(&(b1->_buffer[i]), &(b2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_b(m_b *b1, m_b *b2) +{ + return b1->l == b2->l && b1->c == b2->c; +} + +static int cmp_lseq(m_lseq *b1, m_lseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (b1->_buffer[i] != b2->_buffer[i]) + return 0; + return 1; +} + +static int cmp_etseq(m_etseq *b1, m_etseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!erl_match(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + +static int cmp_et(m_et* b1, m_et *b2) +{ + return erl_match(b1->e, b2->e) && b1->l == b2->l; +} + +static int cmp_es(m_es *b1, m_es *b2) +{ + return b1->f == b2->f && b1->l == b2->l; +} + +static int cmp_arr1(m_arr1 b1, m_arr1 b2) +{ + int i; + + for (i = 0; i < 500; i++) + if (b1[i] != b2[i]) + return 0; + return 1; +} + +static int cmp_dd(m_dd b1, m_dd b2) +{ + + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1[i][j] != b2[i][j]) + return 0; + return 1; +} + + + +static int cmp_strRec(m_strRec *b1, m_strRec *b2) +{ + int i, j; + + if (b1->bb != b2->bb) + return 0; + if (!cmp_str(b1->str4,b2->str4)) + return 0; + if (b1->str5._length != b2->str5._length) + return 0; + for (j = 0; j < b1->str5._length; j++) + if (b1->str5._buffer[j] != b2->str5._buffer[j]) + return 0; + if (!cmp_str(b1->str6,b2->str6)) + return 0; + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1->str7[i][j] != b2->str7[i][j]) + return 0; + for (j = 0; j < 3; j++) + if (b1->str8[j] != b2->str8[j]) + return 0; + if (!cmp_str(b1->str9,b2->str9)) + return 0; + if (b1->str10._length != b2->str10._length) + return 0; + for (j = 0; j < b1->str10._length; j++) + if (b1->str10._buffer[j] != b2->str10._buffer[j]) + return 0; + return 1; +} + + +static int cmp_sseq(m_sseq *b1, m_sseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!cmp_str(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + + +static int cmp_pid(erlang_pid *p1, erlang_pid *p2) +{ + return cmp_str(p1->node,p2-> node) && + p1->num == p2->num && + p1->serial == p2->serial && + p1->creation == p2->creation; +} + +static int cmp_port(erlang_port *p1, erlang_port *p2) +{ + return cmp_str(p1->node,p2-> node) && p1->id == p2->id; +} + +static int cmp_ref(erlang_ref *p1, erlang_ref *p2) +{ + return cmp_str(p1->node, p2->node) && + p1->len == p2->len && + (p1->len < 1 || p1->n[0] == p2->n[0]) && + (p1->len < 2 || p1->n[1] == p2->n[1]) && + (p1->len < 3 || p1->n[2] == p2->n[2]); +} + +static int cmp_s(m_s *b1, m_s *b2) +{ + int i; + + if (b1->l != b2->l) + return 0; + if (b1->sl._length != b2->sl._length) + return 0; + for (i = 0; i < b1->sl._length; i++) + if (b1->sl._buffer[i] != b2->sl._buffer[i]) + return 0; + return 1; +} + + +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2) +{ + int i,j; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (b1->_buffer[i]._length != b2->_buffer[i]._length) + return 0; + for (j = 0; j < b1->_buffer[i]._length; j++) + if (!cmp_str(b1->_buffer[i]._buffer[j], + b2->_buffer[i]._buffer[j])) + return 0; + } + return 1; +} + + + +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_sarr3(&b1->_buffer[i], &b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_arr3(b1->_buffer[i], b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_arr3(m_arr3 b1, m_arr3 b2) +{ + int i; + + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) { + if (b1[i] != b2[i]) + return 0; + } + return 1; +} + +/* Print functions */ +static void print_aseq(m_aseq *a) +{ + int i; + fprintf(stdout, "\nm_aseq size: %ld --------\n", a->_length); + for (i = 0; i < a->_length; i++) + print_a(&(a->_buffer[i])); +} + +static void print_a(m_a *a) +{ + fprintf(stdout, "\nm_a --------\n l: %ld\n d:%f\n", a->l, a->d); + print_bseq(&a->y); +} + +static void print_bseq(m_bseq *b) +{ + int i; + + fprintf(stdout, "\nm_bseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + print_b(&(b->_buffer[i])); +} + +static void print_lseq(m_lseq *b) +{ + int i; + + fprintf(stdout, "\nm_lseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "[%d]: %ld\n", i, b->_buffer[i]); +} + +static void print_b(m_b *b) +{ + fprintf(stdout, "\nm_b --------\n l: %ld\n c: %c\n", b->l, b->c); +} + + +static void print_etseq(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) { + fprintf(stdout, "[%d]:\n", i); + erl_print_term(stdout, b->_buffer[i]); + } +} + + +static void print_et(m_et* b) +{ + fprintf(stdout, "\net struct --------\n"); + erl_print_term(stdout, b->e); + fprintf(stdout, "long: %ld\n", b->l); + fprintf(stdout, "\n--------\n"); +} + +static void print_es(m_es *b) +{ + fprintf(stdout, "\nm_es --------\n f: %d\n l: %ld\n", b->f, b->l); +} + + +static void print_arr1(long a[10]) +{ + int i; + + for (i = 0; i < 10; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, a[i]); +} + +static void print_dd(long a[2][3]) +{ + int i, j; + + fprintf(stdout, "\nlong dd[2][3] --------\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "\n[%d][%d]: %ld\n", i, j, a[i][j]); +} + + +static void print_strRec(m_strRec* sr) +{ + int i, j; + + fprintf(stdout, "\nboolean bb : %d\n",sr->bb); + fprintf(stdout, "string str4 : %s\n",sr->str4); + fprintf(stdout, "str7[2][3] :\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "str7[%d][%d]: %ld\n", i, j, sr->str7[i][j]); + fprintf(stdout, "str5._length : %ld\n",sr->str5._length); + for (j = 0; j < sr->str5._length; j++) + fprintf(stdout, "str5._buffer[%d]: %c\n", j, sr->str5._buffer[j]); + fprintf(stdout, "string str6 : %s\n",sr->str6); + fprintf(stdout, "str8 :\n"); + for (j = 0; j < 3; j++) + fprintf(stdout, "str8[%d]: %c\n", j, sr->str8[j]); + fprintf(stdout, "string str9 : %s\n",sr->str9); + fprintf(stdout, "str10._length : %ld\n",sr->str10._length); + for (j = 0; j < sr->str10._length; j++) + fprintf(stdout, "str10._buffer[%d]: %c\n", j, sr->str10._buffer[j]); +} + +static void print_sseq(m_sseq *b) +{ + int i; + + fprintf(stdout, "\nm_sseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "%s\n", b->_buffer[i]); + +} + + +static void print_pid(erlang_pid *p) +{ + fprintf(stdout, "\nerlang_pid --------\n node: %s\n num: %d\n " + "serial: %d\n creation: %d\n", + p->node, p->num, p->serial, p->creation); +} + +static void print_port(erlang_port *p) +{ + fprintf(stdout, "\nerlang_port --------\n node: %s\n id: %d\n " + "creation: %d\n", p->node, p->id, p->creation); +} + +static void print_ref(erlang_ref *p) +{ + fprintf(stdout, "\nerlang_ref --------\n node: %s\n len: %d\n " + "n[0]: %d\n n[1]: %d\n n[2]: %d\n creation: %d\n", + p->node, p->len, p->n[0], p->n[1], p->n[2], p->creation); +} + +static void print_term(ETERM *t) +{ + fprintf(stdout, "\nETERM --------\n"); + erl_print_term(stdout, t); + fprintf(stdout, "\n--------\n"); +} + +static void print_s(m_s *p) +{ + int i; + + fprintf(stdout, "\n%ld\n", p->l); + for (i = 0; i < p->sl._length; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, p->sl._buffer[i]); +} + + +static void print_ssstr3(m_ssstr3 *b1) +{ + int i,j; + + fprintf(stdout, "\nSSSTR3 --------\n"); + fprintf(stdout,"b1->_length = %ld\n",b1->_length); + for (i = 0; i < b1->_length; i++) { + fprintf(stdout,"\nb1->_buffer[%d]._length %ld\n", + i, b1->_buffer[i]._length); + for (j = 0; j < b1->_buffer[i]._length; j++) + fprintf(stdout,"b1->_buffer[%d]._buffer[%d] = %s\n", + i, j, b1->_buffer[i]._buffer[j]); + } + fprintf(stdout, "\n--------\n"); +} + +static void print_wstr(CORBA_wchar *ws) +{ + int i = 0; + + fprintf(stdout, "\nwstr --------\n"); + while (ws[i]) { + fprintf(stdout, "[%d]: %ld\n", i, ws[i]); + i++; + } + fprintf(stdout, "\n--------\n"); +} + + +static void print_ssarr3(m_ssarr3 *b1) +{ + int i; + + fprintf(stdout, "\nssarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_sarr3(&b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_sarr3(m_sarr3 *b1) +{ + int i; + + fprintf(stdout, "\nsarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_arr3(b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_arr3(m_arr3 b1) +{ + int i; + + fprintf(stdout, "\narr3 --------\n"); + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) + fprintf(stdout, "%ld ", b1[i]); + fprintf(stdout, "\n--------\n"); +} + +static void free_etseq_buf(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) + erl_free_term(b->_buffer[i]); +} + +static void free_et(m_et* b) +{ + erl_free_term(b->e); +} + +static void showtime(MyTimeval *start, MyTimeval *stop) +{ + MyTimeval elapsed; + + elapsed.tv_sec = stop->tv_sec - start->tv_sec; + elapsed.tv_usec = stop->tv_usec - start->tv_usec; + while (elapsed.tv_usec < 0) { + elapsed.tv_sec -= 1; + elapsed.tv_usec += 1000000; + } + fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); +} + +static void my_gettimeofday(MyTimeval *tv) +#ifdef __WIN32__ +#define EPOCH_JULIAN_DIFF 11644473600i64 +{ + SYSTEMTIME t; + FILETIME ft; + LONGLONG lft; + + GetSystemTime(&t); + SystemTimeToFileTime(&t, &ft); + memcpy(&lft, &ft, sizeof(lft)); + tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); + tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); +} +#elif defined VXWORKS +{ + int rate = sysClkRateGet(); /* Ticks per second */ + unsigned long ctick = tickGet(); + tv->tv_sec = ctick / rate; /* secs since reboot */ + tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; +} +#else +{ + gettimeofday(tv, NULL); +} +#endif diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl new file mode 100644 index 0000000000..ccb8f54508 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl @@ -0,0 +1,174 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2001-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +#include "erlang.idl" + + +const short TestConst = 1; + +module m { + + const short TestConst = 2; + + struct b { + long l; + char c; + }; + + struct simple { + long l; + b b_t; + }; + + enum fruit {orange, banana, apple, peach, pear}; + + typedef sequence<long> lseq; + + typedef sequence<b> bseq; + + struct a { + long l; + bseq y; + double d; + }; + + typedef sequence<a> aseq; + + typedef sequence<string> sseq; + typedef string str; + typedef long myLong; + + typedef long arr1[500], dd[2][3]; + + typedef erlang::term apa; + typedef erlang::port banan; + + typedef sequence<erlang::term> etseq; + + struct s { + long l; + sequence<long> sl; + }; + + struct es { + fruit f; + myLong l; + }; + + struct et { + erlang::term e; + long l; + }; + + + typedef sequence<char> str1; + typedef string<12> str2; + typedef char str3[3]; + + typedef sequence<string> sstr3; // sequence of string + typedef sequence<sstr3> ssstr3; // sequence of sequences of strings + + typedef long arr3[3]; // array of long + typedef sequence<arr3> sarr3; // sequence of array + typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings + + struct strRec{ + boolean bb; + string str4; + long str7[3][2]; + sequence<char> str5; + string<12> str6; + str3 str8; + str2 str9; + str1 str10; + }; + + + struct dyn { + long l; + sequence<long> sl; + }; + typedef dyn arr2[1][2]; + + + interface i { + + const short TestConst = 3; + + //arr2 suck(in arr2 x, out arr2 y ); + + ///////////////////////////////// attribute long l; + + // simple types + void void_test(); + long long_test(in long a, out long a1); + long long longlong_test(in long long a, out long long a1); + unsigned short ushort_test(in unsigned short a, out unsigned short a1); + unsigned long ulong_test(in unsigned long a, out unsigned long a1); + unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1); + double double_test(in double a, out double a1); + char char_test(in char a, out char a1); + wchar wchar_test(in wchar a, out wchar a1); + octet octet_test(in octet a, out octet a1); + boolean bool_test(in boolean a, out boolean a1); + + // Seq. and struct tests + b struct_test(in b a, out b a1); + es struct2_test(in es a, out es a1); + //simple struct3_test(in simple x, out simple y); + bseq seq1_test(in bseq a, out bseq a1); + aseq seq2_test(in aseq a, out aseq a1); + lseq seq3_test(in lseq a, out lseq a1); + ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1); + ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1); + + // Array tests + arr1 array1_test(in arr1 a, out arr1 a1); + dd array2_test(in dd a, out dd a1); + + // enum test + fruit enum_test(in fruit a, out fruit a1); + + // string tests + string string1_test(in string a, out string a1); + wstring wstring1_test(in wstring a, out wstring a1); + sseq string2_test(in sseq a, out sseq a1); + str string3_test(in str a, out str a1); + strRec string4_test(in strRec a, out strRec a1); + + // Special erlang types + erlang::pid pid_test(in erlang::pid a, out erlang::pid a1); + erlang::port port_test(in erlang::port a, out erlang::port a1); + erlang::ref ref_test(in erlang::ref a, out erlang::ref a1); + erlang::term term_test(in erlang::term a, out erlang::term a1); + + // typedef test + long typedef_test(in apa a, in banan b, out apa a1, out banan b1); + + // inlined seq. test + s inline_sequence_test(in s a, out s a1); + + // term seq. test + etseq term_sequence_test(in etseq a, out etseq a1); + // term struct test + et term_struct_test(in et a, out et a1); + + }; + +}; diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl new file mode 100644 index 0000000000..dffbbb059c --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl @@ -0,0 +1,28 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(erl_server). + +-export([run/0, stop/0]). + +run() -> + m_i:oe_create(). + +stop() -> + gen_server:cast(cidl_test, stop). diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl new file mode 100644 index 0000000000..cfcaa793a5 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl @@ -0,0 +1,161 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(m_i_impl). +-include("m.hrl"). + +-export([init/1, terminate/2, void_test/1, long_test/2, ushort_test/2, + longlong_test/2, ulong_test/2, ulonglong_test/2, + double_test/2, char_test/2, wchar_test/2, octet_test/2, + bool_test/2, struct_test/2, struct2_test/2, seq1_test/2, + seq2_test/2, seq3_test/2, seq4_test/2, seq5_test/2, + array1_test/2, array2_test/2, enum_test/2, string1_test/2, + string2_test/2, string3_test/2, string4_test/2, pid_test/2, + port_test/2, ref_test/2, term_test/2, typedef_test/3, + inline_sequence_test/2, '_set_l'/2, '_get_l'/1, + term_struct_test/2, term_sequence_test/2, wstring1_test/2]). + +-define(PRINTDEBUG(Case), + io:format("erl_server: case: ~p~n" + "erl_server: location: ~p~n", [Case, [?FILE, ?LINE]])). +-define(PRINTDEBUG2(Case, Msg), + io:format("erl_server: case: ~p~n" + "erl_server: Msg: ~p~n" + "erl_server: location: ~p~n", [Case, Msg, [?FILE, ?LINE]])). + +init(Env) -> + {ok, []}. + +terminate(F, R) -> + ok. + +'_get_l'(State) -> + ?PRINTDEBUG("_get_l"), + {reply, State, State}. +void_test(State) -> + ?PRINTDEBUG("void_test"), + {reply, ok, State}. + +'_set_l'(State, V) -> + ?PRINTDEBUG2("_set_l", V), + {reply, ok, V}. +ushort_test(State, V) -> + ?PRINTDEBUG2("ushort_test", V), + {reply, {V, V}, State}. +long_test(State, V) -> + ?PRINTDEBUG2("long_test", V), + {reply, {V, V}, State}. +longlong_test(State, V) -> + ?PRINTDEBUG2("longlong_test", V), + {reply, {V, V}, State}. +ulong_test(State, V) -> + ?PRINTDEBUG2("ulong_test", V), + {reply, {V, V}, State}. +ulonglong_test(State, V) -> + ?PRINTDEBUG2("ulonglong_test", V), + {reply, {V, V}, State}. +double_test(State, V) -> + ?PRINTDEBUG2("double_test", V), + {reply, {V, V}, State}. +char_test(State, V) -> + ?PRINTDEBUG2("char_test", V), + {reply, {V, V}, State}. +wchar_test(State, V) -> + ?PRINTDEBUG2("wchar_test", V), + {reply, {V, V}, State}. +octet_test(State, V) -> + ?PRINTDEBUG2("octet_test", V), + {reply, {V, V}, State}. +bool_test(State, V) -> + ?PRINTDEBUG2("bool_test", V), + {reply, {V, V}, State}. + +struct_test(State, V) -> + ?PRINTDEBUG2("struct_test", V), + {reply, {V, V}, State}. +struct2_test(State, V) -> + ?PRINTDEBUG2("struct2_test", V), + {reply, {V, V}, State}. +seq1_test(State, V) -> + ?PRINTDEBUG2("seq1_test", V), + {reply, {V, V}, State}. +seq2_test(State, V) -> + ?PRINTDEBUG2("seq2_test", V), + {reply, {V, V}, State}. +seq3_test(State, V) -> + ?PRINTDEBUG2("seq3_test", V), + {reply, {V, V}, State}. +seq4_test(State, V) -> + ?PRINTDEBUG2("seq4_test", V), + {reply, {V, V}, State}. +seq5_test(State, V) -> + ?PRINTDEBUG2("seq5_test", V), + {reply, {V, V}, State}. +array1_test(State, V) -> + ?PRINTDEBUG2("array1_test", V), + {reply, {V, V}, State}. +array2_test(State, V) -> + ?PRINTDEBUG2("array2_test", V), + {reply, {V, V}, State}. +enum_test(State, V) -> + ?PRINTDEBUG2("enum_test", V), + {reply, {V, V}, State}. +string1_test(State, V) -> + ?PRINTDEBUG2("string1_test", V), + {reply, {V, V}, State}. +string2_test(State, V) -> + ?PRINTDEBUG2("string2_test", V), + {reply, {V, V}, State}. +string3_test(State, V) -> + ?PRINTDEBUG2("string3_test", V), + {reply, {V, V}, State}. +string4_test(State, V) -> + ?PRINTDEBUG2("string4_test", V), + {reply, {V, V}, State}. +pid_test(State, V) -> + ?PRINTDEBUG2("pid_test", V), + {reply, {V, V}, State}. +port_test(State, V) -> + ?PRINTDEBUG2("port_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +ref_test(State, V) -> + ?PRINTDEBUG2("ref_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +term_test(State, V) -> + ?PRINTDEBUG2("term_test", V), + {reply, {V, V}, State}. +typedef_test(State, A, B) -> + ?PRINTDEBUG2("typedef_test", [A,B]), + {reply, {4711, A, B}, State}. +inline_sequence_test(State, V) -> + ?PRINTDEBUG2("inline_sequence_test", V), + {reply, {V, V}, State}. +term_sequence_test(State, V) -> + ?PRINTDEBUG2("term_sequence_test", V), + {reply, {V, V}, State}. +term_struct_test(State, V) -> + ?PRINTDEBUG2("term_struct_test", V), + {reply, {V, V}, State}. +wstring1_test(State, V) -> + ?PRINTDEBUG2("wstring1_test", V), + {reply, {V, V}, State}. + + + + diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE.erl b/lib/ic/test/c_client_erl_server_proto_SUITE.erl new file mode 100644 index 0000000000..58309a2221 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE.erl @@ -0,0 +1,315 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +%%---------------------------------------------------------------------- +%% Purpose : Test suite for c-client/erl-server +%%---------------------------------------------------------------------- + +-module(c_client_erl_server_proto_SUITE). +-include("test_server.hrl"). + +-export([init_per_testcase/2, fin_per_testcase/2, + all/1, void_test/1, long_test/1, long_long_test/1, + unsigned_short_test/1, unsigned_long_test/1, + unsigned_long_long_test/1, double_test/1, char_test/1, + wchar_test/1, octet_test/1, bool_test/1, struct_test/1, + struct2_test/1, seq1_test/1, seq2_test/1, seq3_test/1, + seq4_test/1, seq5_test/1, array1_test/1, array2_test/1, + enum_test/1, string1_test/1, string2_test/1, string3_test/1, + string4_test/1, pid_test/1, port_test/1, ref_test/1, term_test/1, + typedef_test/1, inline_sequence_test/1, term_sequence_test/1, + term_struct_test/1, wstring1_test/1]). + +-define(DEFAULT_TIMEOUT, 20000). +-define(PORT_TIMEOUT, 15000). +-define(ERLANG_SERVER_NAME, idl_erlang_server). +-define(C_CLIENT_NODE_NAME, c_client_idl_test). + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i, we have + %% to make sure we are using the right m_i module. + code:purge(m_i), + code:load_file(m_i), + + WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + +all(doc) -> + "Test of IC with a C-client and an Erlang generic server. " + "The communication is via Erlang distribution."; +all(suite) -> + [void_test, long_test, long_long_test, unsigned_short_test, + unsigned_long_test, unsigned_long_long_test, double_test, + char_test, wchar_test, octet_test, bool_test, struct_test, + struct2_test, seq1_test, seq2_test, seq3_test, seq4_test, + seq5_test, array1_test, array2_test, enum_test, string1_test, + string2_test, string3_test, string4_test, pid_test, port_test, + ref_test, term_test, typedef_test, inline_sequence_test, + term_sequence_test, term_struct_test, wstring1_test]. + + +array1_test(doc) -> ""; +array1_test(suite) -> []; +array1_test(Config) -> + do_test(array1_test, Config). + +array2_test(doc) -> ""; +array2_test(suite) -> []; +array2_test(Config) -> + do_test(array2_test, Config). + +bool_test(doc) -> ""; +bool_test(suite) -> []; +bool_test(Config) -> + do_test(bool_test, Config). + +char_test(doc) -> ""; +char_test(suite) -> []; +char_test(Config) -> + do_test(char_test, Config). + +double_test(doc) -> ""; +double_test(suite) -> []; +double_test(Config) -> + do_test(double_test, Config). + +enum_test(doc) -> ""; +enum_test(suite) -> []; +enum_test(Config) -> + do_test(enum_test, Config). + +inline_sequence_test(doc) -> ""; +inline_sequence_test(suite) -> []; +inline_sequence_test(Config) -> + do_test(inline_sequence_test, Config). + +long_long_test(doc) -> ""; +long_long_test(suite) -> []; +long_long_test(Config) -> + do_test(long_long_test, Config). + +long_test(doc) -> ""; +long_test(suite) -> []; +long_test(Config) -> + do_test(long_test, Config). + +octet_test(doc) -> ""; +octet_test(suite) -> []; +octet_test(Config) -> + do_test(octet_test, Config). + +pid_test(doc) -> ""; +pid_test(suite) -> []; +pid_test(Config) -> + do_test(pid_test, Config). + +port_test(doc) -> ""; +port_test(suite) -> []; +port_test(Config) -> + do_test(port_test, Config). + +ref_test(doc) -> ""; +ref_test(suite) -> []; +ref_test(Config) -> + do_test(ref_test, Config). + +seq1_test(doc) -> ""; +seq1_test(suite) -> []; +seq1_test(Config) -> + do_test(seq1_test, Config). + +seq2_test(doc) -> ""; +seq2_test(suite) -> []; +seq2_test(Config) -> + do_test(seq2_test, Config). + +seq3_test(doc) -> ""; +seq3_test(suite) -> []; +seq3_test(Config) -> + do_test(seq3_test, Config). + +seq4_test(doc) -> ""; +seq4_test(suite) -> []; +seq4_test(Config) -> + do_test(seq4_test, Config). + +seq5_test(doc) -> ""; +seq5_test(suite) -> []; +seq5_test(Config) -> + do_test(seq5_test, Config). + +string1_test(doc) -> ""; +string1_test(suite) -> []; +string1_test(Config) -> + do_test(string1_test, Config). + +string2_test(doc) -> ""; +string2_test(suite) -> []; +string2_test(Config) -> + do_test(string2_test, Config). + +string3_test(doc) -> ""; +string3_test(suite) -> []; +string3_test(Config) -> + do_test(string3_test, Config). + +string4_test(doc) -> ""; +string4_test(suite) -> []; +string4_test(Config) -> + do_test(string4_test, Config). + +struct2_test(doc) -> ""; +struct2_test(suite) -> []; +struct2_test(Config) -> + do_test(struct2_test, Config). + +struct_test(doc) -> ""; +struct_test(suite) -> []; +struct_test(Config) -> + do_test(struct_test, Config). + +term_sequence_test(doc) -> ""; +term_sequence_test(suite) -> []; +term_sequence_test(Config) -> + do_test(term_sequence_test, Config). + +term_struct_test(doc) -> ""; +term_struct_test(suite) -> []; +term_struct_test(Config) -> + do_test(term_struct_test, Config). + +term_test(doc) -> ""; +term_test(suite) -> []; +term_test(Config) -> + do_test(term_test, Config). + +typedef_test(doc) -> ""; +typedef_test(suite) -> []; +typedef_test(Config) -> + do_test(typedef_test, Config). + +unsigned_long_long_test(doc) -> ""; +unsigned_long_long_test(suite) -> []; +unsigned_long_long_test(Config) -> + do_test(unsigned_long_long_test, Config). + +unsigned_long_test(doc) -> ""; +unsigned_long_test(suite) -> []; +unsigned_long_test(Config) -> + do_test(unsigned_long_test, Config). + +unsigned_short_test(doc) -> ""; +unsigned_short_test(suite) -> []; +unsigned_short_test(Config) -> + do_test(unsigned_short_test, Config). + +void_test(doc) -> ""; +void_test(suite) -> []; +void_test(Config) -> + do_test(void_test, Config). + +wchar_test(doc) -> ""; +wchar_test(suite) -> []; +wchar_test(Config) -> + do_test(wchar_test, Config). + +wstring1_test(doc) -> ""; +wstring1_test(suite) -> []; +wstring1_test(Config) -> + do_test(wstring1_test, Config). + + +%% It is here that all tests really are done. +%% + +do_test(Case, Config) -> + %% Trap exits + process_flag(trap_exit, true), + %% Start the server + {ok, _Pid} = m_i:oe_create_link([], {local, ?ERLANG_SERVER_NAME}), + Node = atom_to_list(node()), + %% [NodeName, HostName] = string:tokens(Node, "@"), + DataDir = ?config(data_dir, Config), + %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]), + Cookie = atom_to_list(erlang:get_cookie()), + %% Start C-client node as a port program. + Cmd = filename:join([DataDir, "c_client"]) ++ + " -this-node-name " ++ atom_to_list(?C_CLIENT_NODE_NAME) ++ + " -peer-node " ++ Node ++ + " -peer-process-name " ++ atom_to_list(?ERLANG_SERVER_NAME) ++ + " -cookie " ++ Cookie ++ + " -test-case " ++ atom_to_list(Case), + Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]), + Res = wait_for_completion(Port), + %% Kill off node if there was timeout + case Res of + {error, timeout} -> + catch rpc:cast(?C_CLIENT_NODE_NAME, erlang, halt, [1]); + _ -> + ok + end, + process_flag(trap_exit, false), + catch m_i:stop(?ERLANG_SERVER_NAME), + ok = Res. + + +%% Wait for eof *and* exit status, but return if exit status indicates +%% an error, or we have been waiting more than PORT_TIMEOUT seconds. +%% +wait_for_completion(Port) -> + wait_for_completion(Port, 0). + +wait_for_completion(Port, N) when N < 2 -> + receive + {Port, {data, Bytes}} -> + %% Relay output + io:format("~s", [Bytes]), + wait_for_completion(Port, N); + {Port, {exit_status, 0}} -> + wait_for_completion(Port, N + 1); + {Port, {exit_status, Status}} -> + {error, Status}; + {Port, eof} -> + wait_for_completion(Port, N + 1); + {'EXIT', Port, Reason} -> + io:format("Port exited with reason: ~w~n", [Reason]), + wait_for_completion(Port, N); + {'EXIT', From, Reason} -> + io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]), + wait_for_completion(Port, N) + after ?PORT_TIMEOUT -> + {error, timeout} + end; +wait_for_completion(_, _) -> + ok. + + + diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src new file mode 100644 index 0000000000..3dcd1d9387 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src @@ -0,0 +1,146 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2003-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +# Makefile.src for c_client_erl_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@ + + +# Variables from ts: +# + +ERL_INCLUDE = @erl_include@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_LIB = @ic_libpath@@DS@@ic_lib@ + +ERL_INTERFACE_INCLUDE = @erl_interface_include@ +ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@ +ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@ +ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@ +ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@ + +CC = @CC@ +## XXX Should set warning flag with a DEBUG_FLAG +CFLAGS = @CFLAGS@ @DEFS@ -I@erl_include@ \ + -I@ic_include_path@ -I@erl_interface_include@ + +LD = @LD@ +LDFLAGS = @CROSSLDFLAGS@ +LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \ + $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS) +ERLC = erlc + +# Generated C header files +GEN_H_FILES = \ + m.h \ + m_i.h \ + oe_c_erl_test.h + +# Generated C files +GEN_C_FILES = \ + m.c \ + m_i.c \ + oe_c_erl_test.c \ + oe_code_m_a.c \ + oe_code_m_arr1.c \ + oe_code_m_arr2.c \ + oe_code_m_arr3.c \ + oe_code_m_aseq.c \ + oe_code_m_b.c \ + oe_code_m_bseq.c \ + oe_code_m_dd.c \ + oe_code_m_dyn.c \ + oe_code_m_dyn_sl.c \ + oe_code_m_es.c \ + oe_code_m_et.c \ + oe_code_m_etseq.c \ + oe_code_m_fruit.c \ + oe_code_m_lseq.c \ + oe_code_m_s.c \ + oe_code_m_s_sl.c \ + oe_code_m_sarr3.c \ + oe_code_m_simple.c \ + oe_code_m_ssarr3.c \ + oe_code_m_sseq.c \ + oe_code_m_ssstr3.c \ + oe_code_m_sstr3.c \ + oe_code_m_str1.c \ + oe_code_m_str3.c \ + oe_code_m_strRec.c \ + oe_code_m_strRec_str5.c \ + oe_code_m_strRec_str7.c + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_c_erl_test.hrl + +GEN_ERL_FILES = \ + m.erl \ + m_arr2.erl \ + m_arr3.erl \ + m_i.erl \ + m_str3.erl \ + oe_c_erl_test.erl + +C_FILES = $(GEN_C_FILES) c_client.c my.c + +OBJS = $(C_FILES:.c=@obj@) + +PGMS = c_client@exe@ + +ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl + +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(PGMS) $(EBINS) + +clean: + -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + +$(PGMS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(GEN_C_FILES) $(GEN_H_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_client}" \ + "+{user_protocol,my}" c_erl_test.idl + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" c_erl_test.idl + +.c@obj@: + $(CC) -c -o $*@obj@ $(CFLAGS) $< + +.erl.@EMULATOR@: + $(ERLC) -I $(IC_INCLUDE_PATH) $< + diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c new file mode 100644 index 0000000000..f352b91fd5 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c @@ -0,0 +1,1763 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2003-2010. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ +/* C-client for test of IC. + * + * TODO: + * + * 1. XXX #includes for VxWorks, Windows + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __WIN32__ +# include <unistd.h> +#endif + +#include <string.h> + +#ifdef __WIN32__ +# include <time.h> +# include <sys/timeb.h> +#elif defined VXWORKS +#include <time.h> +#include <sys/times.h> +#else +#include <sys/time.h> +#endif + +#include <ctype.h> + +#ifdef __WIN32__ +# include <winsock2.h> +# include <windows.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "ei.h" +#include "erl_interface.h" +#include "m_i.h" + +#define HOSTNAMESZ 256 +#define NODENAMESZ 512 + +#define INBUFSZ 10 +#define OUTBUFSZ 0 + +#define MAXTRIES 5 + +#define CHECK_EXCEPTION(x) \ + if ((x)->_major != CORBA_NO_EXCEPTION) { \ + fprintf(stderr,"\n\nException: %s\n\n", \ + (char *)CORBA_exception_value((x))); \ + CORBA_exception_free((x)); \ + return -1; \ + } \ + +/* XXX Should free things here too! */ +#define RETURN_IF_OK(x) \ + if ((x)) {\ + fprintf(stdout, "ok\n");\ + return 0;\ + }\ + +#define cmp_str(x,y) (!strcmp((x),(y))) +#define cmp_wstr(x,y) (!ic_wstrcmp((x),(y))) + +typedef CORBA_Environment IC_Env; + +typedef int (*TestFunc)(IC_Env *); +typedef struct { + char *name; + TestFunc func; +} TestCase; + +static char longtext[] = +"Introduction The IC application is an IDL compiler implemented in Erlang." +" The IDL compiler generates client stubs and server skeletons." +" Several back-ends are supported, and they fall into three main groups." +" For more details on IC compiler options consult the ic(3) manual page." +" Argument passing cases 1 Caller allocates all necessary storage," +" except that which may be encapsulated and managed within the parameter itself." +" 2 The caller allocates a pointer and passes it by reference to the callee." +" The callee sets the pointer to point to a valid instance of the parameter's type." +" The caller is responsible for releasing the returned storage." +" Following completion of a request, the caller is not allowed to modify any values" +" in the returned storage. To do so the caller must first copy the returned instance" +" into a new instance, then modify the new instance. 3 The caller allocates a" +" pointer to an array slice which has all the same dimensions of the original" +" array except the first, and passes it by reference to the callee. The callee sets" +" the pointer to point to a valid instance of the array. The caller is responsible for" +" releasing the returned storage. Following completion of a request, the caller is not" +" allowed to modify any values in the returned storage. To do so the caller must first" +" copy the returned instance into a new instance, then modify the new instance." +" Generated Files Two files will be generated for each scope. One set of files will be" +" generated for each module and each interface scope. An extra set is generated for" +" those definitions at top level scope. One of the files is a header file(.h), and the" +" other file is a C source code file (.c). In addition to these files a number of C" +" source files will be generated for type encodings, they are named according to the " +"following template: oe_code_<type>.c."; +static char this_node[NODENAMESZ + 1]; +static char *progname; + +/* Test function prototypes */ + +static int void_test(IC_Env *env); +static int long_test(IC_Env *env); +static int long_long_test(IC_Env *env); +static int unsigned_short_test(IC_Env *env); +static int unsigned_long_test(IC_Env *env); +static int unsigned_long_long_test(IC_Env *env); +static int double_test(IC_Env *env); +static int char_test(IC_Env *env); +static int wchar_test(IC_Env *env); +static int octet_test(IC_Env *env); +static int bool_test(IC_Env *env); +static int struct_test(IC_Env *env); +static int struct2_test(IC_Env *env); +static int seq1_test(IC_Env *env); +static int seq2_test(IC_Env *env); +static int seq3_test(IC_Env *env); +static int seq4_test(IC_Env *env); +static int seq5_test(IC_Env *env); +static int array1_test(IC_Env *env); +static int array2_test(IC_Env *env); +static int enum_test(IC_Env *env); +static int string1_test(IC_Env *env); +static int string2_test(IC_Env *env); +static int string3_test(IC_Env *env); +static int string4_test(IC_Env *env); +static int pid_test(IC_Env *env); +static int port_test(IC_Env *env); +static int ref_test(IC_Env *env); +static int term_test(IC_Env *env); +static int typedef_test(IC_Env *env); +static int inline_sequence_test(IC_Env *env); +static int term_sequence_test(IC_Env *env); +static int term_struct_test(IC_Env *env); +static int wstring1_test(IC_Env *env); + +static TestCase test_cases[] = { + {"void_test", void_test}, + {"long_test", long_test}, + {"long_long_test", long_long_test}, + {"unsigned_short_test", unsigned_short_test}, + {"unsigned_long_test", unsigned_long_test}, + {"unsigned_long_long_test", unsigned_long_long_test}, + {"double_test", double_test}, + {"char_test", char_test}, + {"wchar_test", wchar_test}, + {"octet_test", octet_test}, + {"bool_test", bool_test}, + {"struct_test", struct_test}, + {"struct2_test", struct2_test}, + {"seq1_test", seq1_test}, + {"seq2_test", seq2_test}, + {"seq3_test", seq3_test}, + {"seq4_test", seq4_test}, + {"seq5_test", seq5_test}, + {"array1_test", array1_test}, + {"array2_test", array2_test}, + {"enum_test", enum_test}, + {"string1_test", string1_test}, + {"string2_test", string2_test}, + {"string3_test", string3_test}, + {"string4_test", string4_test}, + {"pid_test", pid_test}, + {"port_test", port_test}, + {"ref_test", ref_test}, + {"term_test", term_test}, + {"typedef_test", typedef_test}, + {"inline_sequence_test", inline_sequence_test}, + {"term_sequence_test", term_sequence_test}, + {"term_struct_test", term_struct_test}, + {"wstring1_test", wstring1_test}, + {"", NULL} +}; + +/* Other prototypes */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2); +static int cmp_a(m_a *a1, m_a *a2); +static int cmp_bseq(m_bseq *b1, m_bseq *b2); +static int cmp_b(m_b *b1, m_b *b2); +static int cmp_lseq(m_lseq *b1, m_lseq *b2); +static int cmp_etseq(m_etseq *b1, m_etseq *b2); +static int cmp_et(m_et* b1, m_et *b2); +static int cmp_es(m_es *b1, m_es *b2); +static int cmp_arr1(m_arr1 b1, m_arr1 b2); +static int cmp_dd(m_dd b1, m_dd b2); +static int cmp_strRec(m_strRec *b1, m_strRec *b2); +static int cmp_sseq(m_sseq *b1, m_sseq *b2); +static int cmp_pid(erlang_pid *p1, erlang_pid *p2); +static int cmp_port(erlang_port *p1, erlang_port *p2); +static int cmp_ref(erlang_ref *p1, erlang_ref *p2); +static int cmp_s(m_s *b1, m_s *b2); +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2); +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2); +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2); +static int cmp_arr3(m_arr3 b1, m_arr3 b2); + +static void print_aseq(m_aseq *a); +static void print_a(m_a *a); +static void print_bseq(m_bseq *b); +static void print_lseq(m_lseq *b); +static void print_b(m_b *b); +static void print_etseq(m_etseq *b); +static void print_et(m_et* b); +static void print_es(m_es *b); +static void print_arr1(long a[500]); +static void print_dd(long a[2][3]); +static void print_strRec(m_strRec* sr); +static void print_sseq(m_sseq *b); +static void print_pid(erlang_pid *p); +static void print_port(erlang_port *p); +static void print_ref(erlang_ref *p); +static void print_term(ETERM *t); +static void print_s(m_s *p); +static void print_ssstr3(m_ssstr3 *b1); +static void print_ssarr3(m_ssarr3 *b1); +static void print_sarr3(m_sarr3 *b1); +static void print_arr3(m_arr3 b1); +static void print_wstr(CORBA_wchar *ws); + +static void free_etseq_buf(m_etseq *b); +static void free_et(m_et* b); + +#ifdef __WIN32__ +typedef struct { + long tv_sec; + long tv_usec; +} MyTimeval; +#else +typedef struct timeval MyTimeval; +#endif +static void my_gettimeofday(MyTimeval *tv); +static void showtime(MyTimeval *start, MyTimeval *stop); +static void usage(void); +static void done(int r); + + + +/* main */ + +#ifdef VXWORKS +int client(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + struct hostent *hp; + erlang_pid pid; + MyTimeval start, stop; + int i, fd, ires, tres; + IC_Env *env; + int tries = 0; + char *this_node_name = NULL; + char *peer_node = NULL; + char *peer_process_name = NULL; + char *cookie = NULL; + char host[HOSTNAMESZ + 1]; + TestFunc test_func = NULL; + TestCase *test_case; + char *test_case_name = NULL; + +#ifdef __WIN32__ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); + exit(1); + } +#endif + + progname = argv[0]; + host[HOSTNAMESZ] = '\0'; + if (gethostname(host, HOSTNAMESZ) < 0) { + fprintf(stderr, "Can't find own hostname\n"); + done(1); + } + if ((hp = gethostbyname(host)) == 0) { + fprintf(stderr, "Can't get ip address for host %s\n", host); + done(1); + } + for (i = 1; i < argc; i++) { + if (cmp_str(argv[i], "-help")) { + usage(); + done(0); + } else if (cmp_str(argv[i], "-this-node-name")) { + i++; + this_node_name = argv[i]; + } else if (cmp_str(argv[i], "-peer-node")) { + i++; + peer_node = argv[i]; + } else if (cmp_str(argv[i], "-peer-process-name")) { + i++; + peer_process_name = argv[i]; + } else if (cmp_str(argv[i], "-cookie")) { + i++; + cookie = argv[i]; + } else if (cmp_str(argv[i], "-test-case")) { + i++; + test_case_name = argv[i]; + } else { + fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); + usage(); + done(1); + } + } + + if (this_node_name == NULL || peer_node == NULL || test_case_name == NULL + || peer_process_name == NULL || cookie == NULL) { + fprintf(stderr, "Error: missing option\n"); + usage(); + done(1); + } + + test_case = test_cases; + while (test_case->func) { + if (cmp_str(test_case->name, test_case_name)) { + test_func = test_case->func; + break; + } + test_case++; + } + if (test_func == NULL) { + fprintf(stderr, "Error: illegal test case: \"%s\"\n", test_case_name); + done(1); + } + + /* Behead hostname at first dot */ + for (i=0; host[i] != '\0'; i++) { + if (host[i] == '.') { host[i] = '\0'; break; } + } + sprintf(this_node, "%s@%s", this_node_name, host); + fprintf(stderr, "c_client: this node: \"%s\"\n", this_node); + fprintf(stderr, "c_client: peer node: \"%s\"\n", peer_node); + fprintf(stderr, "c_client: test case: \"%s\"\n", test_case_name); + + fprintf(stderr, "c_client: starting\n"); + + /* initialize erl_interface */ + erl_init(NULL, 0); + + for (tries = 0; tries < MAXTRIES; tries++) { + + /* connect to erlang node */ + + ires = erl_connect_xinit(host, this_node_name, this_node, + (struct in_addr *)*hp->h_addr_list, + cookie, 0); + + fprintf(stderr, "c_client: erl_connect_xinit(): %d\n", ires); + + fd = erl_connect(peer_node); + fprintf(stderr, "c_client: erl_connect(): %d\n", fd); + + if (fd >= 0) + break; + fprintf(stderr, "c_client: cannot connect, retrying\n"); + } + if (fd < 0) { + fprintf(stderr, "c_client: cannot connect, exiting\n"); + done(1); + } + env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); + env->_fd = fd; + strcpy(env->_regname, peer_process_name); + env->_to_pid = NULL; + env->_from_pid = &pid; + + strcpy(pid.node, this_node); + pid.num = fd; + pid.serial = 0; + pid.creation = 0; + + my_gettimeofday(&start); + tres = test_func(env); /* Call test case */ + my_gettimeofday(&stop); + showtime(&start, &stop); + erl_close_connection(fd); + + printf("c_client: env->_inbuf before : %d\n", INBUFSZ); + printf("c_client: env->_outbuf before : %d\n", OUTBUFSZ); + printf("c_client: env->_inbuf after : %d\n", env->_inbufsz); + printf("c_client: env->_outbuf after : %d\n", env->_outbufsz); + + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + done(tres); +} + +static void usage() +{ + fprintf(stderr, "Usage: %s [-help] -this-node-name <name> " + "-peer-node <nodename> -peer-process-name <name> " + "-cookie <cookie> -test-case <test case name>\n", progname); + fprintf(stderr, "Example:\n %s -this-node-name kalle " + "-peer-node olle@home -peer-process-name idltest " + "-cookie oa678er -test-case octet_test\n", progname); +} + +static void done(int r) +{ +#ifdef __WIN32__ + WSACleanup(); +#endif + exit(r); +} + + +/* TESTS */ + +static int void_test(IC_Env *env) +{ + fprintf(stdout, "\n======== m_i_void test ======\n\n"); + m_i_void_test(NULL,env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(1); +} + +static int long_test(IC_Env *env) +{ + long l = 4711, lo, lr; + + fprintf(stdout, "\n======== m_i_long test ======\n\n"); + lr = m_i_long_test(NULL, l, &lo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(l == lo && l == lr); + if (l != lo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", l, lo); + if (l != lr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", l, lr); + return -1; +} + +static int long_long_test(IC_Env *env) +{ + CORBA_long_long ll = 4711, llo, llr; + + fprintf(stdout, "\n======== m_i_longlong test ======\n\n"); + llr = m_i_longlong_test(NULL, ll, &llo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ll == llo && ll == llr); + if (ll != llo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", + ll, llo); + if (ll != llr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", ll, llr); + return -1; +} + +static int unsigned_short_test(IC_Env *env) +{ + unsigned short x, y = 2, z; + + fprintf(stdout, "\n======== m_i_ushort test ======\n\n"); + x = m_i_ushort_test(NULL, y, &z, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(y == z && y == x); + if (y != z) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", y, z); + if (y != x) + fprintf(stdout, " result error, sent: %d, got: %d\n", y, x); + return -1; +} + + +static int unsigned_long_test(IC_Env *env) +{ + unsigned long ul = 5050, ulo, ulr; + + fprintf(stdout, "\n======== m_i_ulong test ======\n\n"); + ulr = m_i_ulong_test(NULL, ul, &ulo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ul == ulo && ul == ulr); + if (ul != ulo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ul, ulo); + if (ul != ulr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", ul, ulr); + return -1; +} + +/* + * Note: CORBA_unsigned_long_long is in fact a plain long. + */ +static int unsigned_long_long_test(IC_Env *env) +{ + CORBA_unsigned_long_long ull = 5050, ullo, ullr; + + fprintf(stdout, "\n======== m_i_ulonglong test ======\n\n"); + ullr = m_i_ulonglong_test(NULL, ull, &ullo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ull == ullo && ull == ullr); + if (ull != ullo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ull, ullo); + if (ull != ullr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + ull, ullr); + return -1; +} + +static int double_test(IC_Env *env) +{ + double d = 12.1212, db, dr; + + fprintf(stdout, "\n======== m_i_double test ======\n\n"); + dr = m_i_double_test(NULL, d, &db, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(d == db && d == dr); + if (d != db) + fprintf(stdout, " out parameter error, sent: %f, got: %f\n", d, db); + if (d != dr) + fprintf(stdout, " result error, sent: %f, got: %f\n", d, dr); + return -1; +} + +static int char_test(IC_Env *env) +{ + char c = 'g', co, cr; + + /* char test */ + fprintf(stdout, "\n======== m_i_char test ======\n\n"); + cr = m_i_char_test(NULL, c, &co, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(c == co && c == cr); + if (c !=co) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", c, co); + if (c != cr) + fprintf(stdout, " result error, sent: %c, got: %c\n", c, cr); + return -1; +} + +static int wchar_test(IC_Env *env) +{ + CORBA_wchar wc = 103, wco, wcr; + + fprintf(stdout, "\n======== m_i_wchar test ======\n\n"); + wcr = m_i_wchar_test(NULL, wc, &wco, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(wc == wco && wc == wcr); + if (wc != wco) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + wc, wco); + if (wc != wcr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + wc, wcr); + return -1; +} + +static int octet_test(IC_Env *env) +{ + char o ='r', oo, or; + + fprintf(stdout, "\n======== m_i_octet test ======\n\n"); + or = m_i_octet_test(NULL, o, &oo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(o == oo && o == or); + if (o != oo) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", o, oo); + if (o != or) + fprintf(stdout, " result error, sent: %c, got: %c\n", o, or); + return -1; +} + +static int bool_test(IC_Env *env) +{ + unsigned char i = 0, io, ir; + + fprintf(stdout, "\n======== m_i_bool test ======\n\n"); + ir = m_i_bool_test(NULL, i, &io, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(i == io && i == ir); + if (i != io) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", i, io); + if (i != ir) + fprintf(stdout, " result error, sent: %d, got: %d\n", i, ir); + return -1; +} + +static int struct_test(IC_Env *env) +{ + m_b b = {4711, 'a'}, bo, br; + + fprintf(stdout, "\n======== m_i_struct test ======\n\n"); + br = m_i_struct_test(NULL, &b, &bo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_b(&b, &bo) && cmp_b(&b, &br)); + if (!cmp_b(&b, &bo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&bo); + fprintf(stdout, "\n"); + } + if (!cmp_b(&b, &br)) { + fprintf(stdout, " result error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&br); + fprintf(stdout, "\n"); + } + return -1; +} + +static int struct2_test(IC_Env *env) +{ + m_es esi = {m_peach, 5050}, eso, esr; + + fprintf(stdout, "\n======== m_i_struct2 test ======\n\n"); + esr = m_i_struct2_test(NULL, &esi, &eso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_es(&esi, &eso) && cmp_es(&esi, &esr)); + if (!cmp_es(&esi, &eso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&eso); + fprintf(stdout, "\n"); + } + if (!cmp_es(&esi, &esr)) { + fprintf(stdout, " result error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&esr); + fprintf(stdout, "\n"); + } + return -1; +} + + +static int seq1_test(IC_Env *env) +{ + m_bseq bs, *bso, *bsr; + + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + bs._length = 3; + bs._buffer = ba; + + fprintf(stdout, "\n======== m_i_seq1 test ======\n\n"); + bsr = m_i_seq1_test(NULL, &bs, &bso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_bseq(&bs, bso) && cmp_bseq(&bs, bsr)); + if (!cmp_bseq(&bs, bso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bso); + fprintf(stdout, "\n"); + } + if (!cmp_bseq(&bs, bsr)) { + fprintf(stdout, " result error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bsr); + fprintf(stdout, "\n"); + } + CORBA_free(bso); + CORBA_free(bsr); + return -1; +} + +static int seq2_test(IC_Env *env) +{ + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + m_a a; + m_a aa[2]; + m_aseq as, *aso, *asr; + + a.l = 9999; + a.y._length = 3; + a.y._buffer = ba; + a.d = 66.89898989; + + aa[0] = a; + aa[1] = a; + as._length = 2; + as._buffer = aa; + + fprintf(stdout, "\n======== m_i_seq2 test ======\n\n"); + asr = m_i_seq2_test(NULL, &as, &aso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_aseq(&as, aso) && cmp_aseq(&as, asr)); + if (!cmp_aseq(&as, aso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(aso); + fprintf(stdout, "\n"); + } + if (!cmp_aseq(&as, asr)) { + fprintf(stdout, " result error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(asr); + fprintf(stdout, "\n"); + } + CORBA_free(aso); + CORBA_free(asr); + return -1; +} + +static int seq3_test(IC_Env *env) +{ + m_lseq lsi, *lso, *lsr; + long al[500]; + int i=0; + + for (i = 0; i < 500; i++) + al[i]=i; + lsi._length = 500; + lsi._buffer = al; + + fprintf(stdout, "\n======== m_i_seq3 test ======\n\n"); + lsr = m_i_seq3_test(NULL, &lsi, &lso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_lseq(&lsi, lso) && cmp_lseq(&lsi, lsr)); + if (!cmp_lseq(&lsi, lso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lso); + fprintf(stdout, "\n"); + } + if (!cmp_lseq(&lsi, lsr)) { + fprintf(stdout, " result error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lsr); + fprintf(stdout, "\n"); + } + CORBA_free(lso); + CORBA_free(lsr); + return -1; +} + +static int seq4_test(IC_Env *env) +{ + char *stra0[3] = {"a", "long", "time"}; + char *stra1[3] = {"ago", "there", "was"}; + char *stra2[3] = {"a", "buggy", "compiler"}; + m_sstr3 str3s[3] = {{3, 3, stra0}, {3, 3, stra1}, {3, 3, stra2}}; + m_ssstr3 str3ssi = {3, 3, str3s}; + m_ssstr3 *str3sso, *str3ssr; + + fprintf(stdout, "\n======== m_i_seq4 test ======\n\n"); + str3ssr = m_i_seq4_test(NULL, &str3ssi, &str3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssstr3(&str3ssi, str3sso) && + cmp_ssstr3(&str3ssi, str3ssr)); + if (!cmp_ssstr3(&str3ssi, str3sso)){ + fprintf(stdout, " out parameter error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssstr3(&str3ssi, str3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(str3sso); + CORBA_free(str3ssr); + return -1; +} + +static int seq5_test(IC_Env *env) +{ + m_arr3 arr3a[3] = { + {4711, 18931947, 3}, + {4711, 18931947, 3}, + {4711, 18931947, 3}}; + m_sarr3 arr3sa[3] = {{3, 3, arr3a}, {3, 3, arr3a}, {3, 3, arr3a}}; + m_ssarr3 arr3ssi = {3, 3, arr3sa}; + m_ssarr3 *arr3sso; + m_ssarr3 *arr3ssr; + + fprintf(stdout, "\n======== m_i_seq5 test ======\n\n"); + arr3ssr = m_i_seq5_test(NULL, &arr3ssi, &arr3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssarr3(&arr3ssi, arr3sso) && + cmp_ssarr3(&arr3ssi, arr3ssr)); + if (!cmp_ssarr3(&arr3ssi, arr3sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssarr3(&arr3ssi, arr3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(arr3sso); + CORBA_free(arr3ssr); + return -1; +} + +static int array1_test(IC_Env *env) +{ + int i; + long al[500]; + m_arr1 alo; + m_arr1_slice* alr; + + for (i = 0; i < 500; i++) + al[i]=i; + + fprintf(stdout, "\n======== m_i_array1 test ======\n\n"); + alr = m_i_array1_test(NULL, al, alo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_arr1(al, alo) && cmp_arr1(al, alr)); + if (!cmp_arr1(al, alo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alo); + fprintf(stdout, "\n"); + } + if (!cmp_arr1(al,alr)) { + fprintf(stdout, " result error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alr); + fprintf(stdout, "\n"); + } + free(alo); + free(alr); + return -1; +} + +static int array2_test(IC_Env *env) +{ + long dl[2][3] = {{11, 2, 7}, {22, 8 ,13}}; + m_dd dlo; + m_dd_slice* dlr; + + fprintf(stdout, "\n======== m_i_array2 test ======\n\n"); + dlr = m_i_array2_test(NULL, dl, dlo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_dd(dl,dlo) && cmp_dd(dl,dlr)); + if (!cmp_dd(dl,dlo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlo); + fprintf(stdout, "\n"); + } + if (!cmp_dd(dl,dlr)) { + fprintf(stdout, " result error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlr); + fprintf(stdout, "\n"); + } + free(*dlr); + return -1; +} + +static int enum_test(IC_Env *env) +{ + m_fruit ei = m_banana, eo, er; + + fprintf(stdout, "\n======== m_i_enum test ======\n\n"); + er = m_i_enum_test(NULL, ei, &eo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ei == eo && ei == er); + if (ei != eo) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", ei, eo); + if (ei != er) + fprintf(stdout, " result error, sent: %d, got: %d\n", ei, er); + return -1; +} + +static int string1_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string1 test ======\n\n"); + sr = m_i_string1_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, sr)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string2_test(IC_Env *env) +{ + char* sa[3] = {"hello", "foo", "bar"}; + m_sseq ssi = {3, 3, sa}; + m_sseq *sso, *ssr; + + fprintf(stdout, "\n======== m_i_string2 test ======\n\n"); + ssr = m_i_string2_test(NULL, &ssi, &sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_sseq(&ssi, sso) && cmp_sseq(&ssi, sso)); + if (!cmp_sseq(&ssi, sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(sso); + } + if (!cmp_sseq(&ssi, ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(ssr); + } + CORBA_free(sso); + CORBA_free(ssr); + return -1; +} + +static int string3_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string3 test ======\n\n"); + sr = m_i_string3_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, so)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string4_test(IC_Env *env) +{ + char as1[100] = "a string", as2[200] = "help", as3[200] = "hello there"; + m_strRec stri = { 1, /* dd */ + as1, /* str4 */ + {{'a', 'k'}, {'z', 'g'}, {'n', 'q'}}, /* str7 */ + {3, 3, "buf"}, /* str5 */ + as2, /* str6 */ + {'m', 'f', 'o'}, /* str8 */ + as3, /* str9 */ + {3, 3, "stu"} /* str10 */ + }; + m_strRec *stro, *strr; + + fprintf(stdout, "\n======== m_i_string4 test ======\n\n"); + strr = m_i_string4_test(NULL, &stri, &stro, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_strRec(&stri,stro) && cmp_strRec(&stri,strr)); + if (!cmp_strRec(&stri,stro)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(stro); + fprintf(stdout, "\n"); + } + if (!cmp_strRec(&stri,strr)) { + fprintf(stdout, " result error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(strr); + fprintf(stdout, "\n"); + } + CORBA_free(stro); + CORBA_free(strr); + return -1; +} + + +static int pid_test(IC_Env *env) +{ + erlang_pid pid = {"", 7, 0, 0}, pido, pidr; + + strcpy(pid.node, this_node), /* this currently running node */ + fprintf(stdout, "\n======== m_i_pid test ======\n\n"); + pidr = m_i_pid_test(NULL, &pid, &pido, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_pid(&pid, &pido) && cmp_pid(&pid, &pidr)); + if (!cmp_pid(&pid, &pido)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pido); + } + if (!cmp_pid(&pid, &pidr)) { + fprintf(stdout, " result error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pidr); + } + return -1; +} + +static int port_test(IC_Env *env) +{ + erlang_port porti = {"node", 5, 1}, porto, portr; + + fprintf(stdout, "\n======== m_i_port test ======\n\n"); + portr = m_i_port_test(NULL, &porti, &porto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_port(&porti, &porto) && cmp_port(&porti, &portr)); + if (!cmp_port(&porti, &porto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&porto); + } + if (!cmp_port(&porti, &portr)) { + fprintf(stdout, " result error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&portr); + } + return -1; +} + +static int ref_test(IC_Env *env) +{ + erlang_ref refi = { "node1", 3, {1, 2, 3}, 1}, + refo, refr; + + fprintf(stdout, "\n======== m_i_ref test ======\n\n"); + refr = m_i_ref_test(NULL, &refi, &refo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ref(&refi, &refo) && cmp_ref(&refi, &refr)); + if (!cmp_ref(&refi, &refo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refo); + } + if (!cmp_ref(&refi, &refr)) { + fprintf(stdout, " result error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refr); + } + return -1; +} + +static int term_test(IC_Env *env) +{ + ETERM *ti, *to, *tr; + + ti = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + + fprintf(stdout, "\n======== m_i_term test ======\n\n"); + tr = m_i_term_test(NULL, ti, &to, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(ti, to) && erl_match(ti, tr)); + if (!erl_match(ti, to)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(to); + } + if (!erl_match(ti, tr)) { + fprintf(stdout, " result error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(tr); + } + erl_free_term(ti); + erl_free_term(to); + erl_free_term(tr); + return -1; +} + +static int typedef_test(IC_Env *env) +{ + m_banan mbi, mbo; /* erlang_port */ + m_apa mai; /* ETERM* */ + m_apa mao = NULL; + long tl; + + strcpy(mbi.node,"node"); + mbi.id = 15; + mbi.creation = 1; + + fprintf(stdout, "\n======== m_i_typedef test ======\n\n"); + mai = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + tl = m_i_typedef_test(NULL, mai, &mbi, &mao, &mbo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(mai, mao) && cmp_port(&mbi, &mbo) && tl == 4711); + if (!erl_match(mai, mao)) { + fprintf(stdout, " out parameter error (term), sent:\n"); + print_term(mai); + fprintf(stdout, "got:\n"); + print_term(mao); + } + if (!cmp_port(&mbi, &mbo)) { + fprintf(stdout, " out parameter error (port), sent:\n"); + print_port(&mbi); + fprintf(stdout, "got:\n"); + print_port(&mbo); + } + if (tl != 4711) { + fprintf(stdout, " result error, sent: 4711, got %ld\n", tl); + } + erl_free_term(mai); + erl_free_term(mao); + return -1; +} + +static int inline_sequence_test(IC_Env *env) +{ + int i; + long al[500]; + m_s isi = {4711, {500, 10, al}}, + *iso, *isr; + + for (i = 0; i < 500; i++) + al[i]=i; + fprintf(stdout, "\n======== m_i_inline_sequence test ======\n\n"); + isr = m_i_inline_sequence_test(NULL, &isi, &iso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_s(&isi, iso) && cmp_s(&isi, isr)); + if (!cmp_s(&isi, iso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(iso); + } + if (!cmp_s(&isi, isr)) { + fprintf(stdout, " result error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(isr); + } + CORBA_free(iso); + CORBA_free(isr); + return -1; +} + +static int term_sequence_test(IC_Env *env) +{ + ETERM* et_array[4] = { + erl_format("[{apa, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{banan, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{apelsin, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{mango, 1, 23}, \"string\", {1.23, 45}]")}; + m_etseq etsi = {4, 4, et_array}, *etso, *etsr; + + fprintf(stdout, "\n======== m_i_term_sequence test ======\n\n"); + etsr = m_i_term_sequence_test(NULL, &etsi, &etso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_etseq(&etsi, etso) && cmp_etseq(&etsi, etsr)); + if (!cmp_etseq(&etsi, etso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etso); + } + if (!cmp_etseq(&etsi, etsr)) { + fprintf(stdout, " result error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etsr); + } + free_etseq_buf(&etsi); + free_etseq_buf(etso); + free_etseq_buf(etsr); + CORBA_free(etso); + CORBA_free(etsr); + return -1; +} + +static int term_struct_test(IC_Env *env) +{ + m_et eti = { erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"), + 121212 }; + m_et eto, etr; + + fprintf(stdout, "\n======== m_i_term_struct test ======\n\n"); + etr = m_i_term_struct_test(NULL, &eti, &eto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_et(&eti, &eto) && cmp_et(&eti, &etr)); + if (!cmp_et(&eti, &eto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&eto); + } + if (!cmp_et(&eti, &etr)) { + fprintf(stdout, " result error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&etr); + } + free_et(&eti); + free_et(&eto); + free_et(&etr); + return -1; +} + +static int wstring1_test(IC_Env *env) +{ + CORBA_wchar wsi[] = {100, 101, 102, 103, 104, 0}, *wso, *wsr; + + fprintf(stdout, "\n======== m_i_wstring1 test ======\n\n"); + wsr = m_i_wstring1_test(NULL, wsi, &wso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_wstr(wsi, wso) && cmp_wstr(wsi, wsr)); + if (!cmp_wstr(wsi, wso)) { + fprintf(stdout, " out parameter error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wso); + } + if (!cmp_wstr(wsi, wsr)) { + fprintf(stdout, " result error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wsr); + } + CORBA_free(wso); + CORBA_free(wsr); + return -1; +} + +/* Compare functions */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2) +{ + int i; + + if (a1->_length != a2->_length) + return 0; + for (i = 0; i < a1->_length; i++) + if (cmp_a(&(a1->_buffer[i]), &(a2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_a(m_a *a1, m_a *a2) +{ + return a1->l == a2->l && + a1->d == a2->d && + cmp_bseq(&a1->y, &a2->y); +} + +static int cmp_bseq(m_bseq *b1, m_bseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (cmp_b(&(b1->_buffer[i]), &(b2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_b(m_b *b1, m_b *b2) +{ + return b1->l == b2->l && b1->c == b2->c; +} + +static int cmp_lseq(m_lseq *b1, m_lseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (b1->_buffer[i] != b2->_buffer[i]) + return 0; + return 1; +} + +static int cmp_etseq(m_etseq *b1, m_etseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!erl_match(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + +static int cmp_et(m_et* b1, m_et *b2) +{ + return erl_match(b1->e, b2->e) && b1->l == b2->l; +} + +static int cmp_es(m_es *b1, m_es *b2) +{ + return b1->f == b2->f && b1->l == b2->l; +} + +static int cmp_arr1(m_arr1 b1, m_arr1 b2) +{ + int i; + + for (i = 0; i < 500; i++) + if (b1[i] != b2[i]) + return 0; + return 1; +} + +static int cmp_dd(m_dd b1, m_dd b2) +{ + + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1[i][j] != b2[i][j]) + return 0; + return 1; +} + + + +static int cmp_strRec(m_strRec *b1, m_strRec *b2) +{ + int i, j; + + if (b1->bb != b2->bb) + return 0; + if (!cmp_str(b1->str4,b2->str4)) + return 0; + if (b1->str5._length != b2->str5._length) + return 0; + for (j = 0; j < b1->str5._length; j++) + if (b1->str5._buffer[j] != b2->str5._buffer[j]) + return 0; + if (!cmp_str(b1->str6,b2->str6)) + return 0; + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1->str7[i][j] != b2->str7[i][j]) + return 0; + for (j = 0; j < 3; j++) + if (b1->str8[j] != b2->str8[j]) + return 0; + if (!cmp_str(b1->str9,b2->str9)) + return 0; + if (b1->str10._length != b2->str10._length) + return 0; + for (j = 0; j < b1->str10._length; j++) + if (b1->str10._buffer[j] != b2->str10._buffer[j]) + return 0; + return 1; +} + + +static int cmp_sseq(m_sseq *b1, m_sseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!cmp_str(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + + +static int cmp_pid(erlang_pid *p1, erlang_pid *p2) +{ + return cmp_str(p1->node,p2-> node) && + p1->num == p2->num && + p1->serial == p2->serial && + p1->creation == p2->creation; +} + +static int cmp_port(erlang_port *p1, erlang_port *p2) +{ + return cmp_str(p1->node,p2-> node) && p1->id == p2->id; +} + +static int cmp_ref(erlang_ref *p1, erlang_ref *p2) +{ + return cmp_str(p1->node, p2->node) && + p1->len == p2->len && + (p1->len < 1 || p1->n[0] == p2->n[0]) && + (p1->len < 2 || p1->n[1] == p2->n[1]) && + (p1->len < 3 || p1->n[2] == p2->n[2]); +} + +static int cmp_s(m_s *b1, m_s *b2) +{ + int i; + + if (b1->l != b2->l) + return 0; + if (b1->sl._length != b2->sl._length) + return 0; + for (i = 0; i < b1->sl._length; i++) + if (b1->sl._buffer[i] != b2->sl._buffer[i]) + return 0; + return 1; +} + + +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2) +{ + int i,j; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (b1->_buffer[i]._length != b2->_buffer[i]._length) + return 0; + for (j = 0; j < b1->_buffer[i]._length; j++) + if (!cmp_str(b1->_buffer[i]._buffer[j], + b2->_buffer[i]._buffer[j])) + return 0; + } + return 1; +} + + + +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_sarr3(&b1->_buffer[i], &b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_arr3(b1->_buffer[i], b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_arr3(m_arr3 b1, m_arr3 b2) +{ + int i; + + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) { + if (b1[i] != b2[i]) + return 0; + } + return 1; +} + +/* Print functions */ +static void print_aseq(m_aseq *a) +{ + int i; + fprintf(stdout, "\nm_aseq size: %ld --------\n", a->_length); + for (i = 0; i < a->_length; i++) + print_a(&(a->_buffer[i])); +} + +static void print_a(m_a *a) +{ + fprintf(stdout, "\nm_a --------\n l: %ld\n d:%f\n", a->l, a->d); + print_bseq(&a->y); +} + +static void print_bseq(m_bseq *b) +{ + int i; + + fprintf(stdout, "\nm_bseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + print_b(&(b->_buffer[i])); +} + +static void print_lseq(m_lseq *b) +{ + int i; + + fprintf(stdout, "\nm_lseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "[%d]: %ld\n", i, b->_buffer[i]); +} + +static void print_b(m_b *b) +{ + fprintf(stdout, "\nm_b --------\n l: %ld\n c: %c\n", b->l, b->c); +} + + +static void print_etseq(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) { + fprintf(stdout, "[%d]:\n", i); + erl_print_term(stdout, b->_buffer[i]); + } +} + + +static void print_et(m_et* b) +{ + fprintf(stdout, "\net struct --------\n"); + erl_print_term(stdout, b->e); + fprintf(stdout, "long: %ld\n", b->l); + fprintf(stdout, "\n--------\n"); +} + +static void print_es(m_es *b) +{ + fprintf(stdout, "\nm_es --------\n f: %d\n l: %ld\n", b->f, b->l); +} + + +static void print_arr1(long a[10]) +{ + int i; + + for (i = 0; i < 10; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, a[i]); +} + +static void print_dd(long a[2][3]) +{ + int i, j; + + fprintf(stdout, "\nlong dd[2][3] --------\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "\n[%d][%d]: %ld\n", i, j, a[i][j]); +} + + +static void print_strRec(m_strRec* sr) +{ + int i, j; + + fprintf(stdout, "\nboolean bb : %d\n",sr->bb); + fprintf(stdout, "string str4 : %s\n",sr->str4); + fprintf(stdout, "str7[2][3] :\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "str7[%d][%d]: %ld\n", i, j, sr->str7[i][j]); + fprintf(stdout, "str5._length : %ld\n",sr->str5._length); + for (j = 0; j < sr->str5._length; j++) + fprintf(stdout, "str5._buffer[%d]: %c\n", j, sr->str5._buffer[j]); + fprintf(stdout, "string str6 : %s\n",sr->str6); + fprintf(stdout, "str8 :\n"); + for (j = 0; j < 3; j++) + fprintf(stdout, "str8[%d]: %c\n", j, sr->str8[j]); + fprintf(stdout, "string str9 : %s\n",sr->str9); + fprintf(stdout, "str10._length : %ld\n",sr->str10._length); + for (j = 0; j < sr->str10._length; j++) + fprintf(stdout, "str10._buffer[%d]: %c\n", j, sr->str10._buffer[j]); +} + +static void print_sseq(m_sseq *b) +{ + int i; + + fprintf(stdout, "\nm_sseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "%s\n", b->_buffer[i]); + +} + + +static void print_pid(erlang_pid *p) +{ + fprintf(stdout, "\nerlang_pid --------\n node: %s\n num: %d\n " + "serial: %d\n creation: %d\n", + p->node, p->num, p->serial, p->creation); +} + +static void print_port(erlang_port *p) +{ + fprintf(stdout, "\nerlang_port --------\n node: %s\n id: %d\n " + "creation: %d\n", p->node, p->id, p->creation); +} + +static void print_ref(erlang_ref *p) +{ + fprintf(stdout, "\nerlang_ref --------\n node: %s\n len: %d\n " + "n[0]: %d\n n[1]: %d\n n[2]: %d\n creation: %d\n", + p->node, p->len, p->n[0], p->n[1], p->n[2], p->creation); +} + +static void print_term(ETERM *t) +{ + fprintf(stdout, "\nETERM --------\n"); + erl_print_term(stdout, t); + fprintf(stdout, "\n--------\n"); +} + +static void print_s(m_s *p) +{ + int i; + + fprintf(stdout, "\n%ld\n", p->l); + for (i = 0; i < p->sl._length; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, p->sl._buffer[i]); +} + + +static void print_ssstr3(m_ssstr3 *b1) +{ + int i,j; + + fprintf(stdout, "\nSSSTR3 --------\n"); + fprintf(stdout,"b1->_length = %ld\n",b1->_length); + for (i = 0; i < b1->_length; i++) { + fprintf(stdout,"\nb1->_buffer[%d]._length %ld\n", + i, b1->_buffer[i]._length); + for (j = 0; j < b1->_buffer[i]._length; j++) + fprintf(stdout,"b1->_buffer[%d]._buffer[%d] = %s\n", + i, j, b1->_buffer[i]._buffer[j]); + } + fprintf(stdout, "\n--------\n"); +} + +static void print_wstr(CORBA_wchar *ws) +{ + int i = 0; + + fprintf(stdout, "\nwstr --------\n"); + while (ws[i]) { + fprintf(stdout, "[%d]: %ld\n", i, ws[i]); + i++; + } + fprintf(stdout, "\n--------\n"); +} + + +static void print_ssarr3(m_ssarr3 *b1) +{ + int i; + + fprintf(stdout, "\nssarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_sarr3(&b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_sarr3(m_sarr3 *b1) +{ + int i; + + fprintf(stdout, "\nsarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_arr3(b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_arr3(m_arr3 b1) +{ + int i; + + fprintf(stdout, "\narr3 --------\n"); + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) + fprintf(stdout, "%ld ", b1[i]); + fprintf(stdout, "\n--------\n"); +} + +static void free_etseq_buf(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) + erl_free_term(b->_buffer[i]); +} + +static void free_et(m_et* b) +{ + erl_free_term(b->e); +} + +static void showtime(MyTimeval *start, MyTimeval *stop) +{ + MyTimeval elapsed; + + elapsed.tv_sec = stop->tv_sec - start->tv_sec; + elapsed.tv_usec = stop->tv_usec - start->tv_usec; + while (elapsed.tv_usec < 0) { + elapsed.tv_sec -= 1; + elapsed.tv_usec += 1000000; + } + fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); +} + +static void my_gettimeofday(MyTimeval *tv) +#ifdef __WIN32__ +#define EPOCH_JULIAN_DIFF 11644473600i64 +{ + SYSTEMTIME t; + FILETIME ft; + LONGLONG lft; + + GetSystemTime(&t); + SystemTimeToFileTime(&t, &ft); + memcpy(&lft, &ft, sizeof(lft)); + tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); + tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); +} +#elif defined VXWORKS +{ + int rate = sysClkRateGet(); /* Ticks per second */ + unsigned long ctick = tickGet(); + tv->tv_sec = ctick / rate; /* secs since reboot */ + tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; +} +#else +{ + gettimeofday(tv, NULL); +} +#endif diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl new file mode 100644 index 0000000000..6d229c3ac1 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl @@ -0,0 +1,173 @@ + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2003-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +#include "erlang.idl" + + +const short TestConst = 1; + +module m { + + const short TestConst = 2; + + struct b { + long l; + char c; + }; + + struct simple { + long l; + b b_t; + }; + + enum fruit {orange, banana, apple, peach, pear}; + + typedef sequence<long> lseq; + + typedef sequence<b> bseq; + + struct a { + long l; + bseq y; + double d; + }; + + typedef sequence<a> aseq; + + typedef sequence<string> sseq; + typedef string str; + typedef long myLong; + + typedef long arr1[500], dd[2][3]; + + typedef erlang::term apa; + typedef erlang::port banan; + + typedef sequence<erlang::term> etseq; + + struct s { + long l; + sequence<long> sl; + }; + + struct es { + fruit f; + myLong l; + }; + + struct et { + erlang::term e; + long l; + }; + + + typedef sequence<char> str1; + typedef string<12> str2; + typedef char str3[3]; + + typedef sequence<string> sstr3; // sequence of string + typedef sequence<sstr3> ssstr3; // sequence of sequences of strings + + typedef long arr3[3]; // array of long + typedef sequence<arr3> sarr3; // sequence of array + typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings + + struct strRec{ + boolean bb; + string str4; + long str7[3][2]; + sequence<char> str5; + string<12> str6; + str3 str8; + str2 str9; + str1 str10; + }; + + + struct dyn { + long l; + sequence<long> sl; + }; + typedef dyn arr2[1][2]; + + + interface i { + + const short TestConst = 3; + + //arr2 suck(in arr2 x, out arr2 y ); + + ///////////////////////////////// attribute long l; + + // simple types + void void_test(); + long long_test(in long a, out long a1); + long long longlong_test(in long long a, out long long a1); + unsigned short ushort_test(in unsigned short a, out unsigned short a1); + unsigned long ulong_test(in unsigned long a, out unsigned long a1); + unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1); + double double_test(in double a, out double a1); + char char_test(in char a, out char a1); + wchar wchar_test(in wchar a, out wchar a1); + octet octet_test(in octet a, out octet a1); + boolean bool_test(in boolean a, out boolean a1); + + // Seq. and struct tests + b struct_test(in b a, out b a1); + es struct2_test(in es a, out es a1); + //simple struct3_test(in simple x, out simple y); + bseq seq1_test(in bseq a, out bseq a1); + aseq seq2_test(in aseq a, out aseq a1); + lseq seq3_test(in lseq a, out lseq a1); + ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1); + ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1); + + // Array tests + arr1 array1_test(in arr1 a, out arr1 a1); + dd array2_test(in dd a, out dd a1); + + // enum test + fruit enum_test(in fruit a, out fruit a1); + + // string tests + string string1_test(in string a, out string a1); + wstring wstring1_test(in wstring a, out wstring a1); + sseq string2_test(in sseq a, out sseq a1); + str string3_test(in str a, out str a1); + strRec string4_test(in strRec a, out strRec a1); + + // Special erlang types + erlang::pid pid_test(in erlang::pid a, out erlang::pid a1); + erlang::port port_test(in erlang::port a, out erlang::port a1); + erlang::ref ref_test(in erlang::ref a, out erlang::ref a1); + erlang::term term_test(in erlang::term a, out erlang::term a1); + + // typedef test + long typedef_test(in apa a, in banan b, out apa a1, out banan b1); + + // inlined seq. test + s inline_sequence_test(in s a, out s a1); + + // term seq. test + etseq term_sequence_test(in etseq a, out etseq a1); + // term struct test + et term_struct_test(in et a, out et a1); + + }; + +}; diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl new file mode 100644 index 0000000000..09358b7cf9 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl @@ -0,0 +1,28 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(erl_server). + +-export([run/0, stop/0]). + +run() -> + m_i:oe_create(). + +stop() -> + gen_server:cast(cidl_test, stop). diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl new file mode 100644 index 0000000000..9f231de856 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl @@ -0,0 +1,161 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(m_i_impl). +-include("m.hrl"). + +-export([init/1, terminate/2, void_test/1, long_test/2, ushort_test/2, + longlong_test/2, ulong_test/2, ulonglong_test/2, + double_test/2, char_test/2, wchar_test/2, octet_test/2, + bool_test/2, struct_test/2, struct2_test/2, seq1_test/2, + seq2_test/2, seq3_test/2, seq4_test/2, seq5_test/2, + array1_test/2, array2_test/2, enum_test/2, string1_test/2, + string2_test/2, string3_test/2, string4_test/2, pid_test/2, + port_test/2, ref_test/2, term_test/2, typedef_test/3, + inline_sequence_test/2, '_set_l'/2, '_get_l'/1, + term_struct_test/2, term_sequence_test/2, wstring1_test/2]). + +-define(PRINTDEBUG(Case), + io:format("erl_server: case: ~p~n" + "erl_server: location: ~p~n", [Case, [?FILE, ?LINE]])). +-define(PRINTDEBUG2(Case, Msg), + io:format("erl_server: case: ~p~n" + "erl_server: Msg: ~p~n" + "erl_server: location: ~p~n", [Case, Msg, [?FILE, ?LINE]])). + +init(Env) -> + {ok, []}. + +terminate(F, R) -> + ok. + +'_get_l'(State) -> + ?PRINTDEBUG("_get_l"), + {reply, State, State}. +void_test(State) -> + ?PRINTDEBUG("void_test"), + {reply, ok, State}. + +'_set_l'(State, V) -> + ?PRINTDEBUG2("_set_l", V), + {reply, ok, V}. +ushort_test(State, V) -> + ?PRINTDEBUG2("ushort_test", V), + {reply, {V, V}, State}. +long_test(State, V) -> + ?PRINTDEBUG2("long_test", V), + {reply, {V, V}, State}. +longlong_test(State, V) -> + ?PRINTDEBUG2("longlong_test", V), + {reply, {V, V}, State}. +ulong_test(State, V) -> + ?PRINTDEBUG2("ulong_test", V), + {reply, {V, V}, State}. +ulonglong_test(State, V) -> + ?PRINTDEBUG2("ulonglong_test", V), + {reply, {V, V}, State}. +double_test(State, V) -> + ?PRINTDEBUG2("double_test", V), + {reply, {V, V}, State}. +char_test(State, V) -> + ?PRINTDEBUG2("char_test", V), + {reply, {V, V}, State}. +wchar_test(State, V) -> + ?PRINTDEBUG2("wchar_test", V), + {reply, {V, V}, State}. +octet_test(State, V) -> + ?PRINTDEBUG2("octet_test", V), + {reply, {V, V}, State}. +bool_test(State, V) -> + ?PRINTDEBUG2("bool_test", V), + {reply, {V, V}, State}. + +struct_test(State, V) -> + ?PRINTDEBUG2("struct_test", V), + {reply, {V, V}, State}. +struct2_test(State, V) -> + ?PRINTDEBUG2("struct2_test", V), + {reply, {V, V}, State}. +seq1_test(State, V) -> + ?PRINTDEBUG2("seq1_test", V), + {reply, {V, V}, State}. +seq2_test(State, V) -> + ?PRINTDEBUG2("seq2_test", V), + {reply, {V, V}, State}. +seq3_test(State, V) -> + ?PRINTDEBUG2("seq3_test", V), + {reply, {V, V}, State}. +seq4_test(State, V) -> + ?PRINTDEBUG2("seq4_test", V), + {reply, {V, V}, State}. +seq5_test(State, V) -> + ?PRINTDEBUG2("seq5_test", V), + {reply, {V, V}, State}. +array1_test(State, V) -> + ?PRINTDEBUG2("array1_test", V), + {reply, {V, V}, State}. +array2_test(State, V) -> + ?PRINTDEBUG2("array2_test", V), + {reply, {V, V}, State}. +enum_test(State, V) -> + ?PRINTDEBUG2("enum_test", V), + {reply, {V, V}, State}. +string1_test(State, V) -> + ?PRINTDEBUG2("string1_test", V), + {reply, {V, V}, State}. +string2_test(State, V) -> + ?PRINTDEBUG2("string2_test", V), + {reply, {V, V}, State}. +string3_test(State, V) -> + ?PRINTDEBUG2("string3_test", V), + {reply, {V, V}, State}. +string4_test(State, V) -> + ?PRINTDEBUG2("string4_test", V), + {reply, {V, V}, State}. +pid_test(State, V) -> + ?PRINTDEBUG2("pid_test", V), + {reply, {V, V}, State}. +port_test(State, V) -> + ?PRINTDEBUG2("port_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +ref_test(State, V) -> + ?PRINTDEBUG2("ref_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +term_test(State, V) -> + ?PRINTDEBUG2("term_test", V), + {reply, {V, V}, State}. +typedef_test(State, A, B) -> + ?PRINTDEBUG2("typedef_test", [A,B]), + {reply, {4711, A, B}, State}. +inline_sequence_test(State, V) -> + ?PRINTDEBUG2("inline_sequence_test", V), + {reply, {V, V}, State}. +term_sequence_test(State, V) -> + ?PRINTDEBUG2("term_sequence_test", V), + {reply, {V, V}, State}. +term_struct_test(State, V) -> + ?PRINTDEBUG2("term_struct_test", V), + {reply, {V, V}, State}. +wstring1_test(State, V) -> + ?PRINTDEBUG2("wstring1_test", V), + {reply, {V, V}, State}. + + + + diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c new file mode 100644 index 0000000000..f8a3b28cc2 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c @@ -0,0 +1,50 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ + +#include "ic.h" +#include "m_i.h" + +int my_prepare_notification_encoding(CORBA_Environment *env) +{ + return oe_prepare_notification_encoding(env); +} + +int my_send_notification(CORBA_Environment *env) +{ + return oe_send_notification(env); +} + +int my_prepare_request_encoding(CORBA_Environment *env) +{ + return oe_prepare_request_encoding(env); +} + +int my_send_request_and_receive_reply(CORBA_Environment *env) +{ + return oe_send_request_and_receive_reply(env); +} + +int my_prepare_reply_decoding(CORBA_Environment *env) +{ + return oe_prepare_reply_decoding(env); +} + + + diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl new file mode 100644 index 0000000000..595c5bf483 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl @@ -0,0 +1,315 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +%%---------------------------------------------------------------------- +%% Purpose : Test suite for c-client/erl-server +%%---------------------------------------------------------------------- + +-module(c_client_erl_server_proto_tmo_SUITE). +-include("test_server.hrl"). + +-export([init_per_testcase/2, fin_per_testcase/2, + all/1, void_test/1, long_test/1, long_long_test/1, + unsigned_short_test/1, unsigned_long_test/1, + unsigned_long_long_test/1, double_test/1, char_test/1, + wchar_test/1, octet_test/1, bool_test/1, struct_test/1, + struct2_test/1, seq1_test/1, seq2_test/1, seq3_test/1, + seq4_test/1, seq5_test/1, array1_test/1, array2_test/1, + enum_test/1, string1_test/1, string2_test/1, string3_test/1, + string4_test/1, pid_test/1, port_test/1, ref_test/1, term_test/1, + typedef_test/1, inline_sequence_test/1, term_sequence_test/1, + term_struct_test/1, wstring1_test/1]). + +-define(DEFAULT_TIMEOUT, 20000). +-define(PORT_TIMEOUT, 15000). +-define(ERLANG_SERVER_NAME, idl_erlang_server). +-define(C_CLIENT_NODE_NAME, c_client_idl_test). + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i, we have + %% to make sure we are using the right m_i module. + code:purge(m_i), + code:load_file(m_i), + + WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + +all(doc) -> + "Test of IC with a C-client and an Erlang generic server. " + "The communication is via Erlang distribution."; +all(suite) -> + [void_test, long_test, long_long_test, unsigned_short_test, + unsigned_long_test, unsigned_long_long_test, double_test, + char_test, wchar_test, octet_test, bool_test, struct_test, + struct2_test, seq1_test, seq2_test, seq3_test, seq4_test, + seq5_test, array1_test, array2_test, enum_test, string1_test, + string2_test, string3_test, string4_test, pid_test, port_test, + ref_test, term_test, typedef_test, inline_sequence_test, + term_sequence_test, term_struct_test, wstring1_test]. + + +array1_test(doc) -> ""; +array1_test(suite) -> []; +array1_test(Config) -> + do_test(array1_test, Config). + +array2_test(doc) -> ""; +array2_test(suite) -> []; +array2_test(Config) -> + do_test(array2_test, Config). + +bool_test(doc) -> ""; +bool_test(suite) -> []; +bool_test(Config) -> + do_test(bool_test, Config). + +char_test(doc) -> ""; +char_test(suite) -> []; +char_test(Config) -> + do_test(char_test, Config). + +double_test(doc) -> ""; +double_test(suite) -> []; +double_test(Config) -> + do_test(double_test, Config). + +enum_test(doc) -> ""; +enum_test(suite) -> []; +enum_test(Config) -> + do_test(enum_test, Config). + +inline_sequence_test(doc) -> ""; +inline_sequence_test(suite) -> []; +inline_sequence_test(Config) -> + do_test(inline_sequence_test, Config). + +long_long_test(doc) -> ""; +long_long_test(suite) -> []; +long_long_test(Config) -> + do_test(long_long_test, Config). + +long_test(doc) -> ""; +long_test(suite) -> []; +long_test(Config) -> + do_test(long_test, Config). + +octet_test(doc) -> ""; +octet_test(suite) -> []; +octet_test(Config) -> + do_test(octet_test, Config). + +pid_test(doc) -> ""; +pid_test(suite) -> []; +pid_test(Config) -> + do_test(pid_test, Config). + +port_test(doc) -> ""; +port_test(suite) -> []; +port_test(Config) -> + do_test(port_test, Config). + +ref_test(doc) -> ""; +ref_test(suite) -> []; +ref_test(Config) -> + do_test(ref_test, Config). + +seq1_test(doc) -> ""; +seq1_test(suite) -> []; +seq1_test(Config) -> + do_test(seq1_test, Config). + +seq2_test(doc) -> ""; +seq2_test(suite) -> []; +seq2_test(Config) -> + do_test(seq2_test, Config). + +seq3_test(doc) -> ""; +seq3_test(suite) -> []; +seq3_test(Config) -> + do_test(seq3_test, Config). + +seq4_test(doc) -> ""; +seq4_test(suite) -> []; +seq4_test(Config) -> + do_test(seq4_test, Config). + +seq5_test(doc) -> ""; +seq5_test(suite) -> []; +seq5_test(Config) -> + do_test(seq5_test, Config). + +string1_test(doc) -> ""; +string1_test(suite) -> []; +string1_test(Config) -> + do_test(string1_test, Config). + +string2_test(doc) -> ""; +string2_test(suite) -> []; +string2_test(Config) -> + do_test(string2_test, Config). + +string3_test(doc) -> ""; +string3_test(suite) -> []; +string3_test(Config) -> + do_test(string3_test, Config). + +string4_test(doc) -> ""; +string4_test(suite) -> []; +string4_test(Config) -> + do_test(string4_test, Config). + +struct2_test(doc) -> ""; +struct2_test(suite) -> []; +struct2_test(Config) -> + do_test(struct2_test, Config). + +struct_test(doc) -> ""; +struct_test(suite) -> []; +struct_test(Config) -> + do_test(struct_test, Config). + +term_sequence_test(doc) -> ""; +term_sequence_test(suite) -> []; +term_sequence_test(Config) -> + do_test(term_sequence_test, Config). + +term_struct_test(doc) -> ""; +term_struct_test(suite) -> []; +term_struct_test(Config) -> + do_test(term_struct_test, Config). + +term_test(doc) -> ""; +term_test(suite) -> []; +term_test(Config) -> + do_test(term_test, Config). + +typedef_test(doc) -> ""; +typedef_test(suite) -> []; +typedef_test(Config) -> + do_test(typedef_test, Config). + +unsigned_long_long_test(doc) -> ""; +unsigned_long_long_test(suite) -> []; +unsigned_long_long_test(Config) -> + do_test(unsigned_long_long_test, Config). + +unsigned_long_test(doc) -> ""; +unsigned_long_test(suite) -> []; +unsigned_long_test(Config) -> + do_test(unsigned_long_test, Config). + +unsigned_short_test(doc) -> ""; +unsigned_short_test(suite) -> []; +unsigned_short_test(Config) -> + do_test(unsigned_short_test, Config). + +void_test(doc) -> ""; +void_test(suite) -> []; +void_test(Config) -> + do_test(void_test, Config). + +wchar_test(doc) -> ""; +wchar_test(suite) -> []; +wchar_test(Config) -> + do_test(wchar_test, Config). + +wstring1_test(doc) -> ""; +wstring1_test(suite) -> []; +wstring1_test(Config) -> + do_test(wstring1_test, Config). + + +%% It is here that all tests really are done. +%% + +do_test(Case, Config) -> + %% Trap exits + process_flag(trap_exit, true), + %% Start the server + {ok, _Pid} = m_i:oe_create_link([], {local, ?ERLANG_SERVER_NAME}), + Node = atom_to_list(node()), + %% [NodeName, HostName] = string:tokens(Node, "@"), + DataDir = ?config(data_dir, Config), + %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]), + Cookie = atom_to_list(erlang:get_cookie()), + %% Start C-client node as a port program. + Cmd = filename:join([DataDir, "c_client"]) ++ + " -this-node-name " ++ atom_to_list(?C_CLIENT_NODE_NAME) ++ + " -peer-node " ++ Node ++ + " -peer-process-name " ++ atom_to_list(?ERLANG_SERVER_NAME) ++ + " -cookie " ++ Cookie ++ + " -test-case " ++ atom_to_list(Case), + Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]), + Res = wait_for_completion(Port), + %% Kill off node if there was timeout + case Res of + {error, timeout} -> + catch rpc:cast(?C_CLIENT_NODE_NAME, erlang, halt, [1]); + _ -> + ok + end, + process_flag(trap_exit, false), + catch m_i:stop(?ERLANG_SERVER_NAME), + ok = Res. + + +%% Wait for eof *and* exit status, but return if exit status indicates +%% an error, or we have been waiting more than PORT_TIMEOUT seconds. +%% +wait_for_completion(Port) -> + wait_for_completion(Port, 0). + +wait_for_completion(Port, N) when N < 2 -> + receive + {Port, {data, Bytes}} -> + %% Relay output + io:format("~s", [Bytes]), + wait_for_completion(Port, N); + {Port, {exit_status, 0}} -> + wait_for_completion(Port, N + 1); + {Port, {exit_status, Status}} -> + {error, Status}; + {Port, eof} -> + wait_for_completion(Port, N + 1); + {'EXIT', Port, Reason} -> + io:format("Port exited with reason: ~w~n", [Reason]), + wait_for_completion(Port, N); + {'EXIT', From, Reason} -> + io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]), + wait_for_completion(Port, N) + after ?PORT_TIMEOUT -> + {error, timeout} + end; +wait_for_completion(_, _) -> + ok. + + + diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src new file mode 100644 index 0000000000..62672e0b95 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src @@ -0,0 +1,146 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +# Makefile.src for c_client_erl_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@ + + +# Variables from ts: +# + +ERL_INCLUDE = @erl_include@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_LIB = @ic_libpath@@DS@@ic_lib@ + +ERL_INTERFACE_INCLUDE = @erl_interface_include@ +ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@ +ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@ +ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@ +ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@ + +CC = @CC@ +## XXX Should set warning flag with a DEBUG_FLAG +CFLAGS = @CFLAGS@ @DEFS@ -I@erl_include@ \ + -I@ic_include_path@ -I@erl_interface_include@ + +LD = @LD@ +LDFLAGS = @CROSSLDFLAGS@ +LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \ + $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS) +ERLC = erlc + +# Generated C header files +GEN_H_FILES = \ + m.h \ + m_i.h \ + oe_c_erl_test.h + +# Generated C files +GEN_C_FILES = \ + m.c \ + m_i.c \ + oe_c_erl_test.c \ + oe_code_m_a.c \ + oe_code_m_arr1.c \ + oe_code_m_arr2.c \ + oe_code_m_arr3.c \ + oe_code_m_aseq.c \ + oe_code_m_b.c \ + oe_code_m_bseq.c \ + oe_code_m_dd.c \ + oe_code_m_dyn.c \ + oe_code_m_dyn_sl.c \ + oe_code_m_es.c \ + oe_code_m_et.c \ + oe_code_m_etseq.c \ + oe_code_m_fruit.c \ + oe_code_m_lseq.c \ + oe_code_m_s.c \ + oe_code_m_s_sl.c \ + oe_code_m_sarr3.c \ + oe_code_m_simple.c \ + oe_code_m_ssarr3.c \ + oe_code_m_sseq.c \ + oe_code_m_ssstr3.c \ + oe_code_m_sstr3.c \ + oe_code_m_str1.c \ + oe_code_m_str3.c \ + oe_code_m_strRec.c \ + oe_code_m_strRec_str5.c \ + oe_code_m_strRec_str7.c + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_c_erl_test.hrl + +GEN_ERL_FILES = \ + m.erl \ + m_arr2.erl \ + m_arr3.erl \ + m_i.erl \ + m_str3.erl \ + oe_c_erl_test.erl + +C_FILES = $(GEN_C_FILES) c_client.c my.c + +OBJS = $(C_FILES:.c=@obj@) + +PGMS = c_client@exe@ + +ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl + +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(PGMS) $(EBINS) + +clean: + -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + +$(PGMS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(GEN_C_FILES) $(GEN_H_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_client}" \ + "+{user_protocol,my}" "+{c_timeout,{5000,5000}}" c_erl_test.idl + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" c_erl_test.idl + +.c@obj@: + $(CC) -c -o $*@obj@ $(CFLAGS) $< + +.erl.@EMULATOR@: + $(ERLC) -I $(IC_INCLUDE_PATH) $< + diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c new file mode 100644 index 0000000000..b2c5b0c836 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c @@ -0,0 +1,1763 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2010. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ +/* C-client for test of IC. + * + * TODO: + * + * 1. XXX #includes for VxWorks, Windows + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __WIN32__ +# include <unistd.h> +#endif + +#include <string.h> + +#ifdef __WIN32__ +# include <time.h> +# include <sys/timeb.h> +#elif defined VXWORKS +#include <time.h> +#include <sys/times.h> +#else +#include <sys/time.h> +#endif + +#include <ctype.h> + +#ifdef __WIN32__ +# include <winsock2.h> +# include <windows.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "ei.h" +#include "erl_interface.h" +#include "m_i.h" + +#define HOSTNAMESZ 256 +#define NODENAMESZ 512 + +#define INBUFSZ 10 +#define OUTBUFSZ 0 + +#define MAXTRIES 5 + +#define CHECK_EXCEPTION(x) \ + if ((x)->_major != CORBA_NO_EXCEPTION) { \ + fprintf(stderr,"\n\nException: %s\n\n", \ + (char *)CORBA_exception_value((x))); \ + CORBA_exception_free((x)); \ + return -1; \ + } \ + +/* XXX Should free things here too! */ +#define RETURN_IF_OK(x) \ + if ((x)) {\ + fprintf(stdout, "ok\n");\ + return 0;\ + }\ + +#define cmp_str(x,y) (!strcmp((x),(y))) +#define cmp_wstr(x,y) (!ic_wstrcmp((x),(y))) + +typedef CORBA_Environment IC_Env; + +typedef int (*TestFunc)(IC_Env *); +typedef struct { + char *name; + TestFunc func; +} TestCase; + +static char longtext[] = +"Introduction The IC application is an IDL compiler implemented in Erlang." +" The IDL compiler generates client stubs and server skeletons." +" Several back-ends are supported, and they fall into three main groups." +" For more details on IC compiler options consult the ic(3) manual page." +" Argument passing cases 1 Caller allocates all necessary storage," +" except that which may be encapsulated and managed within the parameter itself." +" 2 The caller allocates a pointer and passes it by reference to the callee." +" The callee sets the pointer to point to a valid instance of the parameter's type." +" The caller is responsible for releasing the returned storage." +" Following completion of a request, the caller is not allowed to modify any values" +" in the returned storage. To do so the caller must first copy the returned instance" +" into a new instance, then modify the new instance. 3 The caller allocates a" +" pointer to an array slice which has all the same dimensions of the original" +" array except the first, and passes it by reference to the callee. The callee sets" +" the pointer to point to a valid instance of the array. The caller is responsible for" +" releasing the returned storage. Following completion of a request, the caller is not" +" allowed to modify any values in the returned storage. To do so the caller must first" +" copy the returned instance into a new instance, then modify the new instance." +" Generated Files Two files will be generated for each scope. One set of files will be" +" generated for each module and each interface scope. An extra set is generated for" +" those definitions at top level scope. One of the files is a header file(.h), and the" +" other file is a C source code file (.c). In addition to these files a number of C" +" source files will be generated for type encodings, they are named according to the " +"following template: oe_code_<type>.c."; +static char this_node[NODENAMESZ + 1]; +static char *progname; + +/* Test function prototypes */ + +static int void_test(IC_Env *env); +static int long_test(IC_Env *env); +static int long_long_test(IC_Env *env); +static int unsigned_short_test(IC_Env *env); +static int unsigned_long_test(IC_Env *env); +static int unsigned_long_long_test(IC_Env *env); +static int double_test(IC_Env *env); +static int char_test(IC_Env *env); +static int wchar_test(IC_Env *env); +static int octet_test(IC_Env *env); +static int bool_test(IC_Env *env); +static int struct_test(IC_Env *env); +static int struct2_test(IC_Env *env); +static int seq1_test(IC_Env *env); +static int seq2_test(IC_Env *env); +static int seq3_test(IC_Env *env); +static int seq4_test(IC_Env *env); +static int seq5_test(IC_Env *env); +static int array1_test(IC_Env *env); +static int array2_test(IC_Env *env); +static int enum_test(IC_Env *env); +static int string1_test(IC_Env *env); +static int string2_test(IC_Env *env); +static int string3_test(IC_Env *env); +static int string4_test(IC_Env *env); +static int pid_test(IC_Env *env); +static int port_test(IC_Env *env); +static int ref_test(IC_Env *env); +static int term_test(IC_Env *env); +static int typedef_test(IC_Env *env); +static int inline_sequence_test(IC_Env *env); +static int term_sequence_test(IC_Env *env); +static int term_struct_test(IC_Env *env); +static int wstring1_test(IC_Env *env); + +static TestCase test_cases[] = { + {"void_test", void_test}, + {"long_test", long_test}, + {"long_long_test", long_long_test}, + {"unsigned_short_test", unsigned_short_test}, + {"unsigned_long_test", unsigned_long_test}, + {"unsigned_long_long_test", unsigned_long_long_test}, + {"double_test", double_test}, + {"char_test", char_test}, + {"wchar_test", wchar_test}, + {"octet_test", octet_test}, + {"bool_test", bool_test}, + {"struct_test", struct_test}, + {"struct2_test", struct2_test}, + {"seq1_test", seq1_test}, + {"seq2_test", seq2_test}, + {"seq3_test", seq3_test}, + {"seq4_test", seq4_test}, + {"seq5_test", seq5_test}, + {"array1_test", array1_test}, + {"array2_test", array2_test}, + {"enum_test", enum_test}, + {"string1_test", string1_test}, + {"string2_test", string2_test}, + {"string3_test", string3_test}, + {"string4_test", string4_test}, + {"pid_test", pid_test}, + {"port_test", port_test}, + {"ref_test", ref_test}, + {"term_test", term_test}, + {"typedef_test", typedef_test}, + {"inline_sequence_test", inline_sequence_test}, + {"term_sequence_test", term_sequence_test}, + {"term_struct_test", term_struct_test}, + {"wstring1_test", wstring1_test}, + {"", NULL} +}; + +/* Other prototypes */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2); +static int cmp_a(m_a *a1, m_a *a2); +static int cmp_bseq(m_bseq *b1, m_bseq *b2); +static int cmp_b(m_b *b1, m_b *b2); +static int cmp_lseq(m_lseq *b1, m_lseq *b2); +static int cmp_etseq(m_etseq *b1, m_etseq *b2); +static int cmp_et(m_et* b1, m_et *b2); +static int cmp_es(m_es *b1, m_es *b2); +static int cmp_arr1(m_arr1 b1, m_arr1 b2); +static int cmp_dd(m_dd b1, m_dd b2); +static int cmp_strRec(m_strRec *b1, m_strRec *b2); +static int cmp_sseq(m_sseq *b1, m_sseq *b2); +static int cmp_pid(erlang_pid *p1, erlang_pid *p2); +static int cmp_port(erlang_port *p1, erlang_port *p2); +static int cmp_ref(erlang_ref *p1, erlang_ref *p2); +static int cmp_s(m_s *b1, m_s *b2); +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2); +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2); +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2); +static int cmp_arr3(m_arr3 b1, m_arr3 b2); + +static void print_aseq(m_aseq *a); +static void print_a(m_a *a); +static void print_bseq(m_bseq *b); +static void print_lseq(m_lseq *b); +static void print_b(m_b *b); +static void print_etseq(m_etseq *b); +static void print_et(m_et* b); +static void print_es(m_es *b); +static void print_arr1(long a[500]); +static void print_dd(long a[2][3]); +static void print_strRec(m_strRec* sr); +static void print_sseq(m_sseq *b); +static void print_pid(erlang_pid *p); +static void print_port(erlang_port *p); +static void print_ref(erlang_ref *p); +static void print_term(ETERM *t); +static void print_s(m_s *p); +static void print_ssstr3(m_ssstr3 *b1); +static void print_ssarr3(m_ssarr3 *b1); +static void print_sarr3(m_sarr3 *b1); +static void print_arr3(m_arr3 b1); +static void print_wstr(CORBA_wchar *ws); + +static void free_etseq_buf(m_etseq *b); +static void free_et(m_et* b); + +#ifdef __WIN32__ +typedef struct { + long tv_sec; + long tv_usec; +} MyTimeval; +#else +typedef struct timeval MyTimeval; +#endif +static void my_gettimeofday(MyTimeval *tv); +static void showtime(MyTimeval *start, MyTimeval *stop); +static void usage(void); +static void done(int r); + + + +/* main */ + +#ifdef VXWORKS +int client(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + struct hostent *hp; + erlang_pid pid; + MyTimeval start, stop; + int i, fd, ires, tres; + IC_Env *env; + int tries = 0; + char *this_node_name = NULL; + char *peer_node = NULL; + char *peer_process_name = NULL; + char *cookie = NULL; + char host[HOSTNAMESZ + 1]; + TestFunc test_func = NULL; + TestCase *test_case; + char *test_case_name = NULL; + +#ifdef __WIN32__ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); + exit(1); + } +#endif + + progname = argv[0]; + host[HOSTNAMESZ] = '\0'; + if (gethostname(host, HOSTNAMESZ) < 0) { + fprintf(stderr, "Can't find own hostname\n"); + done(1); + } + if ((hp = gethostbyname(host)) == 0) { + fprintf(stderr, "Can't get ip address for host %s\n", host); + done(1); + } + for (i = 1; i < argc; i++) { + if (cmp_str(argv[i], "-help")) { + usage(); + done(0); + } else if (cmp_str(argv[i], "-this-node-name")) { + i++; + this_node_name = argv[i]; + } else if (cmp_str(argv[i], "-peer-node")) { + i++; + peer_node = argv[i]; + } else if (cmp_str(argv[i], "-peer-process-name")) { + i++; + peer_process_name = argv[i]; + } else if (cmp_str(argv[i], "-cookie")) { + i++; + cookie = argv[i]; + } else if (cmp_str(argv[i], "-test-case")) { + i++; + test_case_name = argv[i]; + } else { + fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); + usage(); + done(1); + } + } + + if (this_node_name == NULL || peer_node == NULL || test_case_name == NULL + || peer_process_name == NULL || cookie == NULL) { + fprintf(stderr, "Error: missing option\n"); + usage(); + done(1); + } + + test_case = test_cases; + while (test_case->func) { + if (cmp_str(test_case->name, test_case_name)) { + test_func = test_case->func; + break; + } + test_case++; + } + if (test_func == NULL) { + fprintf(stderr, "Error: illegal test case: \"%s\"\n", test_case_name); + done(1); + } + + /* Behead hostname at first dot */ + for (i=0; host[i] != '\0'; i++) { + if (host[i] == '.') { host[i] = '\0'; break; } + } + sprintf(this_node, "%s@%s", this_node_name, host); + fprintf(stderr, "c_client: this node: \"%s\"\n", this_node); + fprintf(stderr, "c_client: peer node: \"%s\"\n", peer_node); + fprintf(stderr, "c_client: test case: \"%s\"\n", test_case_name); + + fprintf(stderr, "c_client: starting\n"); + + /* initialize erl_interface */ + erl_init(NULL, 0); + + for (tries = 0; tries < MAXTRIES; tries++) { + + /* connect to erlang node */ + + ires = erl_connect_xinit(host, this_node_name, this_node, + (struct in_addr *)*hp->h_addr_list, + cookie, 0); + + fprintf(stderr, "c_client: erl_connect_xinit(): %d\n", ires); + + fd = erl_connect(peer_node); + fprintf(stderr, "c_client: erl_connect(): %d\n", fd); + + if (fd >= 0) + break; + fprintf(stderr, "c_client: cannot connect, retrying\n"); + } + if (fd < 0) { + fprintf(stderr, "c_client: cannot connect, exiting\n"); + done(1); + } + env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); + env->_fd = fd; + strcpy(env->_regname, peer_process_name); + env->_to_pid = NULL; + env->_from_pid = &pid; + + strcpy(pid.node, this_node); + pid.num = fd; + pid.serial = 0; + pid.creation = 0; + + my_gettimeofday(&start); + tres = test_func(env); /* Call test case */ + my_gettimeofday(&stop); + showtime(&start, &stop); + erl_close_connection(fd); + + printf("c_client: env->_inbuf before : %d\n", INBUFSZ); + printf("c_client: env->_outbuf before : %d\n", OUTBUFSZ); + printf("c_client: env->_inbuf after : %d\n", env->_inbufsz); + printf("c_client: env->_outbuf after : %d\n", env->_outbufsz); + + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + done(tres); +} + +static void usage() +{ + fprintf(stderr, "Usage: %s [-help] -this-node-name <name> " + "-peer-node <nodename> -peer-process-name <name> " + "-cookie <cookie> -test-case <test case name>\n", progname); + fprintf(stderr, "Example:\n %s -this-node-name kalle " + "-peer-node olle@home -peer-process-name idltest " + "-cookie oa678er -test-case octet_test\n", progname); +} + +static void done(int r) +{ +#ifdef __WIN32__ + WSACleanup(); +#endif + exit(r); +} + + +/* TESTS */ + +static int void_test(IC_Env *env) +{ + fprintf(stdout, "\n======== m_i_void test ======\n\n"); + m_i_void_test(NULL,env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(1); +} + +static int long_test(IC_Env *env) +{ + long l = 4711, lo, lr; + + fprintf(stdout, "\n======== m_i_long test ======\n\n"); + lr = m_i_long_test(NULL, l, &lo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(l == lo && l == lr); + if (l != lo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", l, lo); + if (l != lr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", l, lr); + return -1; +} + +static int long_long_test(IC_Env *env) +{ + CORBA_long_long ll = 4711, llo, llr; + + fprintf(stdout, "\n======== m_i_longlong test ======\n\n"); + llr = m_i_longlong_test(NULL, ll, &llo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ll == llo && ll == llr); + if (ll != llo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", + ll, llo); + if (ll != llr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", ll, llr); + return -1; +} + +static int unsigned_short_test(IC_Env *env) +{ + unsigned short x, y = 2, z; + + fprintf(stdout, "\n======== m_i_ushort test ======\n\n"); + x = m_i_ushort_test(NULL, y, &z, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(y == z && y == x); + if (y != z) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", y, z); + if (y != x) + fprintf(stdout, " result error, sent: %d, got: %d\n", y, x); + return -1; +} + + +static int unsigned_long_test(IC_Env *env) +{ + unsigned long ul = 5050, ulo, ulr; + + fprintf(stdout, "\n======== m_i_ulong test ======\n\n"); + ulr = m_i_ulong_test(NULL, ul, &ulo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ul == ulo && ul == ulr); + if (ul != ulo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ul, ulo); + if (ul != ulr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", ul, ulr); + return -1; +} + +/* + * Note: CORBA_unsigned_long_long is in fact a plain long. + */ +static int unsigned_long_long_test(IC_Env *env) +{ + CORBA_unsigned_long_long ull = 5050, ullo, ullr; + + fprintf(stdout, "\n======== m_i_ulonglong test ======\n\n"); + ullr = m_i_ulonglong_test(NULL, ull, &ullo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ull == ullo && ull == ullr); + if (ull != ullo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ull, ullo); + if (ull != ullr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + ull, ullr); + return -1; +} + +static int double_test(IC_Env *env) +{ + double d = 12.1212, db, dr; + + fprintf(stdout, "\n======== m_i_double test ======\n\n"); + dr = m_i_double_test(NULL, d, &db, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(d == db && d == dr); + if (d != db) + fprintf(stdout, " out parameter error, sent: %f, got: %f\n", d, db); + if (d != dr) + fprintf(stdout, " result error, sent: %f, got: %f\n", d, dr); + return -1; +} + +static int char_test(IC_Env *env) +{ + char c = 'g', co, cr; + + /* char test */ + fprintf(stdout, "\n======== m_i_char test ======\n\n"); + cr = m_i_char_test(NULL, c, &co, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(c == co && c == cr); + if (c !=co) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", c, co); + if (c != cr) + fprintf(stdout, " result error, sent: %c, got: %c\n", c, cr); + return -1; +} + +static int wchar_test(IC_Env *env) +{ + CORBA_wchar wc = 103, wco, wcr; + + fprintf(stdout, "\n======== m_i_wchar test ======\n\n"); + wcr = m_i_wchar_test(NULL, wc, &wco, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(wc == wco && wc == wcr); + if (wc != wco) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + wc, wco); + if (wc != wcr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + wc, wcr); + return -1; +} + +static int octet_test(IC_Env *env) +{ + char o ='r', oo, or; + + fprintf(stdout, "\n======== m_i_octet test ======\n\n"); + or = m_i_octet_test(NULL, o, &oo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(o == oo && o == or); + if (o != oo) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", o, oo); + if (o != or) + fprintf(stdout, " result error, sent: %c, got: %c\n", o, or); + return -1; +} + +static int bool_test(IC_Env *env) +{ + unsigned char i = 0, io, ir; + + fprintf(stdout, "\n======== m_i_bool test ======\n\n"); + ir = m_i_bool_test(NULL, i, &io, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(i == io && i == ir); + if (i != io) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", i, io); + if (i != ir) + fprintf(stdout, " result error, sent: %d, got: %d\n", i, ir); + return -1; +} + +static int struct_test(IC_Env *env) +{ + m_b b = {4711, 'a'}, bo, br; + + fprintf(stdout, "\n======== m_i_struct test ======\n\n"); + br = m_i_struct_test(NULL, &b, &bo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_b(&b, &bo) && cmp_b(&b, &br)); + if (!cmp_b(&b, &bo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&bo); + fprintf(stdout, "\n"); + } + if (!cmp_b(&b, &br)) { + fprintf(stdout, " result error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&br); + fprintf(stdout, "\n"); + } + return -1; +} + +static int struct2_test(IC_Env *env) +{ + m_es esi = {m_peach, 5050}, eso, esr; + + fprintf(stdout, "\n======== m_i_struct2 test ======\n\n"); + esr = m_i_struct2_test(NULL, &esi, &eso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_es(&esi, &eso) && cmp_es(&esi, &esr)); + if (!cmp_es(&esi, &eso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&eso); + fprintf(stdout, "\n"); + } + if (!cmp_es(&esi, &esr)) { + fprintf(stdout, " result error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&esr); + fprintf(stdout, "\n"); + } + return -1; +} + + +static int seq1_test(IC_Env *env) +{ + m_bseq bs, *bso, *bsr; + + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + bs._length = 3; + bs._buffer = ba; + + fprintf(stdout, "\n======== m_i_seq1 test ======\n\n"); + bsr = m_i_seq1_test(NULL, &bs, &bso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_bseq(&bs, bso) && cmp_bseq(&bs, bsr)); + if (!cmp_bseq(&bs, bso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bso); + fprintf(stdout, "\n"); + } + if (!cmp_bseq(&bs, bsr)) { + fprintf(stdout, " result error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bsr); + fprintf(stdout, "\n"); + } + CORBA_free(bso); + CORBA_free(bsr); + return -1; +} + +static int seq2_test(IC_Env *env) +{ + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + m_a a; + m_a aa[2]; + m_aseq as, *aso, *asr; + + a.l = 9999; + a.y._length = 3; + a.y._buffer = ba; + a.d = 66.89898989; + + aa[0] = a; + aa[1] = a; + as._length = 2; + as._buffer = aa; + + fprintf(stdout, "\n======== m_i_seq2 test ======\n\n"); + asr = m_i_seq2_test(NULL, &as, &aso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_aseq(&as, aso) && cmp_aseq(&as, asr)); + if (!cmp_aseq(&as, aso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(aso); + fprintf(stdout, "\n"); + } + if (!cmp_aseq(&as, asr)) { + fprintf(stdout, " result error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(asr); + fprintf(stdout, "\n"); + } + CORBA_free(aso); + CORBA_free(asr); + return -1; +} + +static int seq3_test(IC_Env *env) +{ + m_lseq lsi, *lso, *lsr; + long al[500]; + int i=0; + + for (i = 0; i < 500; i++) + al[i]=i; + lsi._length = 500; + lsi._buffer = al; + + fprintf(stdout, "\n======== m_i_seq3 test ======\n\n"); + lsr = m_i_seq3_test(NULL, &lsi, &lso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_lseq(&lsi, lso) && cmp_lseq(&lsi, lsr)); + if (!cmp_lseq(&lsi, lso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lso); + fprintf(stdout, "\n"); + } + if (!cmp_lseq(&lsi, lsr)) { + fprintf(stdout, " result error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lsr); + fprintf(stdout, "\n"); + } + CORBA_free(lso); + CORBA_free(lsr); + return -1; +} + +static int seq4_test(IC_Env *env) +{ + char *stra0[3] = {"a", "long", "time"}; + char *stra1[3] = {"ago", "there", "was"}; + char *stra2[3] = {"a", "buggy", "compiler"}; + m_sstr3 str3s[3] = {{3, 3, stra0}, {3, 3, stra1}, {3, 3, stra2}}; + m_ssstr3 str3ssi = {3, 3, str3s}; + m_ssstr3 *str3sso, *str3ssr; + + fprintf(stdout, "\n======== m_i_seq4 test ======\n\n"); + str3ssr = m_i_seq4_test(NULL, &str3ssi, &str3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssstr3(&str3ssi, str3sso) && + cmp_ssstr3(&str3ssi, str3ssr)); + if (!cmp_ssstr3(&str3ssi, str3sso)){ + fprintf(stdout, " out parameter error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssstr3(&str3ssi, str3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(str3sso); + CORBA_free(str3ssr); + return -1; +} + +static int seq5_test(IC_Env *env) +{ + m_arr3 arr3a[3] = { + {4711, 18931947, 3}, + {4711, 18931947, 3}, + {4711, 18931947, 3}}; + m_sarr3 arr3sa[3] = {{3, 3, arr3a}, {3, 3, arr3a}, {3, 3, arr3a}}; + m_ssarr3 arr3ssi = {3, 3, arr3sa}; + m_ssarr3 *arr3sso; + m_ssarr3 *arr3ssr; + + fprintf(stdout, "\n======== m_i_seq5 test ======\n\n"); + arr3ssr = m_i_seq5_test(NULL, &arr3ssi, &arr3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssarr3(&arr3ssi, arr3sso) && + cmp_ssarr3(&arr3ssi, arr3ssr)); + if (!cmp_ssarr3(&arr3ssi, arr3sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssarr3(&arr3ssi, arr3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(arr3sso); + CORBA_free(arr3ssr); + return -1; +} + +static int array1_test(IC_Env *env) +{ + int i; + long al[500]; + m_arr1 alo; + m_arr1_slice* alr; + + for (i = 0; i < 500; i++) + al[i]=i; + + fprintf(stdout, "\n======== m_i_array1 test ======\n\n"); + alr = m_i_array1_test(NULL, al, alo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_arr1(al, alo) && cmp_arr1(al, alr)); + if (!cmp_arr1(al, alo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alo); + fprintf(stdout, "\n"); + } + if (!cmp_arr1(al,alr)) { + fprintf(stdout, " result error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alr); + fprintf(stdout, "\n"); + } + free(alo); + free(alr); + return -1; +} + +static int array2_test(IC_Env *env) +{ + long dl[2][3] = {{11, 2, 7}, {22, 8 ,13}}; + m_dd dlo; + m_dd_slice* dlr; + + fprintf(stdout, "\n======== m_i_array2 test ======\n\n"); + dlr = m_i_array2_test(NULL, dl, dlo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_dd(dl,dlo) && cmp_dd(dl,dlr)); + if (!cmp_dd(dl,dlo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlo); + fprintf(stdout, "\n"); + } + if (!cmp_dd(dl,dlr)) { + fprintf(stdout, " result error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlr); + fprintf(stdout, "\n"); + } + free(*dlr); + return -1; +} + +static int enum_test(IC_Env *env) +{ + m_fruit ei = m_banana, eo, er; + + fprintf(stdout, "\n======== m_i_enum test ======\n\n"); + er = m_i_enum_test(NULL, ei, &eo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ei == eo && ei == er); + if (ei != eo) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", ei, eo); + if (ei != er) + fprintf(stdout, " result error, sent: %d, got: %d\n", ei, er); + return -1; +} + +static int string1_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string1 test ======\n\n"); + sr = m_i_string1_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, sr)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string2_test(IC_Env *env) +{ + char* sa[3] = {"hello", "foo", "bar"}; + m_sseq ssi = {3, 3, sa}; + m_sseq *sso, *ssr; + + fprintf(stdout, "\n======== m_i_string2 test ======\n\n"); + ssr = m_i_string2_test(NULL, &ssi, &sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_sseq(&ssi, sso) && cmp_sseq(&ssi, sso)); + if (!cmp_sseq(&ssi, sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(sso); + } + if (!cmp_sseq(&ssi, ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(ssr); + } + CORBA_free(sso); + CORBA_free(ssr); + return -1; +} + +static int string3_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string3 test ======\n\n"); + sr = m_i_string3_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, so)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string4_test(IC_Env *env) +{ + char as1[100] = "a string", as2[200] = "help", as3[200] = "hello there"; + m_strRec stri = { 1, /* dd */ + as1, /* str4 */ + {{'a', 'k'}, {'z', 'g'}, {'n', 'q'}}, /* str7 */ + {3, 3, "buf"}, /* str5 */ + as2, /* str6 */ + {'m', 'f', 'o'}, /* str8 */ + as3, /* str9 */ + {3, 3, "stu"} /* str10 */ + }; + m_strRec *stro, *strr; + + fprintf(stdout, "\n======== m_i_string4 test ======\n\n"); + strr = m_i_string4_test(NULL, &stri, &stro, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_strRec(&stri,stro) && cmp_strRec(&stri,strr)); + if (!cmp_strRec(&stri,stro)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(stro); + fprintf(stdout, "\n"); + } + if (!cmp_strRec(&stri,strr)) { + fprintf(stdout, " result error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(strr); + fprintf(stdout, "\n"); + } + CORBA_free(stro); + CORBA_free(strr); + return -1; +} + + +static int pid_test(IC_Env *env) +{ + erlang_pid pid = {"", 7, 0, 0}, pido, pidr; + + strcpy(pid.node, this_node), /* this currently running node */ + fprintf(stdout, "\n======== m_i_pid test ======\n\n"); + pidr = m_i_pid_test(NULL, &pid, &pido, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_pid(&pid, &pido) && cmp_pid(&pid, &pidr)); + if (!cmp_pid(&pid, &pido)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pido); + } + if (!cmp_pid(&pid, &pidr)) { + fprintf(stdout, " result error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pidr); + } + return -1; +} + +static int port_test(IC_Env *env) +{ + erlang_port porti = {"node", 5, 1}, porto, portr; + + fprintf(stdout, "\n======== m_i_port test ======\n\n"); + portr = m_i_port_test(NULL, &porti, &porto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_port(&porti, &porto) && cmp_port(&porti, &portr)); + if (!cmp_port(&porti, &porto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&porto); + } + if (!cmp_port(&porti, &portr)) { + fprintf(stdout, " result error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&portr); + } + return -1; +} + +static int ref_test(IC_Env *env) +{ + erlang_ref refi = { "node1", 3, {1, 2, 3}, 1}, + refo, refr; + + fprintf(stdout, "\n======== m_i_ref test ======\n\n"); + refr = m_i_ref_test(NULL, &refi, &refo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ref(&refi, &refo) && cmp_ref(&refi, &refr)); + if (!cmp_ref(&refi, &refo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refo); + } + if (!cmp_ref(&refi, &refr)) { + fprintf(stdout, " result error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refr); + } + return -1; +} + +static int term_test(IC_Env *env) +{ + ETERM *ti, *to, *tr; + + ti = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + + fprintf(stdout, "\n======== m_i_term test ======\n\n"); + tr = m_i_term_test(NULL, ti, &to, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(ti, to) && erl_match(ti, tr)); + if (!erl_match(ti, to)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(to); + } + if (!erl_match(ti, tr)) { + fprintf(stdout, " result error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(tr); + } + erl_free_term(ti); + erl_free_term(to); + erl_free_term(tr); + return -1; +} + +static int typedef_test(IC_Env *env) +{ + m_banan mbi, mbo; /* erlang_port */ + m_apa mai; /* ETERM* */ + m_apa mao = NULL; + long tl; + + strcpy(mbi.node,"node"); + mbi.id = 15; + mbi.creation = 1; + + fprintf(stdout, "\n======== m_i_typedef test ======\n\n"); + mai = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + tl = m_i_typedef_test(NULL, mai, &mbi, &mao, &mbo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(mai, mao) && cmp_port(&mbi, &mbo) && tl == 4711); + if (!erl_match(mai, mao)) { + fprintf(stdout, " out parameter error (term), sent:\n"); + print_term(mai); + fprintf(stdout, "got:\n"); + print_term(mao); + } + if (!cmp_port(&mbi, &mbo)) { + fprintf(stdout, " out parameter error (port), sent:\n"); + print_port(&mbi); + fprintf(stdout, "got:\n"); + print_port(&mbo); + } + if (tl != 4711) { + fprintf(stdout, " result error, sent: 4711, got %ld\n", tl); + } + erl_free_term(mai); + erl_free_term(mao); + return -1; +} + +static int inline_sequence_test(IC_Env *env) +{ + int i; + long al[500]; + m_s isi = {4711, {500, 10, al}}, + *iso, *isr; + + for (i = 0; i < 500; i++) + al[i]=i; + fprintf(stdout, "\n======== m_i_inline_sequence test ======\n\n"); + isr = m_i_inline_sequence_test(NULL, &isi, &iso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_s(&isi, iso) && cmp_s(&isi, isr)); + if (!cmp_s(&isi, iso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(iso); + } + if (!cmp_s(&isi, isr)) { + fprintf(stdout, " result error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(isr); + } + CORBA_free(iso); + CORBA_free(isr); + return -1; +} + +static int term_sequence_test(IC_Env *env) +{ + ETERM* et_array[4] = { + erl_format("[{apa, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{banan, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{apelsin, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{mango, 1, 23}, \"string\", {1.23, 45}]")}; + m_etseq etsi = {4, 4, et_array}, *etso, *etsr; + + fprintf(stdout, "\n======== m_i_term_sequence test ======\n\n"); + etsr = m_i_term_sequence_test(NULL, &etsi, &etso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_etseq(&etsi, etso) && cmp_etseq(&etsi, etsr)); + if (!cmp_etseq(&etsi, etso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etso); + } + if (!cmp_etseq(&etsi, etsr)) { + fprintf(stdout, " result error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etsr); + } + free_etseq_buf(&etsi); + free_etseq_buf(etso); + free_etseq_buf(etsr); + CORBA_free(etso); + CORBA_free(etsr); + return -1; +} + +static int term_struct_test(IC_Env *env) +{ + m_et eti = { erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"), + 121212 }; + m_et eto, etr; + + fprintf(stdout, "\n======== m_i_term_struct test ======\n\n"); + etr = m_i_term_struct_test(NULL, &eti, &eto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_et(&eti, &eto) && cmp_et(&eti, &etr)); + if (!cmp_et(&eti, &eto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&eto); + } + if (!cmp_et(&eti, &etr)) { + fprintf(stdout, " result error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&etr); + } + free_et(&eti); + free_et(&eto); + free_et(&etr); + return -1; +} + +static int wstring1_test(IC_Env *env) +{ + CORBA_wchar wsi[] = {100, 101, 102, 103, 104, 0}, *wso, *wsr; + + fprintf(stdout, "\n======== m_i_wstring1 test ======\n\n"); + wsr = m_i_wstring1_test(NULL, wsi, &wso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_wstr(wsi, wso) && cmp_wstr(wsi, wsr)); + if (!cmp_wstr(wsi, wso)) { + fprintf(stdout, " out parameter error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wso); + } + if (!cmp_wstr(wsi, wsr)) { + fprintf(stdout, " result error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wsr); + } + CORBA_free(wso); + CORBA_free(wsr); + return -1; +} + +/* Compare functions */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2) +{ + int i; + + if (a1->_length != a2->_length) + return 0; + for (i = 0; i < a1->_length; i++) + if (cmp_a(&(a1->_buffer[i]), &(a2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_a(m_a *a1, m_a *a2) +{ + return a1->l == a2->l && + a1->d == a2->d && + cmp_bseq(&a1->y, &a2->y); +} + +static int cmp_bseq(m_bseq *b1, m_bseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (cmp_b(&(b1->_buffer[i]), &(b2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_b(m_b *b1, m_b *b2) +{ + return b1->l == b2->l && b1->c == b2->c; +} + +static int cmp_lseq(m_lseq *b1, m_lseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (b1->_buffer[i] != b2->_buffer[i]) + return 0; + return 1; +} + +static int cmp_etseq(m_etseq *b1, m_etseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!erl_match(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + +static int cmp_et(m_et* b1, m_et *b2) +{ + return erl_match(b1->e, b2->e) && b1->l == b2->l; +} + +static int cmp_es(m_es *b1, m_es *b2) +{ + return b1->f == b2->f && b1->l == b2->l; +} + +static int cmp_arr1(m_arr1 b1, m_arr1 b2) +{ + int i; + + for (i = 0; i < 500; i++) + if (b1[i] != b2[i]) + return 0; + return 1; +} + +static int cmp_dd(m_dd b1, m_dd b2) +{ + + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1[i][j] != b2[i][j]) + return 0; + return 1; +} + + + +static int cmp_strRec(m_strRec *b1, m_strRec *b2) +{ + int i, j; + + if (b1->bb != b2->bb) + return 0; + if (!cmp_str(b1->str4,b2->str4)) + return 0; + if (b1->str5._length != b2->str5._length) + return 0; + for (j = 0; j < b1->str5._length; j++) + if (b1->str5._buffer[j] != b2->str5._buffer[j]) + return 0; + if (!cmp_str(b1->str6,b2->str6)) + return 0; + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1->str7[i][j] != b2->str7[i][j]) + return 0; + for (j = 0; j < 3; j++) + if (b1->str8[j] != b2->str8[j]) + return 0; + if (!cmp_str(b1->str9,b2->str9)) + return 0; + if (b1->str10._length != b2->str10._length) + return 0; + for (j = 0; j < b1->str10._length; j++) + if (b1->str10._buffer[j] != b2->str10._buffer[j]) + return 0; + return 1; +} + + +static int cmp_sseq(m_sseq *b1, m_sseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!cmp_str(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + + +static int cmp_pid(erlang_pid *p1, erlang_pid *p2) +{ + return cmp_str(p1->node,p2-> node) && + p1->num == p2->num && + p1->serial == p2->serial && + p1->creation == p2->creation; +} + +static int cmp_port(erlang_port *p1, erlang_port *p2) +{ + return cmp_str(p1->node,p2-> node) && p1->id == p2->id; +} + +static int cmp_ref(erlang_ref *p1, erlang_ref *p2) +{ + return cmp_str(p1->node, p2->node) && + p1->len == p2->len && + (p1->len < 1 || p1->n[0] == p2->n[0]) && + (p1->len < 2 || p1->n[1] == p2->n[1]) && + (p1->len < 3 || p1->n[2] == p2->n[2]); +} + +static int cmp_s(m_s *b1, m_s *b2) +{ + int i; + + if (b1->l != b2->l) + return 0; + if (b1->sl._length != b2->sl._length) + return 0; + for (i = 0; i < b1->sl._length; i++) + if (b1->sl._buffer[i] != b2->sl._buffer[i]) + return 0; + return 1; +} + + +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2) +{ + int i,j; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (b1->_buffer[i]._length != b2->_buffer[i]._length) + return 0; + for (j = 0; j < b1->_buffer[i]._length; j++) + if (!cmp_str(b1->_buffer[i]._buffer[j], + b2->_buffer[i]._buffer[j])) + return 0; + } + return 1; +} + + + +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_sarr3(&b1->_buffer[i], &b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_arr3(b1->_buffer[i], b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_arr3(m_arr3 b1, m_arr3 b2) +{ + int i; + + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) { + if (b1[i] != b2[i]) + return 0; + } + return 1; +} + +/* Print functions */ +static void print_aseq(m_aseq *a) +{ + int i; + fprintf(stdout, "\nm_aseq size: %ld --------\n", a->_length); + for (i = 0; i < a->_length; i++) + print_a(&(a->_buffer[i])); +} + +static void print_a(m_a *a) +{ + fprintf(stdout, "\nm_a --------\n l: %ld\n d:%f\n", a->l, a->d); + print_bseq(&a->y); +} + +static void print_bseq(m_bseq *b) +{ + int i; + + fprintf(stdout, "\nm_bseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + print_b(&(b->_buffer[i])); +} + +static void print_lseq(m_lseq *b) +{ + int i; + + fprintf(stdout, "\nm_lseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "[%d]: %ld\n", i, b->_buffer[i]); +} + +static void print_b(m_b *b) +{ + fprintf(stdout, "\nm_b --------\n l: %ld\n c: %c\n", b->l, b->c); +} + + +static void print_etseq(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) { + fprintf(stdout, "[%d]:\n", i); + erl_print_term(stdout, b->_buffer[i]); + } +} + + +static void print_et(m_et* b) +{ + fprintf(stdout, "\net struct --------\n"); + erl_print_term(stdout, b->e); + fprintf(stdout, "long: %ld\n", b->l); + fprintf(stdout, "\n--------\n"); +} + +static void print_es(m_es *b) +{ + fprintf(stdout, "\nm_es --------\n f: %d\n l: %ld\n", b->f, b->l); +} + + +static void print_arr1(long a[10]) +{ + int i; + + for (i = 0; i < 10; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, a[i]); +} + +static void print_dd(long a[2][3]) +{ + int i, j; + + fprintf(stdout, "\nlong dd[2][3] --------\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "\n[%d][%d]: %ld\n", i, j, a[i][j]); +} + + +static void print_strRec(m_strRec* sr) +{ + int i, j; + + fprintf(stdout, "\nboolean bb : %d\n",sr->bb); + fprintf(stdout, "string str4 : %s\n",sr->str4); + fprintf(stdout, "str7[2][3] :\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "str7[%d][%d]: %ld\n", i, j, sr->str7[i][j]); + fprintf(stdout, "str5._length : %ld\n",sr->str5._length); + for (j = 0; j < sr->str5._length; j++) + fprintf(stdout, "str5._buffer[%d]: %c\n", j, sr->str5._buffer[j]); + fprintf(stdout, "string str6 : %s\n",sr->str6); + fprintf(stdout, "str8 :\n"); + for (j = 0; j < 3; j++) + fprintf(stdout, "str8[%d]: %c\n", j, sr->str8[j]); + fprintf(stdout, "string str9 : %s\n",sr->str9); + fprintf(stdout, "str10._length : %ld\n",sr->str10._length); + for (j = 0; j < sr->str10._length; j++) + fprintf(stdout, "str10._buffer[%d]: %c\n", j, sr->str10._buffer[j]); +} + +static void print_sseq(m_sseq *b) +{ + int i; + + fprintf(stdout, "\nm_sseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "%s\n", b->_buffer[i]); + +} + + +static void print_pid(erlang_pid *p) +{ + fprintf(stdout, "\nerlang_pid --------\n node: %s\n num: %d\n " + "serial: %d\n creation: %d\n", + p->node, p->num, p->serial, p->creation); +} + +static void print_port(erlang_port *p) +{ + fprintf(stdout, "\nerlang_port --------\n node: %s\n id: %d\n " + "creation: %d\n", p->node, p->id, p->creation); +} + +static void print_ref(erlang_ref *p) +{ + fprintf(stdout, "\nerlang_ref --------\n node: %s\n len: %d\n " + "n[0]: %d\n n[1]: %d\n n[2]: %d\n creation: %d\n", + p->node, p->len, p->n[0], p->n[1], p->n[2], p->creation); +} + +static void print_term(ETERM *t) +{ + fprintf(stdout, "\nETERM --------\n"); + erl_print_term(stdout, t); + fprintf(stdout, "\n--------\n"); +} + +static void print_s(m_s *p) +{ + int i; + + fprintf(stdout, "\n%ld\n", p->l); + for (i = 0; i < p->sl._length; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, p->sl._buffer[i]); +} + + +static void print_ssstr3(m_ssstr3 *b1) +{ + int i,j; + + fprintf(stdout, "\nSSSTR3 --------\n"); + fprintf(stdout,"b1->_length = %ld\n",b1->_length); + for (i = 0; i < b1->_length; i++) { + fprintf(stdout,"\nb1->_buffer[%d]._length %ld\n", + i, b1->_buffer[i]._length); + for (j = 0; j < b1->_buffer[i]._length; j++) + fprintf(stdout,"b1->_buffer[%d]._buffer[%d] = %s\n", + i, j, b1->_buffer[i]._buffer[j]); + } + fprintf(stdout, "\n--------\n"); +} + +static void print_wstr(CORBA_wchar *ws) +{ + int i = 0; + + fprintf(stdout, "\nwstr --------\n"); + while (ws[i]) { + fprintf(stdout, "[%d]: %ld\n", i, ws[i]); + i++; + } + fprintf(stdout, "\n--------\n"); +} + + +static void print_ssarr3(m_ssarr3 *b1) +{ + int i; + + fprintf(stdout, "\nssarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_sarr3(&b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_sarr3(m_sarr3 *b1) +{ + int i; + + fprintf(stdout, "\nsarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_arr3(b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_arr3(m_arr3 b1) +{ + int i; + + fprintf(stdout, "\narr3 --------\n"); + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) + fprintf(stdout, "%ld ", b1[i]); + fprintf(stdout, "\n--------\n"); +} + +static void free_etseq_buf(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) + erl_free_term(b->_buffer[i]); +} + +static void free_et(m_et* b) +{ + erl_free_term(b->e); +} + +static void showtime(MyTimeval *start, MyTimeval *stop) +{ + MyTimeval elapsed; + + elapsed.tv_sec = stop->tv_sec - start->tv_sec; + elapsed.tv_usec = stop->tv_usec - start->tv_usec; + while (elapsed.tv_usec < 0) { + elapsed.tv_sec -= 1; + elapsed.tv_usec += 1000000; + } + fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); +} + +static void my_gettimeofday(MyTimeval *tv) +#ifdef __WIN32__ +#define EPOCH_JULIAN_DIFF 11644473600i64 +{ + SYSTEMTIME t; + FILETIME ft; + LONGLONG lft; + + GetSystemTime(&t); + SystemTimeToFileTime(&t, &ft); + memcpy(&lft, &ft, sizeof(lft)); + tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); + tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); +} +#elif defined VXWORKS +{ + int rate = sysClkRateGet(); /* Ticks per second */ + unsigned long ctick = tickGet(); + tv->tv_sec = ctick / rate; /* secs since reboot */ + tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; +} +#else +{ + gettimeofday(tv, NULL); +} +#endif diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl new file mode 100644 index 0000000000..e687cec114 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl @@ -0,0 +1,173 @@ + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2004-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +#include "erlang.idl" + + +const short TestConst = 1; + +module m { + + const short TestConst = 2; + + struct b { + long l; + char c; + }; + + struct simple { + long l; + b b_t; + }; + + enum fruit {orange, banana, apple, peach, pear}; + + typedef sequence<long> lseq; + + typedef sequence<b> bseq; + + struct a { + long l; + bseq y; + double d; + }; + + typedef sequence<a> aseq; + + typedef sequence<string> sseq; + typedef string str; + typedef long myLong; + + typedef long arr1[500], dd[2][3]; + + typedef erlang::term apa; + typedef erlang::port banan; + + typedef sequence<erlang::term> etseq; + + struct s { + long l; + sequence<long> sl; + }; + + struct es { + fruit f; + myLong l; + }; + + struct et { + erlang::term e; + long l; + }; + + + typedef sequence<char> str1; + typedef string<12> str2; + typedef char str3[3]; + + typedef sequence<string> sstr3; // sequence of string + typedef sequence<sstr3> ssstr3; // sequence of sequences of strings + + typedef long arr3[3]; // array of long + typedef sequence<arr3> sarr3; // sequence of array + typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings + + struct strRec{ + boolean bb; + string str4; + long str7[3][2]; + sequence<char> str5; + string<12> str6; + str3 str8; + str2 str9; + str1 str10; + }; + + + struct dyn { + long l; + sequence<long> sl; + }; + typedef dyn arr2[1][2]; + + + interface i { + + const short TestConst = 3; + + //arr2 suck(in arr2 x, out arr2 y ); + + ///////////////////////////////// attribute long l; + + // simple types + void void_test(); + long long_test(in long a, out long a1); + long long longlong_test(in long long a, out long long a1); + unsigned short ushort_test(in unsigned short a, out unsigned short a1); + unsigned long ulong_test(in unsigned long a, out unsigned long a1); + unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1); + double double_test(in double a, out double a1); + char char_test(in char a, out char a1); + wchar wchar_test(in wchar a, out wchar a1); + octet octet_test(in octet a, out octet a1); + boolean bool_test(in boolean a, out boolean a1); + + // Seq. and struct tests + b struct_test(in b a, out b a1); + es struct2_test(in es a, out es a1); + //simple struct3_test(in simple x, out simple y); + bseq seq1_test(in bseq a, out bseq a1); + aseq seq2_test(in aseq a, out aseq a1); + lseq seq3_test(in lseq a, out lseq a1); + ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1); + ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1); + + // Array tests + arr1 array1_test(in arr1 a, out arr1 a1); + dd array2_test(in dd a, out dd a1); + + // enum test + fruit enum_test(in fruit a, out fruit a1); + + // string tests + string string1_test(in string a, out string a1); + wstring wstring1_test(in wstring a, out wstring a1); + sseq string2_test(in sseq a, out sseq a1); + str string3_test(in str a, out str a1); + strRec string4_test(in strRec a, out strRec a1); + + // Special erlang types + erlang::pid pid_test(in erlang::pid a, out erlang::pid a1); + erlang::port port_test(in erlang::port a, out erlang::port a1); + erlang::ref ref_test(in erlang::ref a, out erlang::ref a1); + erlang::term term_test(in erlang::term a, out erlang::term a1); + + // typedef test + long typedef_test(in apa a, in banan b, out apa a1, out banan b1); + + // inlined seq. test + s inline_sequence_test(in s a, out s a1); + + // term seq. test + etseq term_sequence_test(in etseq a, out etseq a1); + // term struct test + et term_struct_test(in et a, out et a1); + + }; + +}; diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl new file mode 100644 index 0000000000..2e624ec5c0 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl @@ -0,0 +1,28 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(erl_server). + +-export([run/0, stop/0]). + +run() -> + m_i:oe_create(). + +stop() -> + gen_server:cast(cidl_test, stop). diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl new file mode 100644 index 0000000000..0c96fb9edf --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl @@ -0,0 +1,161 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(m_i_impl). +-include("m.hrl"). + +-export([init/1, terminate/2, void_test/1, long_test/2, ushort_test/2, + longlong_test/2, ulong_test/2, ulonglong_test/2, + double_test/2, char_test/2, wchar_test/2, octet_test/2, + bool_test/2, struct_test/2, struct2_test/2, seq1_test/2, + seq2_test/2, seq3_test/2, seq4_test/2, seq5_test/2, + array1_test/2, array2_test/2, enum_test/2, string1_test/2, + string2_test/2, string3_test/2, string4_test/2, pid_test/2, + port_test/2, ref_test/2, term_test/2, typedef_test/3, + inline_sequence_test/2, '_set_l'/2, '_get_l'/1, + term_struct_test/2, term_sequence_test/2, wstring1_test/2]). + +-define(PRINTDEBUG(Case), + io:format("erl_server: case: ~p~n" + "erl_server: location: ~p~n", [Case, [?FILE, ?LINE]])). +-define(PRINTDEBUG2(Case, Msg), + io:format("erl_server: case: ~p~n" + "erl_server: Msg: ~p~n" + "erl_server: location: ~p~n", [Case, Msg, [?FILE, ?LINE]])). + +init(Env) -> + {ok, []}. + +terminate(F, R) -> + ok. + +'_get_l'(State) -> + ?PRINTDEBUG("_get_l"), + {reply, State, State}. +void_test(State) -> + ?PRINTDEBUG("void_test"), + {reply, ok, State}. + +'_set_l'(State, V) -> + ?PRINTDEBUG2("_set_l", V), + {reply, ok, V}. +ushort_test(State, V) -> + ?PRINTDEBUG2("ushort_test", V), + {reply, {V, V}, State}. +long_test(State, V) -> + ?PRINTDEBUG2("long_test", V), + {reply, {V, V}, State}. +longlong_test(State, V) -> + ?PRINTDEBUG2("longlong_test", V), + {reply, {V, V}, State}. +ulong_test(State, V) -> + ?PRINTDEBUG2("ulong_test", V), + {reply, {V, V}, State}. +ulonglong_test(State, V) -> + ?PRINTDEBUG2("ulonglong_test", V), + {reply, {V, V}, State}. +double_test(State, V) -> + ?PRINTDEBUG2("double_test", V), + {reply, {V, V}, State}. +char_test(State, V) -> + ?PRINTDEBUG2("char_test", V), + {reply, {V, V}, State}. +wchar_test(State, V) -> + ?PRINTDEBUG2("wchar_test", V), + {reply, {V, V}, State}. +octet_test(State, V) -> + ?PRINTDEBUG2("octet_test", V), + {reply, {V, V}, State}. +bool_test(State, V) -> + ?PRINTDEBUG2("bool_test", V), + {reply, {V, V}, State}. + +struct_test(State, V) -> + ?PRINTDEBUG2("struct_test", V), + {reply, {V, V}, State}. +struct2_test(State, V) -> + ?PRINTDEBUG2("struct2_test", V), + {reply, {V, V}, State}. +seq1_test(State, V) -> + ?PRINTDEBUG2("seq1_test", V), + {reply, {V, V}, State}. +seq2_test(State, V) -> + ?PRINTDEBUG2("seq2_test", V), + {reply, {V, V}, State}. +seq3_test(State, V) -> + ?PRINTDEBUG2("seq3_test", V), + {reply, {V, V}, State}. +seq4_test(State, V) -> + ?PRINTDEBUG2("seq4_test", V), + {reply, {V, V}, State}. +seq5_test(State, V) -> + ?PRINTDEBUG2("seq5_test", V), + {reply, {V, V}, State}. +array1_test(State, V) -> + ?PRINTDEBUG2("array1_test", V), + {reply, {V, V}, State}. +array2_test(State, V) -> + ?PRINTDEBUG2("array2_test", V), + {reply, {V, V}, State}. +enum_test(State, V) -> + ?PRINTDEBUG2("enum_test", V), + {reply, {V, V}, State}. +string1_test(State, V) -> + ?PRINTDEBUG2("string1_test", V), + {reply, {V, V}, State}. +string2_test(State, V) -> + ?PRINTDEBUG2("string2_test", V), + {reply, {V, V}, State}. +string3_test(State, V) -> + ?PRINTDEBUG2("string3_test", V), + {reply, {V, V}, State}. +string4_test(State, V) -> + ?PRINTDEBUG2("string4_test", V), + {reply, {V, V}, State}. +pid_test(State, V) -> + ?PRINTDEBUG2("pid_test", V), + {reply, {V, V}, State}. +port_test(State, V) -> + ?PRINTDEBUG2("port_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +ref_test(State, V) -> + ?PRINTDEBUG2("ref_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +term_test(State, V) -> + ?PRINTDEBUG2("term_test", V), + {reply, {V, V}, State}. +typedef_test(State, A, B) -> + ?PRINTDEBUG2("typedef_test", [A,B]), + {reply, {4711, A, B}, State}. +inline_sequence_test(State, V) -> + ?PRINTDEBUG2("inline_sequence_test", V), + {reply, {V, V}, State}. +term_sequence_test(State, V) -> + ?PRINTDEBUG2("term_sequence_test", V), + {reply, {V, V}, State}. +term_struct_test(State, V) -> + ?PRINTDEBUG2("term_struct_test", V), + {reply, {V, V}, State}. +wstring1_test(State, V) -> + ?PRINTDEBUG2("wstring1_test", V), + {reply, {V, V}, State}. + + + + diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c new file mode 100644 index 0000000000..4e0be3fec1 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c @@ -0,0 +1,51 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ +#include "ic.h" +#include "m_i.h" + +int my_prepare_notification_encoding(CORBA_Environment *env) +{ + return oe_prepare_notification_encoding(env); +} + +int my_send_notification_tmo(CORBA_Environment *env, unsigned int send_ms) +{ + return oe_send_notification_tmo(env, send_ms); +} + +int my_prepare_request_encoding(CORBA_Environment *env) +{ + return oe_prepare_request_encoding(env); +} + +int my_send_request_and_receive_reply_tmo(CORBA_Environment *env, + unsigned int send_ms, + unsigned int recv_ms) +{ + return oe_send_request_and_receive_reply_tmo(env, send_ms, recv_ms); +} + +int my_prepare_reply_decoding(CORBA_Environment *env) +{ + return oe_prepare_reply_decoding(env); +} + + + diff --git a/lib/ic/test/erl_client_c_server_SUITE.erl b/lib/ic/test/erl_client_c_server_SUITE.erl new file mode 100644 index 0000000000..c5f5b6a218 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE.erl @@ -0,0 +1,350 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2002-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +%%---------------------------------------------------------------------- +%% Purpose : Test suite for erl-client/c-server +%%---------------------------------------------------------------------- + + +-module(erl_client_c_server_SUITE). +-include("test_server.hrl"). + +-export([init_per_testcase/2, fin_per_testcase/2, all/1, void_test/1, + long_test/1, longlong_test/1, ushort_test/1, ulong_test/1, + ulonglong_test/1, double_test/1, char_test/1, wchar_test/1, + octet_test/1, bool_test/1, struct_test/1, struct2_test/1, + seq1_test/1, seq2_test/1, seq3_test/1, seq4_test/1, + seq5_test/1, array1_test/1, array2_test/1, enum_test/1, + string1_test/1, string2_test/1, string3_test/1, + string4_test/1, pid_test/1, port_test/1, ref_test/1, + term_test/1, typedef_test/1, inline_sequence_test/1, + term_sequence_test/1, term_struct_test/1, wstring1_test/1]). + +-define(DEFAULT_TIMEOUT, 20000). +-define(PORT_TIMEOUT, 15000). +-define(CALL_TIMEOUT, 5000). + +-define(C_SERVER_NODE_NAME, idl_c_server_test). + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i, we have + %% to make sure we are using the right m_i module. + code:purge(m_i), + code:load_file(m_i), + + WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + +all(doc) -> + "Test of IC with an Erlang client and a C server. " + "The communication is via Erlang distribution."; +all(suite) -> + [void_test, long_test, longlong_test, ushort_test, + ulong_test, ulonglong_test, double_test, + char_test, wchar_test, octet_test, bool_test, struct_test, + struct2_test, seq1_test, seq2_test, seq3_test, seq4_test, + seq5_test, array1_test, array2_test, enum_test, string1_test, + string2_test, string3_test, string4_test, pid_test, port_test, + ref_test, term_test, typedef_test, inline_sequence_test, + term_sequence_test, term_struct_test, wstring1_test]. + + +array1_test(doc) -> ""; +array1_test(suite) -> []; +array1_test(Config) -> + do_test(array1_test, Config). + +array2_test(doc) -> ""; +array2_test(suite) -> []; +array2_test(Config) -> + do_test(array2_test, Config). + +bool_test(doc) -> ""; +bool_test(suite) -> []; +bool_test(Config) -> + do_test(bool_test, Config). + +char_test(doc) -> ""; +char_test(suite) -> []; +char_test(Config) -> + do_test(char_test, Config). + +double_test(doc) -> ""; +double_test(suite) -> []; +double_test(Config) -> + do_test(double_test, Config). + +enum_test(doc) -> ""; +enum_test(suite) -> []; +enum_test(Config) -> + do_test(enum_test, Config). + +inline_sequence_test(doc) -> ""; +inline_sequence_test(suite) -> []; +inline_sequence_test(Config) -> + do_test(inline_sequence_test, Config). + +longlong_test(doc) -> ""; +longlong_test(suite) -> []; +longlong_test(Config) -> + do_test(longlong_test, Config). + +long_test(doc) -> ""; +long_test(suite) -> []; +long_test(Config) -> + do_test(long_test, Config). + +octet_test(doc) -> ""; +octet_test(suite) -> []; +octet_test(Config) -> + do_test(octet_test, Config). + +pid_test(doc) -> ""; +pid_test(suite) -> []; +pid_test(Config) -> + do_test(pid_test, Config). + +port_test(doc) -> ""; +port_test(suite) -> []; +port_test(Config) -> + do_test(port_test, Config). + +ref_test(doc) -> ""; +ref_test(suite) -> []; +ref_test(Config) -> + do_test(ref_test, Config). + +seq1_test(doc) -> ""; +seq1_test(suite) -> []; +seq1_test(Config) -> + do_test(seq1_test, Config). + +seq2_test(doc) -> ""; +seq2_test(suite) -> []; +seq2_test(Config) -> + do_test(seq2_test, Config). + +seq3_test(doc) -> ""; +seq3_test(suite) -> []; +seq3_test(Config) -> + do_test(seq3_test, Config). + +seq4_test(doc) -> ""; +seq4_test(suite) -> []; +seq4_test(Config) -> + do_test(seq4_test, Config). + +seq5_test(doc) -> ""; +seq5_test(suite) -> []; +seq5_test(Config) -> + do_test(seq5_test, Config). + +string1_test(doc) -> ""; +string1_test(suite) -> []; +string1_test(Config) -> + do_test(string1_test, Config). + +string2_test(doc) -> ""; +string2_test(suite) -> []; +string2_test(Config) -> + do_test(string2_test, Config). + +string3_test(doc) -> ""; +string3_test(suite) -> []; +string3_test(Config) -> + do_test(string3_test, Config). + +string4_test(doc) -> ""; +string4_test(suite) -> []; +string4_test(Config) -> + do_test(string4_test, Config). + +struct2_test(doc) -> ""; +struct2_test(suite) -> []; +struct2_test(Config) -> + do_test(struct2_test, Config). + +struct_test(doc) -> ""; +struct_test(suite) -> []; +struct_test(Config) -> + do_test(struct_test, Config). + +term_sequence_test(doc) -> ""; +term_sequence_test(suite) -> []; +term_sequence_test(Config) -> + do_test(term_sequence_test, Config). + +term_struct_test(doc) -> ""; +term_struct_test(suite) -> []; +term_struct_test(Config) -> + do_test(term_struct_test, Config). + +term_test(doc) -> ""; +term_test(suite) -> []; +term_test(Config) -> + do_test(term_test, Config). + +typedef_test(doc) -> ""; +typedef_test(suite) -> []; +typedef_test(Config) -> + do_test(typedef_test, Config). + +ulonglong_test(doc) -> ""; +ulonglong_test(suite) -> []; +ulonglong_test(Config) -> + do_test(ulonglong_test, Config). + +ulong_test(doc) -> ""; +ulong_test(suite) -> []; +ulong_test(Config) -> + do_test(ulong_test, Config). + +ushort_test(doc) -> ""; +ushort_test(suite) -> []; +ushort_test(Config) -> + do_test(ushort_test, Config). + +void_test(doc) -> ""; +void_test(suite) -> []; +void_test(Config) -> + do_test(void_test, Config). + +wchar_test(doc) -> ""; +wchar_test(suite) -> []; +wchar_test(Config) -> + do_test(wchar_test, Config). + +wstring1_test(doc) -> ""; +wstring1_test(suite) -> []; +wstring1_test(Config) -> + do_test(wstring1_test, Config). + + +do_test(Case, Config) -> + %% Trap exits + process_flag(trap_exit, true), + Node = atom_to_list(node()), + [_NodeName, HostName] = string:tokens(Node, "@"), + DataDir = ?config(data_dir, Config), + %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]), + Cookie = atom_to_list(erlang:get_cookie()), + ServerNodeName = atom_to_list(?C_SERVER_NODE_NAME), + %% Start C-server node as a port program. We wait for the node + %% to connect to us. + Cmd = filename:join([DataDir, "c_server"]) ++ + " -this-node-name " ++ ServerNodeName ++ + " -peer-node " ++ Node ++ + " -cookie " ++ Cookie, + Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]), + ServerNode = list_to_atom(ServerNodeName ++ "@" ++ HostName), + Res = case wait_for_hidden_node(ServerNode) of + ok -> + %% Need a port for port_test and typedef_test + put(port_test_port, Port), + R = (catch erl_client:Case(ServerNode, ?CALL_TIMEOUT)), + case wait_for_completion(Port) of + {error, timeout} -> + kill_off_node(ServerNode); + _ -> + ok + end, + R; + {error, timeout} -> + case wait_for_completion(Port) of + {error, timeout} -> + kill_off_node(ServerNode); + _ -> + ok + end, + {error, timeout} + end, + process_flag(trap_exit, false), + true = Res. + + +%% Wait for eof *and* exit status, but return if exit status indicates +%% an error, or we have been waiting more than PORT_TIMEOUT seconds. +%% +wait_for_completion(Port) -> + wait_for_completion(Port, 0). + +wait_for_completion(Port, N) when N < 2 -> + receive + {Port, {data, Bytes}} -> + %% Relay output + io:format("~s", [Bytes]), + wait_for_completion(Port, N); + {Port, {exit_status, 0}} -> + wait_for_completion(Port, N + 1); + {Port, {exit_status, Status}} -> + {error, Status}; + {Port, eof} -> + wait_for_completion(Port, N + 1); + {'EXIT', Port, Reason} -> + io:format("Port exited with reason: ~w~n", [Reason]), + wait_for_completion(Port, N); + {'EXIT', From, Reason} -> + io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]), + wait_for_completion(Port, N) + after ?PORT_TIMEOUT -> + {error, timeout} + end; +wait_for_completion(_, _) -> + ok. + +wait_for_hidden_node(Node) -> + Times = ?DEFAULT_TIMEOUT div 100, + wait_for_hidden_node(Node, Times, 100). + +wait_for_hidden_node(Node, Times, WaitTime) when Times > 0 -> + io:format("Waiting for hidden node: ~p~n", [Node]), + case lists:member(Node, erlang:nodes(hidden)) of + true -> + ok; + false -> + delay(WaitTime), + wait_for_hidden_node(Node, Times - 1, WaitTime) + end; +wait_for_hidden_node(_Node, _, _WaitTime) -> + {error, timeout}. + +kill_off_node(Node) -> + catch rpc:cast(Node, erlang, halt, [1]). + +delay(Time) -> + receive + after Time -> + ok + end. + + + + diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src b/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src new file mode 100644 index 0000000000..cd34d2b247 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src @@ -0,0 +1,150 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +# Makefile.src for erl_client_c_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@ + + +# Variables from ts: +# + +ERL_INCLUDE = @erl_include@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_LIB = @ic_libpath@@DS@@ic_lib@ + +ERL_INTERFACE_INCLUDE = @erl_interface_include@ +ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@ +ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@ +ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@ +ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@ + +CC = @CC@ +## XXX Should set warning flag with a DEBUG_FLAG +CFLAGS = @CFLAGS@ @DEFS@ -I$(ERL_INCLUDE) \ + -I$(IC_INCLUDE_PATH) -I$(ERL_INTERFACE_INCLUDE) + +LD = @LD@ +LDFLAGS = @CROSSLDFLAGS@ +LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \ + $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS) +ERLC = erlc + +# Generated C header files +GEN_H_FILES = \ + m__s.h \ + m_i__s.h \ + oe_erl_c_test__s.h + +# Generated C files +GEN_C_FILES = \ + m__s.c \ + m_i__s.c \ + oe_code_m_a.c \ + oe_code_m_arr1.c \ + oe_code_m_arr2.c \ + oe_code_m_arr3.c \ + oe_code_m_aseq.c \ + oe_code_m_b.c \ + oe_code_m_bseq.c \ + oe_code_m_dd.c \ + oe_code_m_dyn.c \ + oe_code_m_dyn_sl.c \ + oe_code_m_es.c \ + oe_code_m_et.c \ + oe_code_m_etseq.c \ + oe_code_m_fruit.c \ + oe_code_m_lseq.c \ + oe_code_m_s.c \ + oe_code_m_s_sl.c \ + oe_code_m_sarr3.c \ + oe_code_m_simple.c \ + oe_code_m_ssarr3.c \ + oe_code_m_sseq.c \ + oe_code_m_ssstr3.c \ + oe_code_m_sstr3.c \ + oe_code_m_str1.c \ + oe_code_m_str3.c \ + oe_code_m_strRec.c \ + oe_code_m_strRec_str5.c \ + oe_code_m_strRec_str7.c \ + oe_erl_c_test__s.c + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_erl_c_test.hrl + +GEN_ERL_FILES = \ + m.erl \ + m_arr2.erl \ + m_arr3.erl \ + m_i.erl \ + m_str3.erl \ + oe_erl_c_test.erl + +C_FILES = $(GEN_C_FILES) c_server.c callbacks.c + +OBJS = $(C_FILES:.c=@obj@) + +PGMS = c_server@exe@ + +ERL_FILES = $(GEN_ERL_FILES) erl_client.erl + +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(PGMS) $(EBINS) + +clean: + -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + +$(PGMS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(GEN_C_FILES) $(GEN_H_FILES): erl_c_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_server}" \ + "+{scoped_op_calls,true}" erl_c_test.idl + +# If we have scoped operation calls for C, we must have that for +# Erlang as well, if we use the m_i.erl file for calling the server. + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): erl_c_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" \ + "+{scoped_op_calls,true}" "+{timeout,true}" erl_c_test.idl + +.c@obj@: + $(CC) -c -o $*@obj@ $(CFLAGS) $< + +.erl.@EMULATOR@: + $(ERLC) -W -I $(IC_INCLUDE_PATH) $< + diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c new file mode 100644 index 0000000000..acdeff80fe --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c @@ -0,0 +1,299 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ +/* C-server for test of IC. + * + * The C-node implemented here connects to its peer node, waits for + * one message, evaluates the message, returns an result message, and + * terminates. + * + * TODO: + * + * 1. XXX #includes for VxWorks, Windows + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __WIN32__ +# include <unistd.h> +#endif + +#include <string.h> + +#ifdef __WIN32__ +# include <time.h> +# include <sys/timeb.h> +#elif defined VXWORKS +# include <time.h> +# include <sys/times.h> +#else +# include <sys/time.h> +#endif + +#include <ctype.h> + +#ifdef __WIN32__ +# include <winsock2.h> +# include <windows.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "ic.h" +#include "ei.h" +#include "erl_interface.h" +#include "eicode.h" +#include "m_i__s.h" +#include "m__s.h" + +#ifdef __WIN32__ +typedef struct { + long tv_sec; + long tv_usec; +} MyTimeval; +#else +typedef struct timeval MyTimeval; +#endif +static void my_gettimeofday(MyTimeval *tv); +static void showtime(MyTimeval *start, MyTimeval *stop); +static void usage(void); +static void done(int r); + +#define HOSTNAMESZ 256 +#define NODENAMESZ 512 +#define INBUFSZ 10 +#define OUTBUFSZ 0 +#define MAXTRIES 5 + +static char *progname; + +/* main */ +#ifdef VXWORKS +int c_server(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + struct hostent *hp; + MyTimeval start, stop; + int i, fd, ires, tries; + CORBA_Environment *env; + char *this_node_name = NULL; + char *peer_node = NULL; + char *cookie = NULL; + char host[HOSTNAMESZ + 1]; + char this_node[NODENAMESZ + 1]; + erlang_msg msg; + int status, loop; + +#ifdef __WIN32__ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); + exit(1); + } +#endif + + progname = argv[0]; + host[HOSTNAMESZ] = '\0'; + if (gethostname(host, HOSTNAMESZ) < 0) { + fprintf(stderr, "Can't find own hostname\n"); + done(1); + } + if ((hp = gethostbyname(host)) == 0) { + fprintf(stderr, "Can't get ip address for host %s\n", host); + done(1); + } + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-help") == 0) { + usage(); + done(0); + } else if (strcmp(argv[i], "-this-node-name") == 0) { + i++; + this_node_name = argv[i]; + } else if (strcmp(argv[i], "-peer-node") == 0) { + i++; + peer_node = argv[i]; + } else if (strcmp(argv[i], "-cookie") == 0) { + i++; + cookie = argv[i]; + } else { + fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); + usage(); + done(1); + } + } + + if (this_node_name == NULL || peer_node == NULL || cookie == NULL) { + fprintf(stderr, "Error: missing option\n"); + usage(); + done(1); + } + + /* Behead hostname at first dot */ + for (i=0; host[i] != '\0'; i++) { + if (host[i] == '.') { host[i] = '\0'; break; } + } + sprintf(this_node, "%s@%s", this_node_name, host); + + fprintf(stderr, "c_server: this node: \"%s\"\n", this_node); + fprintf(stderr, "c_server: peer node: \"%s\"\n", peer_node); + + /* initialize erl_interface */ + erl_init(NULL, 0); + + for (tries = 0; tries < MAXTRIES; tries++) { + /* connect to peer node */ + ires = erl_connect_xinit(host, this_node_name, this_node, + (struct in_addr *)*hp->h_addr_list, + cookie, 0); + fprintf(stderr, "c_server: erl_connect_xinit(): %d\n", ires); + + fd = erl_connect(peer_node); + fprintf(stderr, "c_server: erl_connect(): %d\n", fd); + if (fd >= 0) + break; + fprintf(stderr, "c_server: cannot connect, retrying\n"); + } + if (fd < 0) { + fprintf(stderr, "c_server: cannot connect, exiting\n"); + done(1); + } + env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); + env->_fd = fd; + + status = 1; + loop = 1; + my_gettimeofday(&start); + while (status >= 0 && loop > 0) { + status = ei_receive_encoded(env->_fd, &env->_inbuf, &env->_inbufsz, + &msg, &env->_iin); + switch(status) { + case ERL_SEND: + case ERL_REG_SEND: + /* get result */ + m_i__switch(NULL, env); + switch(env->_major) { + case CORBA_NO_EXCEPTION: + break; + case CORBA_SYSTEM_EXCEPTION: + fprintf(stderr, "Request failure, reason : %s\n", + (char *) CORBA_exception_value(env)); + CORBA_exception_free(env); + break; + default: /* Should not happen */ + CORBA_exception_free(env); + break; + } + /* send back result data */ + if (env->_iout > 0) + ei_send_encoded(env->_fd, &env->_caller, env->_outbuf, + env->_iout); + loop = 0; + break; + case ERL_TICK: + break; + default: + if (status < 0) { + fprintf(stderr, "Status negative: %d\n", status); + loop = 0; + } + break; + } + } + my_gettimeofday(&stop); + showtime(&start, &stop); + + erl_close_connection(fd); + + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + if (status < 0) + done(-status); + else + done(0); +} + +static void usage() +{ + fprintf(stderr, "Usage: %s [-help] -this-node-name <name> " + "-peer-node <nodename> -cookie <cookie>\n", progname); + fprintf(stderr, "Example:\n %s -this-node-name kalle " + "-peer-node olle@home -cookie oa678er\n", progname); +} + +static void done(int r) +{ +#ifdef __WIN32__ + WSACleanup(); +#endif + exit(r); +} + +static void showtime(MyTimeval *start, MyTimeval *stop) +{ + MyTimeval elapsed; + + elapsed.tv_sec = stop->tv_sec - start->tv_sec; + elapsed.tv_usec = stop->tv_usec - start->tv_usec; + while (elapsed.tv_usec < 0) { + elapsed.tv_sec -= 1; + elapsed.tv_usec += 1000000; + } + fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); +} + + + +static void my_gettimeofday(MyTimeval *tv) +#ifdef __WIN32__ +#define EPOCH_JULIAN_DIFF 11644473600i64 +{ + SYSTEMTIME t; + FILETIME ft; + LONGLONG lft; + + GetSystemTime(&t); + SystemTimeToFileTime(&t, &ft); + memcpy(&lft, &ft, sizeof(lft)); + tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); + tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); +} +#elif defined VXWORKS +{ + int rate = sysClkRateGet(); /* Ticks per second */ + unsigned long ctick = tickGet(); + tv->tv_sec = ctick / rate; /* secs since reboot */ + tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; +} +#else +{ + gettimeofday(tv, NULL); +} +#endif diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c b/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c new file mode 100644 index 0000000000..d6b28b619d --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c @@ -0,0 +1,610 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ +#include <stdio.h> +#include <stdlib.h> +#ifndef __WIN32__ +# include <unistd.h> +#endif +#include <string.h> +#include <ctype.h> +#include <ic.h> +#include <erl_interface.h> +#include <ei.h> +#include "m_i__s.h" + + + +/* OK */ + +void my_void_test(CORBA_Object oe_obj, + CORBA_Environment *oe_env) +{ + /* printf("void test !\n"); */ +} + +m_i_void_test__rs* m_i_void_test__cb(CORBA_Object oe_obj, + CORBA_Environment *oe_env) +{ + return (m_i_void_test__rs*) (my_void_test); +} + + + +/* OK */ + +void my_long_test(CORBA_Object oe_obj, + long* a, + long* b, + long* c, + CORBA_Environment *oe_env) +{ + /* printf("long test !\n"); */ +} + + +m_i_long_test__rs* m_i_long_test__cb(CORBA_Object oe_obj, + long* a, + long* b, + long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_long_test__rs*) (my_long_test); +} + +/* OK */ + +void my_longlong_test(CORBA_Object oe_obj, + CORBA_long_long* a, + CORBA_long_long* b, + CORBA_long_long* c, + CORBA_Environment *oe_env) +{ + /* printf("long test !\n"); */ +} + +m_i_longlong_test__rs* m_i_longlong_test__cb(CORBA_Object oe_obj, + CORBA_long_long* a, + CORBA_long_long* b, + CORBA_long_long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_longlong_test__rs*) (my_longlong_test); +} + +/* OK */ +void my_ulong_test(CORBA_Object oe_obj, + unsigned long* a, + unsigned long* b, + unsigned long* c, + CORBA_Environment *oe_env) +{ + /* printf("ulong test !\n"); */ +} + +m_i_ulong_test__rs* m_i_ulong_test__cb(CORBA_Object oe_obj, + unsigned long* a, + unsigned long* b, + unsigned long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ulong_test__rs*) (my_ulong_test); +} + +/* OK */ +void my_ulonglong_test(CORBA_Object oe_obj, + CORBA_unsigned_long_long* a, + CORBA_unsigned_long_long* b, + CORBA_unsigned_long_long* c, + CORBA_Environment *oe_env) +{ + /* printf("ulong test !\n"); */ +} + +m_i_ulonglong_test__rs* m_i_ulonglong_test__cb(CORBA_Object oe_obj, + CORBA_unsigned_long_long* a, + CORBA_unsigned_long_long* b, + CORBA_unsigned_long_long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ulonglong_test__rs*) (my_ulonglong_test); +} + +m_i_ushort_test__rs* m_i_ushort_test__cb(CORBA_Object oe_obj, + unsigned short* a, + unsigned short* b, + unsigned short* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ushort_test__rs*) NULL; +} + + +/* OK */ +void my_double_test(CORBA_Object oe_obj, + double* a, + double* b, + double* c, + CORBA_Environment *oe_env) +{ + /* printf("double test !\n"); */ +} + +m_i_double_test__rs* m_i_double_test__cb(CORBA_Object oe_obj, + double* a, + double* b, + double* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_double_test__rs*) (my_double_test); +} + +/* OK */ +m_i_char_test__rs* m_i_char_test__cb(CORBA_Object oe_obj, + char* a, + char* b, + char* c, + CORBA_Environment *oe_env) +{ + m_i_char_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + + +/* OK */ +m_i_wchar_test__rs* m_i_wchar_test__cb(CORBA_Object oe_obj, + CORBA_wchar* a, + CORBA_wchar* b, + CORBA_wchar* c, + CORBA_Environment *oe_env) +{ + m_i_wchar_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_octet_test__rs* m_i_octet_test__cb(CORBA_Object oe_obj, + char* a, + char* b, + char* c, + CORBA_Environment *oe_env) +{ + m_i_octet_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_bool_test__rs* m_i_bool_test__cb(CORBA_Object oe_obj, + CORBA_boolean* a, + CORBA_boolean* b, + CORBA_boolean* c, + CORBA_Environment *oe_env) +{ + m_i_bool_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +void my_struct_test(CORBA_Object oe_obj, + m_b* a, + m_b* b, + m_b* c, + CORBA_Environment *oe_env) +{ + /* printf("struct test !\n"); */ +} + +m_i_struct_test__rs* m_i_struct_test__cb(CORBA_Object oe_obj, + m_b* a, + m_b* b, + m_b* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_struct_test__rs*) (my_struct_test); +} + +/* OK */ +m_i_struct2_test__rs* m_i_struct2_test__cb(CORBA_Object oe_obj, + m_es* a, + m_es* b, + m_es* c, + CORBA_Environment *oe_env) +{ + m_i_struct2_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +/* XXX Commented out +m_i_struct3_test__rs* m_i_struct3_test__cb(CORBA_Object oe_obj, + m_simple* a, + m_simple* b, + m_simple* c, + CORBA_Environment *oe_env) +{ + m_i_struct3_test__rs* rs = NULL; + *a = *b; + *c = *b; + return rs; +} +*/ + +/* OK */ +m_i_seq1_test__rs* m_i_seq1_test__cb(CORBA_Object oe_obj, + m_bseq** a, + m_bseq* b, + m_bseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq1_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_seq2_test__rs* m_i_seq2_test__cb(CORBA_Object oe_obj, + m_aseq** a, + m_aseq* b, + m_aseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq2_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq3_test__rs* m_i_seq3_test__cb(CORBA_Object oe_obj, + m_lseq** a, + m_lseq* b, + m_lseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq3_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq4_test__rs* m_i_seq4_test__cb(CORBA_Object oe_obj, + m_ssstr3** a, + m_ssstr3* b, + m_ssstr3** c, + CORBA_Environment *oe_env) +{ + m_i_seq4_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq5_test__rs* m_i_seq5_test__cb(CORBA_Object oe_obj, + m_ssarr3** a, + m_ssarr3* b, + m_ssarr3** c, + CORBA_Environment *oe_env) +{ + m_i_seq5_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_array1_test__rs* m_i_array1_test__cb(CORBA_Object oe_obj, + m_arr1 a, + m_arr1 b, + m_arr1 c, + CORBA_Environment *oe_env) +{ + int i; + m_i_array1_test__rs* rs = NULL; + + for (i = 0; i < 500; i++) { + a[i] = b[i]; + c[i] = b[i]; + } + return rs; +} + +/* OK */ +m_i_array2_test__rs* m_i_array2_test__cb(CORBA_Object oe_obj, + m_dd a, + m_dd b, + m_dd c, + CORBA_Environment *oe_env) +{ + int i,j; + m_i_array2_test__rs* rs = NULL; + + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) { + a[i][j] = b[i][j]; + c[i][j] = b[i][j]; + } + return rs; +} + + +/* OK */ +m_i_enum_test__rs* m_i_enum_test__cb(CORBA_Object oe_obj, + m_fruit* a, + m_fruit* b, + m_fruit* c, + CORBA_Environment *oe_env) +{ + m_i_enum_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_string1_test__rs* m_i_string1_test__cb(CORBA_Object oe_obj, + char ** a, + char * b, + char ** c, + CORBA_Environment *oe_env) +{ + m_i_string1_test__rs* rs = NULL; + + /*printf("\nString in ------> %s\n\n",b);*/ + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_string2_test__rs* m_i_string2_test__cb(CORBA_Object oe_obj, + m_sseq** a, + m_sseq* b, + m_sseq** c, + CORBA_Environment *oe_env) +{ + m_i_string2_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_string3_test__rs* m_i_string3_test__cb(CORBA_Object oe_obj, + char ** a, + char * b, + char ** c, + CORBA_Environment *oe_env) +{ + m_i_string3_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +m_i_string4_test__rs* m_i_string4_test__cb(CORBA_Object oe_obj, + m_strRec** a, + m_strRec* b, + m_strRec** c, + CORBA_Environment *oe_env) +{ + *a = b; + *c = b; + + return (m_i_string4_test__rs*) NULL; +} + +/* OK */ +m_i_wstring1_test__rs* m_i_wstring1_test__cb(CORBA_Object oe_obj, + CORBA_wchar ** a, + CORBA_wchar * b, + CORBA_wchar ** c, + CORBA_Environment *oe_env) +{ + int tmp; + m_i_wstring1_test__rs* rs = NULL; + + /*printf("\nString in ------> %s\n\n",b);*/ + + for(tmp = 0; tmp < 5; tmp++) + fprintf(stderr,"\np[%d] = %ld\n", tmp, b[tmp]); + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_pid_test__rs* m_i_pid_test__cb(CORBA_Object oe_obj, + erlang_pid* a, + erlang_pid* b, + erlang_pid* c, + CORBA_Environment *oe_env) +{ + m_i_pid_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_port_test__rs* m_i_port_test__cb(CORBA_Object oe_obj, + erlang_port* a, + erlang_port* b, + erlang_port* c, + CORBA_Environment *oe_env) +{ + m_i_port_test__rs* rs = NULL; + + strcpy((*a).node,(*b).node); + (*a).id = (*b).id; + (*a).creation = 0; + + strcpy((*c).node,(*b).node); + (*c).id = (*b).id; + (*c).creation = 0; + return rs; +} + +/* OK */ +m_i_ref_test__rs* m_i_ref_test__cb(CORBA_Object oe_obj, + erlang_ref* a, + erlang_ref* b, + erlang_ref* c, + CORBA_Environment *oe_env) +{ + + m_i_ref_test__rs* rs = NULL; + + strcpy((*a).node,(*b).node); + /*(*a).id = (*b).id;*/ + (*a).len = (*b).len; + (*a).n[0] = (*b).n[0]; + (*a).n[1] = (*b).n[1]; + (*a).n[2] = (*b).n[2]; + (*a).creation = 0; + + strcpy((*c).node,(*b).node); + /*(*c).id = (*b).id;*/ + (*c).len = (*b).len; + (*c).n[0] = (*b).n[0]; + (*c).n[1] = (*b).n[1]; + (*c).n[2] = (*b).n[2]; + (*c).creation = 0; + return rs; +} + +/* OK */ +m_i_term_test__rs* m_i_term_test__cb(CORBA_Object oe_obj, + ETERM** a, + ETERM** b, + ETERM** c, + CORBA_Environment *oe_env) +{ + m_i_term_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +m_i_typedef_test__rs* m_i_typedef_test__cb(CORBA_Object oe_obj, + long* a, + ETERM** b, + erlang_port* c, + ETERM** d , + erlang_port* e, + CORBA_Environment *oe_env) +{ + m_i_typedef_test__rs* rs = NULL; + + *d = *b; + strcpy((*e).node,(*c).node); + (*e).id = (*c).id; + (*e).creation = 0; + *a = 4711; + return rs; +} + +/* OK */ +m_i_inline_sequence_test__rs* m_i_inline_sequence_test__cb( + CORBA_Object oe_obj, + m_s** a, + m_s* b, + m_s** c, + CORBA_Environment *oe_env) +{ + m_i_inline_sequence_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_term_sequence_test__rs* m_i_term_sequence_test__cb( + CORBA_Object oe_obj, + m_etseq** a, + m_etseq* b, + m_etseq** c, + CORBA_Environment *oe_env) +{ + m_i_term_sequence_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_term_struct_test__rs* m_i_term_struct_test__cb(CORBA_Object oe_obj, + m_et* a, + m_et* b, + m_et* c, + CORBA_Environment *oe_env) +{ + m_i_term_struct_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl b/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl new file mode 100644 index 0000000000..963bc69017 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl @@ -0,0 +1,174 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2002-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +#include "erlang.idl" + + +const short TestConst = 1; + +module m { + + const short TestConst = 2; + + struct b { + long l; + char c; + }; + + struct simple { + long l; + b b_t; + }; + + enum fruit {orange, banana, apple, peach, pear}; + + typedef sequence<long> lseq; + + typedef sequence<b> bseq; + + struct a { + long l; + bseq y; + double d; + }; + + typedef sequence<a> aseq; + + typedef sequence<string> sseq; + typedef string str; + typedef long myLong; + + typedef long arr1[500], dd[2][3]; + + typedef erlang::term apa; + typedef erlang::port banan; + + typedef sequence<erlang::term> etseq; + + struct s { + long l; + sequence<long> sl; + }; + + struct es { + fruit f; + myLong l; + }; + + struct et { + erlang::term e; + long l; + }; + + + typedef sequence<char> str1; + typedef string<12> str2; + typedef char str3[3]; + + typedef sequence<string> sstr3; // sequence of string + typedef sequence<sstr3> ssstr3; // sequence of sequences of strings + + typedef long arr3[3]; // array of long + typedef sequence<arr3> sarr3; // sequence of array + typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings + + struct strRec{ + boolean bb; + string str4; + long str7[3][2]; + sequence<char> str5; + string<12> str6; + str3 str8; + str2 str9; + str1 str10; + }; + + + struct dyn { + long l; + sequence<long> sl; + }; + typedef dyn arr2[1][2]; + + + interface i { + + const short TestConst = 3; + + //arr2 suck(in arr2 x, out arr2 y ); + + ///////////////////////////////// attribute long l; + + // simple types + void void_test(); + long long_test(in long a, out long a1); + long long longlong_test(in long long a, out long long a1); + unsigned short ushort_test(in unsigned short a, out unsigned short a1); + unsigned long ulong_test(in unsigned long a, out unsigned long a1); + unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1); + double double_test(in double a, out double a1); + char char_test(in char a, out char a1); + wchar wchar_test(in wchar a, out wchar a1); + octet octet_test(in octet a, out octet a1); + boolean bool_test(in boolean a, out boolean a1); + + // Seq. and struct tests + b struct_test(in b a, out b a1); + es struct2_test(in es a, out es a1); + //simple struct3_test(in simple x, out simple y); + bseq seq1_test(in bseq a, out bseq a1); + aseq seq2_test(in aseq a, out aseq a1); + lseq seq3_test(in lseq a, out lseq a1); + ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1); + ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1); + + // Array tests + arr1 array1_test(in arr1 a, out arr1 a1); + dd array2_test(in dd a, out dd a1); + + // enum test + fruit enum_test(in fruit a, out fruit a1); + + // string tests + string string1_test(in string a, out string a1); + wstring wstring1_test(in wstring a, out wstring a1); + sseq string2_test(in sseq a, out sseq a1); + str string3_test(in str a, out str a1); + strRec string4_test(in strRec a, out strRec a1); + + // Special erlang types + erlang::pid pid_test(in erlang::pid a, out erlang::pid a1); + erlang::port port_test(in erlang::port a, out erlang::port a1); + erlang::ref ref_test(in erlang::ref a, out erlang::ref a1); + erlang::term term_test(in erlang::term a, out erlang::term a1); + + // typedef test + long typedef_test(in apa a, in banan b, out apa a1, out banan b1); + + // inlined seq. test + s inline_sequence_test(in s a, out s a1); + + // term seq. test + etseq term_sequence_test(in etseq a, out etseq a1); + // term struct test + et term_struct_test(in et a, out et a1); + + }; + +}; diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl b/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl new file mode 100644 index 0000000000..79ec28a921 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl @@ -0,0 +1,331 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2002-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(erl_client). + +-export([void_test/2, long_test/2, longlong_test/2, ushort_test/2, + ulong_test/2, ulonglong_test/2, double_test/2, char_test/2, + wchar_test/2, octet_test/2, bool_test/2, struct_test/2, + struct2_test/2, seq1_test/2, seq2_test/2, seq3_test/2, + seq4_test/2, seq5_test/2, array1_test/2, array2_test/2, + enum_test/2, string1_test/2, wstring1_test/2, string2_test/2, + string3_test/2, string4_test/2, pid_test/2, port_test/2, + ref_test/2, term_test/2, typedef_test/2, + inline_sequence_test/2, term_sequence_test/2, + term_struct_test/2 + +]). + +-include("m.hrl"). +-include("m_i.hrl"). +-include("oe_erl_c_test.hrl"). + +%%b +void_test(Node, Timeout) -> + Ret = m_i:void_test({olsson, Node}, Timeout), + Ret == void. % XXX Not documented +%%e + +%%b +long_test(Node, Timeout) -> + In = max_long(), + {Ret, Out} = m_i:long_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +longlong_test(Node, Timeout) -> + In = 65537, + {Ret, Out} = m_i:longlong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ushort_test(Node, Timeout) -> + In = max_ushort(), + {Ret, Out} = m_i:ushort_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ulong_test(Node, Timeout) -> + In = max_ulong(), + {Ret, Out} = m_i:ulong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ulonglong_test(Node, Timeout) -> + In = 65537, + {Ret, Out} = m_i:ulonglong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +double_test(Node, Timeout) -> + In = 37768.93, + {Ret, Out} = m_i:double_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +char_test(Node, Timeout) -> + In = 80, + {Ret, Out} = m_i:char_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +wchar_test(Node, Timeout) -> + In = 4097, + {Ret, Out} = m_i:wchar_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +octet_test(Node, Timeout) -> + In = 255, + {Ret, Out} = m_i:octet_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +bool_test(Node, Timeout) -> + In = false, + {Ret, Out} = m_i:bool_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +struct_test(Node, Timeout) -> + In = #m_b{l = max_long(), c = $a}, + {Ret, Out} = m_i:struct_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +struct2_test(Node, Timeout) -> + In = #m_es{ f = banana, l = max_long()}, + {Ret, Out} = m_i:struct2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq1_test(Node, Timeout) -> + B1 = #m_b{l = max_long(), c = $a}, + B2 = #m_b{l = min_long(), c = $b}, + In = [B1, B2], + {Ret, Out} = m_i:seq1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq2_test(Node, Timeout) -> + B = #m_b{l = max_long(), c = $a}, + A = #m_a{l = min_long(), y = [B, B], d = 4711.31}, + In = [A, A, A], + {Ret, Out} = m_i:seq2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq3_test(Node, Timeout) -> + In = [max_long(), min_long(), max_long()], + {Ret, Out} = m_i:seq3_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq4_test(Node, Timeout) -> + In = [["hello", "all"], ["Erlang", "users", "!"]], + {Ret, Out} = m_i:seq4_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq5_test(Node, Timeout) -> + Arr3 = mk_array(3, max_long()), + In = [[Arr3, Arr3], [Arr3, Arr3, Arr3]], + {Ret, Out} = m_i:seq5_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +array1_test(Node, Timeout) -> + In = mk_array(500, min_long()), + {Ret, Out} = m_i:array1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +array2_test(Node, Timeout) -> + In = mk_array(2, mk_array(3, min_long())), + {Ret, Out} = m_i:array2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +enum_test(Node, Timeout) -> + In = banana, + {Ret, Out} = m_i:enum_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string1_test(Node, Timeout) -> + In = "Developing Erlang applications is fun!", + {Ret, Out} = m_i:string1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +wstring1_test(Node, Timeout) -> + In = [1047| "eveloping Erlang applications is fun!"], + {Ret, Out} = m_i:wstring1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string2_test(Node, Timeout) -> + In = ["Developing Erlang applications ", "is fun!"], + {Ret, Out} = m_i:string2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string3_test(Node, Timeout) -> + In = "Developing Erlang applications is fun!", + {Ret, Out} = m_i:string3_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string4_test(Node, Timeout) -> + + In = #m_strRec{ + bb = true, + str4 = "Developing Erlang applications " + "is fun!", + str7 = mk_array(3, mk_array(2, max_long())), + str5 = [$a, $b, $c, $d, $e, $f], + str6 = "123456789012", + str8 = {$x, $y, $x}, + str9 = "123456789012", + str10 = [$a, $b, $c, $d, $e, $f] + }, + {Ret, Out} = m_i:string4_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +pid_test(Node, Timeout) -> + In = self(), + {Ret, Out} = m_i:pid_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +port_test(Node, Timeout) -> + In = get(port_test_port), + {Ret, Out} = m_i:port_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ref_test(Node, Timeout) -> + In = make_ref(), + {Ret, Out} = m_i:ref_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_test(Node, Timeout) -> + In = {[a, b], 17, kalle}, + {Ret, Out} = m_i:term_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +typedef_test(Node, Timeout) -> + In1 = {nisse, [1, 2], olsson}, + In2 = get(port_test_port), + {Ret, Out1, Out2} = m_i:typedef_test({olsson, Node}, Timeout, In1, In2), + %% XXX Should check that Ret is an integer. + (Out1 == In1) and (Out2 == In2). +%%e + +%%b +inline_sequence_test(Node, Timeout) -> + In = #m_s{l = min_long(), sl = [max_long(), min_long()]}, + {Ret, Out} = m_i:inline_sequence_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_sequence_test(Node, Timeout) -> + In = lists:duplicate(17, {nisse, [1, 2], {kalle, olsson}}), + {Ret, Out} = m_i:term_sequence_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_struct_test(Node, Timeout) -> + In = #m_et{e = {nisse, ["abcde"], {kalle, olsson}}, l = 4711}, + {Ret, Out} = m_i:term_struct_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + + +%% Locals + +mk_array(Es) -> + list_to_tuple(Es). + +mk_array(N, E) -> + mk_array(lists:duplicate(N, E)). + +%% max_short() -> +%% power_of_two(15) - 1. +max_long() -> + power_of_two(31) - 1. +max_longlong() -> + power_of_two(63) - 1. +max_ushort() -> + power_of_two(16) - 1. +max_ulong() -> + power_of_two(32) - 1. +max_ulonglong() -> + power_of_two(64) - 1. + +%% min_short() -> +%% -power_of_two(15). +min_long() -> + -power_of_two(31). +%% min_longlong() -> +%% -power_of_two(63). +%% min_ushort() -> +%% 0. +%% min_ulong() -> +%% 0. +%% min_ulonglong() -> +%% 0. + +power_of_two(N) -> + round(math:pow(2, N)). + diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE.erl b/lib/ic/test/erl_client_c_server_proto_SUITE.erl new file mode 100644 index 0000000000..d75feb621a --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE.erl @@ -0,0 +1,350 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +%%---------------------------------------------------------------------- +%% Purpose : Test suite for erl-client/c-server +%%---------------------------------------------------------------------- + + +-module(erl_client_c_server_proto_SUITE). +-include("test_server.hrl"). + +-export([init_per_testcase/2, fin_per_testcase/2, all/1, void_test/1, + long_test/1, longlong_test/1, ushort_test/1, ulong_test/1, + ulonglong_test/1, double_test/1, char_test/1, wchar_test/1, + octet_test/1, bool_test/1, struct_test/1, struct2_test/1, + seq1_test/1, seq2_test/1, seq3_test/1, seq4_test/1, + seq5_test/1, array1_test/1, array2_test/1, enum_test/1, + string1_test/1, string2_test/1, string3_test/1, + string4_test/1, pid_test/1, port_test/1, ref_test/1, + term_test/1, typedef_test/1, inline_sequence_test/1, + term_sequence_test/1, term_struct_test/1, wstring1_test/1]). + +-define(DEFAULT_TIMEOUT, 20000). +-define(PORT_TIMEOUT, 15000). +-define(CALL_TIMEOUT, 5000). + +-define(C_SERVER_NODE_NAME, idl_c_server_test). + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i, we have + %% to make sure we are using the right m_i module. + code:purge(m_i), + code:load_file(m_i), + + WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + +all(doc) -> + "Test of IC with an Erlang client and a C server. " + "The communication is via Erlang distribution."; +all(suite) -> + [void_test, long_test, longlong_test, ushort_test, + ulong_test, ulonglong_test, double_test, + char_test, wchar_test, octet_test, bool_test, struct_test, + struct2_test, seq1_test, seq2_test, seq3_test, seq4_test, + seq5_test, array1_test, array2_test, enum_test, string1_test, + string2_test, string3_test, string4_test, pid_test, port_test, + ref_test, term_test, typedef_test, inline_sequence_test, + term_sequence_test, term_struct_test, wstring1_test]. + + +array1_test(doc) -> ""; +array1_test(suite) -> []; +array1_test(Config) -> + do_test(array1_test, Config). + +array2_test(doc) -> ""; +array2_test(suite) -> []; +array2_test(Config) -> + do_test(array2_test, Config). + +bool_test(doc) -> ""; +bool_test(suite) -> []; +bool_test(Config) -> + do_test(bool_test, Config). + +char_test(doc) -> ""; +char_test(suite) -> []; +char_test(Config) -> + do_test(char_test, Config). + +double_test(doc) -> ""; +double_test(suite) -> []; +double_test(Config) -> + do_test(double_test, Config). + +enum_test(doc) -> ""; +enum_test(suite) -> []; +enum_test(Config) -> + do_test(enum_test, Config). + +inline_sequence_test(doc) -> ""; +inline_sequence_test(suite) -> []; +inline_sequence_test(Config) -> + do_test(inline_sequence_test, Config). + +longlong_test(doc) -> ""; +longlong_test(suite) -> []; +longlong_test(Config) -> + do_test(longlong_test, Config). + +long_test(doc) -> ""; +long_test(suite) -> []; +long_test(Config) -> + do_test(long_test, Config). + +octet_test(doc) -> ""; +octet_test(suite) -> []; +octet_test(Config) -> + do_test(octet_test, Config). + +pid_test(doc) -> ""; +pid_test(suite) -> []; +pid_test(Config) -> + do_test(pid_test, Config). + +port_test(doc) -> ""; +port_test(suite) -> []; +port_test(Config) -> + do_test(port_test, Config). + +ref_test(doc) -> ""; +ref_test(suite) -> []; +ref_test(Config) -> + do_test(ref_test, Config). + +seq1_test(doc) -> ""; +seq1_test(suite) -> []; +seq1_test(Config) -> + do_test(seq1_test, Config). + +seq2_test(doc) -> ""; +seq2_test(suite) -> []; +seq2_test(Config) -> + do_test(seq2_test, Config). + +seq3_test(doc) -> ""; +seq3_test(suite) -> []; +seq3_test(Config) -> + do_test(seq3_test, Config). + +seq4_test(doc) -> ""; +seq4_test(suite) -> []; +seq4_test(Config) -> + do_test(seq4_test, Config). + +seq5_test(doc) -> ""; +seq5_test(suite) -> []; +seq5_test(Config) -> + do_test(seq5_test, Config). + +string1_test(doc) -> ""; +string1_test(suite) -> []; +string1_test(Config) -> + do_test(string1_test, Config). + +string2_test(doc) -> ""; +string2_test(suite) -> []; +string2_test(Config) -> + do_test(string2_test, Config). + +string3_test(doc) -> ""; +string3_test(suite) -> []; +string3_test(Config) -> + do_test(string3_test, Config). + +string4_test(doc) -> ""; +string4_test(suite) -> []; +string4_test(Config) -> + do_test(string4_test, Config). + +struct2_test(doc) -> ""; +struct2_test(suite) -> []; +struct2_test(Config) -> + do_test(struct2_test, Config). + +struct_test(doc) -> ""; +struct_test(suite) -> []; +struct_test(Config) -> + do_test(struct_test, Config). + +term_sequence_test(doc) -> ""; +term_sequence_test(suite) -> []; +term_sequence_test(Config) -> + do_test(term_sequence_test, Config). + +term_struct_test(doc) -> ""; +term_struct_test(suite) -> []; +term_struct_test(Config) -> + do_test(term_struct_test, Config). + +term_test(doc) -> ""; +term_test(suite) -> []; +term_test(Config) -> + do_test(term_test, Config). + +typedef_test(doc) -> ""; +typedef_test(suite) -> []; +typedef_test(Config) -> + do_test(typedef_test, Config). + +ulonglong_test(doc) -> ""; +ulonglong_test(suite) -> []; +ulonglong_test(Config) -> + do_test(ulonglong_test, Config). + +ulong_test(doc) -> ""; +ulong_test(suite) -> []; +ulong_test(Config) -> + do_test(ulong_test, Config). + +ushort_test(doc) -> ""; +ushort_test(suite) -> []; +ushort_test(Config) -> + do_test(ushort_test, Config). + +void_test(doc) -> ""; +void_test(suite) -> []; +void_test(Config) -> + do_test(void_test, Config). + +wchar_test(doc) -> ""; +wchar_test(suite) -> []; +wchar_test(Config) -> + do_test(wchar_test, Config). + +wstring1_test(doc) -> ""; +wstring1_test(suite) -> []; +wstring1_test(Config) -> + do_test(wstring1_test, Config). + + +do_test(Case, Config) -> + %% Trap exits + process_flag(trap_exit, true), + Node = atom_to_list(node()), + [_NodeName, HostName] = string:tokens(Node, "@"), + DataDir = ?config(data_dir, Config), + %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]), + Cookie = atom_to_list(erlang:get_cookie()), + ServerNodeName = atom_to_list(?C_SERVER_NODE_NAME), + %% Start C-server node as a port program. We wait for the node + %% to connect to us. + Cmd = filename:join([DataDir, "c_server"]) ++ + " -this-node-name " ++ ServerNodeName ++ + " -peer-node " ++ Node ++ + " -cookie " ++ Cookie, + Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]), + ServerNode = list_to_atom(ServerNodeName ++ "@" ++ HostName), + Res = case wait_for_hidden_node(ServerNode) of + ok -> + %% Need a port for port_test and typedef_test + put(port_test_port, Port), + R = (catch erl_client:Case(ServerNode, ?CALL_TIMEOUT)), + case wait_for_completion(Port) of + {error, timeout} -> + kill_off_node(ServerNode); + _ -> + ok + end, + R; + {error, timeout} -> + case wait_for_completion(Port) of + {error, timeout} -> + kill_off_node(ServerNode); + _ -> + ok + end, + {error, timeout} + end, + process_flag(trap_exit, false), + true = Res. + + +%% Wait for eof *and* exit status, but return if exit status indicates +%% an error, or we have been waiting more than PORT_TIMEOUT seconds. +%% +wait_for_completion(Port) -> + wait_for_completion(Port, 0). + +wait_for_completion(Port, N) when N < 2 -> + receive + {Port, {data, Bytes}} -> + %% Relay output + io:format("~s", [Bytes]), + wait_for_completion(Port, N); + {Port, {exit_status, 0}} -> + wait_for_completion(Port, N + 1); + {Port, {exit_status, Status}} -> + {error, Status}; + {Port, eof} -> + wait_for_completion(Port, N + 1); + {'EXIT', Port, Reason} -> + io:format("Port exited with reason: ~w~n", [Reason]), + wait_for_completion(Port, N); + {'EXIT', From, Reason} -> + io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]), + wait_for_completion(Port, N) + after ?PORT_TIMEOUT -> + {error, timeout} + end; +wait_for_completion(_, _) -> + ok. + +wait_for_hidden_node(Node) -> + Times = ?DEFAULT_TIMEOUT div 100, + wait_for_hidden_node(Node, Times, 100). + +wait_for_hidden_node(Node, Times, WaitTime) when Times > 0 -> + io:format("Waiting for hidden node: ~p~n", [Node]), + case lists:member(Node, erlang:nodes(hidden)) of + true -> + ok; + false -> + delay(WaitTime), + wait_for_hidden_node(Node, Times - 1, WaitTime) + end; +wait_for_hidden_node(_Node, _, _WaitTime) -> + {error, timeout}. + +kill_off_node(Node) -> + catch rpc:cast(Node, erlang, halt, [1]). + +delay(Time) -> + receive + after Time -> + ok + end. + + + + diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src b/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src new file mode 100644 index 0000000000..b7e7ee77d0 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src @@ -0,0 +1,150 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +# Makefile.src for erl_client_c_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@ + + +# Variables from ts: +# + +ERL_INCLUDE = @erl_include@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_LIB = @ic_libpath@@DS@@ic_lib@ + +ERL_INTERFACE_INCLUDE = @erl_interface_include@ +ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@ +ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@ +ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@ +ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@ + +CC = @CC@ +## XXX Should set warning flag with a DEBUG_FLAG +CFLAGS = @CFLAGS@ @DEFS@ -I$(ERL_INCLUDE) \ + -I$(IC_INCLUDE_PATH) -I$(ERL_INTERFACE_INCLUDE) + +LD = @LD@ +LDFLAGS = @CROSSLDFLAGS@ +LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \ + $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS) +ERLC = erlc + +# Generated C header files +GEN_H_FILES = \ + m__s.h \ + m_i__s.h \ + oe_erl_c_test__s.h + +# Generated C files +GEN_C_FILES = \ + m__s.c \ + m_i__s.c \ + oe_code_m_a.c \ + oe_code_m_arr1.c \ + oe_code_m_arr2.c \ + oe_code_m_arr3.c \ + oe_code_m_aseq.c \ + oe_code_m_b.c \ + oe_code_m_bseq.c \ + oe_code_m_dd.c \ + oe_code_m_dyn.c \ + oe_code_m_dyn_sl.c \ + oe_code_m_es.c \ + oe_code_m_et.c \ + oe_code_m_etseq.c \ + oe_code_m_fruit.c \ + oe_code_m_lseq.c \ + oe_code_m_s.c \ + oe_code_m_s_sl.c \ + oe_code_m_sarr3.c \ + oe_code_m_simple.c \ + oe_code_m_ssarr3.c \ + oe_code_m_sseq.c \ + oe_code_m_ssstr3.c \ + oe_code_m_sstr3.c \ + oe_code_m_str1.c \ + oe_code_m_str3.c \ + oe_code_m_strRec.c \ + oe_code_m_strRec_str5.c \ + oe_code_m_strRec_str7.c \ + oe_erl_c_test__s.c + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_erl_c_test.hrl + +GEN_ERL_FILES = \ + m.erl \ + m_arr2.erl \ + m_arr3.erl \ + m_i.erl \ + m_str3.erl \ + oe_erl_c_test.erl + +C_FILES = $(GEN_C_FILES) c_server.c callbacks.c + +OBJS = $(C_FILES:.c=@obj@) + +PGMS = c_server@exe@ + +ERL_FILES = $(GEN_ERL_FILES) erl_client.erl + +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(PGMS) $(EBINS) + +clean: + -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + +$(PGMS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(GEN_C_FILES) $(GEN_H_FILES): erl_c_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_server}" \ + "+{scoped_op_calls,true}" erl_c_test.idl + +# If we have scoped operation calls for C, we must have that for +# Erlang as well, if we use the m_i.erl file for calling the server. + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): erl_c_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" \ + "+{scoped_op_calls,true}" "+{timeout,true}" erl_c_test.idl + +.c@obj@: + $(CC) -c -o $*@obj@ $(CFLAGS) $< + +.erl.@EMULATOR@: + $(ERLC) -W -I $(IC_INCLUDE_PATH) $< + diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c new file mode 100644 index 0000000000..329f444112 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c @@ -0,0 +1,299 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ +/* C-server for test of IC. + * + * The C-node implemented here connects to its peer node, waits for + * one message, evaluates the message, returns an result message, and + * terminates. + * + * TODO: + * + * 1. XXX #includes for VxWorks, Windows + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __WIN32__ +# include <unistd.h> +#endif + +#include <string.h> + +#ifdef __WIN32__ +# include <time.h> +# include <sys/timeb.h> +#elif defined VXWORKS +# include <time.h> +# include <sys/times.h> +#else +# include <sys/time.h> +#endif + +#include <ctype.h> + +#ifdef __WIN32__ +# include <winsock2.h> +# include <windows.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "ic.h" +#include "ei.h" +#include "erl_interface.h" +#include "eicode.h" +#include "m_i__s.h" +#include "m__s.h" + +#ifdef __WIN32__ +typedef struct { + long tv_sec; + long tv_usec; +} MyTimeval; +#else +typedef struct timeval MyTimeval; +#endif +static void my_gettimeofday(MyTimeval *tv); +static void showtime(MyTimeval *start, MyTimeval *stop); +static void usage(void); +static void done(int r); + +#define HOSTNAMESZ 256 +#define NODENAMESZ 512 +#define INBUFSZ 10 +#define OUTBUFSZ 0 +#define MAXTRIES 5 + +static char *progname; + +/* main */ +#ifdef VXWORKS +int c_server(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + struct hostent *hp; + MyTimeval start, stop; + int i, fd, ires, tries; + CORBA_Environment *env; + char *this_node_name = NULL; + char *peer_node = NULL; + char *cookie = NULL; + char host[HOSTNAMESZ + 1]; + char this_node[NODENAMESZ + 1]; + erlang_msg msg; + int status, loop; + +#ifdef __WIN32__ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); + exit(1); + } +#endif + + progname = argv[0]; + host[HOSTNAMESZ] = '\0'; + if (gethostname(host, HOSTNAMESZ) < 0) { + fprintf(stderr, "Can't find own hostname\n"); + done(1); + } + if ((hp = gethostbyname(host)) == 0) { + fprintf(stderr, "Can't get ip address for host %s\n", host); + done(1); + } + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-help") == 0) { + usage(); + done(0); + } else if (strcmp(argv[i], "-this-node-name") == 0) { + i++; + this_node_name = argv[i]; + } else if (strcmp(argv[i], "-peer-node") == 0) { + i++; + peer_node = argv[i]; + } else if (strcmp(argv[i], "-cookie") == 0) { + i++; + cookie = argv[i]; + } else { + fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); + usage(); + done(1); + } + } + + if (this_node_name == NULL || peer_node == NULL || cookie == NULL) { + fprintf(stderr, "Error: missing option\n"); + usage(); + done(1); + } + + /* Behead hostname at first dot */ + for (i=0; host[i] != '\0'; i++) { + if (host[i] == '.') { host[i] = '\0'; break; } + } + sprintf(this_node, "%s@%s", this_node_name, host); + + fprintf(stderr, "c_server: this node: \"%s\"\n", this_node); + fprintf(stderr, "c_server: peer node: \"%s\"\n", peer_node); + + /* initialize erl_interface */ + erl_init(NULL, 0); + + for (tries = 0; tries < MAXTRIES; tries++) { + /* connect to peer node */ + ires = erl_connect_xinit(host, this_node_name, this_node, + (struct in_addr *)*hp->h_addr_list, + cookie, 0); + fprintf(stderr, "c_server: erl_connect_xinit(): %d\n", ires); + + fd = erl_connect(peer_node); + fprintf(stderr, "c_server: erl_connect(): %d\n", fd); + if (fd >= 0) + break; + fprintf(stderr, "c_server: cannot connect, retrying\n"); + } + if (fd < 0) { + fprintf(stderr, "c_server: cannot connect, exiting\n"); + done(1); + } + env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); + env->_fd = fd; + + status = 1; + loop = 1; + my_gettimeofday(&start); + while (status >= 0 && loop > 0) { + status = ei_receive_encoded(env->_fd, &env->_inbuf, &env->_inbufsz, + &msg, &env->_iin); + switch(status) { + case ERL_SEND: + case ERL_REG_SEND: + /* get result */ + m_i__switch(NULL, env); + switch(env->_major) { + case CORBA_NO_EXCEPTION: + break; + case CORBA_SYSTEM_EXCEPTION: + fprintf(stderr, "Request failure, reason : %s\n", + (char *) CORBA_exception_value(env)); + CORBA_exception_free(env); + break; + default: /* Should not happen */ + CORBA_exception_free(env); + break; + } + /* send back result data */ + if (env->_iout > 0) + ei_send_encoded(env->_fd, &env->_caller, env->_outbuf, + env->_iout); + loop = 0; + break; + case ERL_TICK: + break; + default: + if (status < 0) { + fprintf(stderr, "Status negative: %d\n", status); + loop = 0; + } + break; + } + } + my_gettimeofday(&stop); + showtime(&start, &stop); + + erl_close_connection(fd); + + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + if (status < 0) + done(-status); + else + done(0); +} + +static void usage() +{ + fprintf(stderr, "Usage: %s [-help] -this-node-name <name> " + "-peer-node <nodename> -cookie <cookie>\n", progname); + fprintf(stderr, "Example:\n %s -this-node-name kalle " + "-peer-node olle@home -cookie oa678er\n", progname); +} + +static void done(int r) +{ +#ifdef __WIN32__ + WSACleanup(); +#endif + exit(r); +} + +static void showtime(MyTimeval *start, MyTimeval *stop) +{ + MyTimeval elapsed; + + elapsed.tv_sec = stop->tv_sec - start->tv_sec; + elapsed.tv_usec = stop->tv_usec - start->tv_usec; + while (elapsed.tv_usec < 0) { + elapsed.tv_sec -= 1; + elapsed.tv_usec += 1000000; + } + fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); +} + + + +static void my_gettimeofday(MyTimeval *tv) +#ifdef __WIN32__ +#define EPOCH_JULIAN_DIFF 11644473600i64 +{ + SYSTEMTIME t; + FILETIME ft; + LONGLONG lft; + + GetSystemTime(&t); + SystemTimeToFileTime(&t, &ft); + memcpy(&lft, &ft, sizeof(lft)); + tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); + tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); +} +#elif defined VXWORKS +{ + int rate = sysClkRateGet(); /* Ticks per second */ + unsigned long ctick = tickGet(); + tv->tv_sec = ctick / rate; /* secs since reboot */ + tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; +} +#else +{ + gettimeofday(tv, NULL); +} +#endif diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c new file mode 100644 index 0000000000..b029bcc63c --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c @@ -0,0 +1,610 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ +#include <stdio.h> +#include <stdlib.h> +#ifndef __WIN32__ +# include <unistd.h> +#endif +#include <string.h> +#include <ctype.h> +#include <ic.h> +#include <erl_interface.h> +#include <ei.h> +#include "m_i__s.h" + + + +/* OK */ + +void my_void_test(CORBA_Object oe_obj, + CORBA_Environment *oe_env) +{ + /* printf("void test !\n"); */ +} + +m_i_void_test__rs* m_i_void_test__cb(CORBA_Object oe_obj, + CORBA_Environment *oe_env) +{ + return (m_i_void_test__rs*) (my_void_test); +} + + + +/* OK */ + +void my_long_test(CORBA_Object oe_obj, + long* a, + long* b, + long* c, + CORBA_Environment *oe_env) +{ + /* printf("long test !\n"); */ +} + + +m_i_long_test__rs* m_i_long_test__cb(CORBA_Object oe_obj, + long* a, + long* b, + long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_long_test__rs*) (my_long_test); +} + +/* OK */ + +void my_longlong_test(CORBA_Object oe_obj, + CORBA_long_long* a, + CORBA_long_long* b, + CORBA_long_long* c, + CORBA_Environment *oe_env) +{ + /* printf("long test !\n"); */ +} + +m_i_longlong_test__rs* m_i_longlong_test__cb(CORBA_Object oe_obj, + CORBA_long_long* a, + CORBA_long_long* b, + CORBA_long_long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_longlong_test__rs*) (my_longlong_test); +} + +/* OK */ +void my_ulong_test(CORBA_Object oe_obj, + unsigned long* a, + unsigned long* b, + unsigned long* c, + CORBA_Environment *oe_env) +{ + /* printf("ulong test !\n"); */ +} + +m_i_ulong_test__rs* m_i_ulong_test__cb(CORBA_Object oe_obj, + unsigned long* a, + unsigned long* b, + unsigned long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ulong_test__rs*) (my_ulong_test); +} + +/* OK */ +void my_ulonglong_test(CORBA_Object oe_obj, + CORBA_unsigned_long_long* a, + CORBA_unsigned_long_long* b, + CORBA_unsigned_long_long* c, + CORBA_Environment *oe_env) +{ + /* printf("ulong test !\n"); */ +} + +m_i_ulonglong_test__rs* m_i_ulonglong_test__cb(CORBA_Object oe_obj, + CORBA_unsigned_long_long* a, + CORBA_unsigned_long_long* b, + CORBA_unsigned_long_long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ulonglong_test__rs*) (my_ulonglong_test); +} + +m_i_ushort_test__rs* m_i_ushort_test__cb(CORBA_Object oe_obj, + unsigned short* a, + unsigned short* b, + unsigned short* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ushort_test__rs*) NULL; +} + + +/* OK */ +void my_double_test(CORBA_Object oe_obj, + double* a, + double* b, + double* c, + CORBA_Environment *oe_env) +{ + /* printf("double test !\n"); */ +} + +m_i_double_test__rs* m_i_double_test__cb(CORBA_Object oe_obj, + double* a, + double* b, + double* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_double_test__rs*) (my_double_test); +} + +/* OK */ +m_i_char_test__rs* m_i_char_test__cb(CORBA_Object oe_obj, + char* a, + char* b, + char* c, + CORBA_Environment *oe_env) +{ + m_i_char_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + + +/* OK */ +m_i_wchar_test__rs* m_i_wchar_test__cb(CORBA_Object oe_obj, + CORBA_wchar* a, + CORBA_wchar* b, + CORBA_wchar* c, + CORBA_Environment *oe_env) +{ + m_i_wchar_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_octet_test__rs* m_i_octet_test__cb(CORBA_Object oe_obj, + char* a, + char* b, + char* c, + CORBA_Environment *oe_env) +{ + m_i_octet_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_bool_test__rs* m_i_bool_test__cb(CORBA_Object oe_obj, + CORBA_boolean* a, + CORBA_boolean* b, + CORBA_boolean* c, + CORBA_Environment *oe_env) +{ + m_i_bool_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +void my_struct_test(CORBA_Object oe_obj, + m_b* a, + m_b* b, + m_b* c, + CORBA_Environment *oe_env) +{ + /* printf("struct test !\n"); */ +} + +m_i_struct_test__rs* m_i_struct_test__cb(CORBA_Object oe_obj, + m_b* a, + m_b* b, + m_b* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_struct_test__rs*) (my_struct_test); +} + +/* OK */ +m_i_struct2_test__rs* m_i_struct2_test__cb(CORBA_Object oe_obj, + m_es* a, + m_es* b, + m_es* c, + CORBA_Environment *oe_env) +{ + m_i_struct2_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +/* XXX Commented out +m_i_struct3_test__rs* m_i_struct3_test__cb(CORBA_Object oe_obj, + m_simple* a, + m_simple* b, + m_simple* c, + CORBA_Environment *oe_env) +{ + m_i_struct3_test__rs* rs = NULL; + *a = *b; + *c = *b; + return rs; +} +*/ + +/* OK */ +m_i_seq1_test__rs* m_i_seq1_test__cb(CORBA_Object oe_obj, + m_bseq** a, + m_bseq* b, + m_bseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq1_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_seq2_test__rs* m_i_seq2_test__cb(CORBA_Object oe_obj, + m_aseq** a, + m_aseq* b, + m_aseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq2_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq3_test__rs* m_i_seq3_test__cb(CORBA_Object oe_obj, + m_lseq** a, + m_lseq* b, + m_lseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq3_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq4_test__rs* m_i_seq4_test__cb(CORBA_Object oe_obj, + m_ssstr3** a, + m_ssstr3* b, + m_ssstr3** c, + CORBA_Environment *oe_env) +{ + m_i_seq4_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq5_test__rs* m_i_seq5_test__cb(CORBA_Object oe_obj, + m_ssarr3** a, + m_ssarr3* b, + m_ssarr3** c, + CORBA_Environment *oe_env) +{ + m_i_seq5_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_array1_test__rs* m_i_array1_test__cb(CORBA_Object oe_obj, + m_arr1 a, + m_arr1 b, + m_arr1 c, + CORBA_Environment *oe_env) +{ + int i; + m_i_array1_test__rs* rs = NULL; + + for (i = 0; i < 500; i++) { + a[i] = b[i]; + c[i] = b[i]; + } + return rs; +} + +/* OK */ +m_i_array2_test__rs* m_i_array2_test__cb(CORBA_Object oe_obj, + m_dd a, + m_dd b, + m_dd c, + CORBA_Environment *oe_env) +{ + int i,j; + m_i_array2_test__rs* rs = NULL; + + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) { + a[i][j] = b[i][j]; + c[i][j] = b[i][j]; + } + return rs; +} + + +/* OK */ +m_i_enum_test__rs* m_i_enum_test__cb(CORBA_Object oe_obj, + m_fruit* a, + m_fruit* b, + m_fruit* c, + CORBA_Environment *oe_env) +{ + m_i_enum_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_string1_test__rs* m_i_string1_test__cb(CORBA_Object oe_obj, + char ** a, + char * b, + char ** c, + CORBA_Environment *oe_env) +{ + m_i_string1_test__rs* rs = NULL; + + /*printf("\nString in ------> %s\n\n",b);*/ + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_string2_test__rs* m_i_string2_test__cb(CORBA_Object oe_obj, + m_sseq** a, + m_sseq* b, + m_sseq** c, + CORBA_Environment *oe_env) +{ + m_i_string2_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_string3_test__rs* m_i_string3_test__cb(CORBA_Object oe_obj, + char ** a, + char * b, + char ** c, + CORBA_Environment *oe_env) +{ + m_i_string3_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +m_i_string4_test__rs* m_i_string4_test__cb(CORBA_Object oe_obj, + m_strRec** a, + m_strRec* b, + m_strRec** c, + CORBA_Environment *oe_env) +{ + *a = b; + *c = b; + + return (m_i_string4_test__rs*) NULL; +} + +/* OK */ +m_i_wstring1_test__rs* m_i_wstring1_test__cb(CORBA_Object oe_obj, + CORBA_wchar ** a, + CORBA_wchar * b, + CORBA_wchar ** c, + CORBA_Environment *oe_env) +{ + int tmp; + m_i_wstring1_test__rs* rs = NULL; + + /*printf("\nString in ------> %s\n\n",b);*/ + + for(tmp = 0; tmp < 5; tmp++) + fprintf(stderr,"\np[%d] = %ld\n", tmp, b[tmp]); + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_pid_test__rs* m_i_pid_test__cb(CORBA_Object oe_obj, + erlang_pid* a, + erlang_pid* b, + erlang_pid* c, + CORBA_Environment *oe_env) +{ + m_i_pid_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_port_test__rs* m_i_port_test__cb(CORBA_Object oe_obj, + erlang_port* a, + erlang_port* b, + erlang_port* c, + CORBA_Environment *oe_env) +{ + m_i_port_test__rs* rs = NULL; + + strcpy((*a).node,(*b).node); + (*a).id = (*b).id; + (*a).creation = 0; + + strcpy((*c).node,(*b).node); + (*c).id = (*b).id; + (*c).creation = 0; + return rs; +} + +/* OK */ +m_i_ref_test__rs* m_i_ref_test__cb(CORBA_Object oe_obj, + erlang_ref* a, + erlang_ref* b, + erlang_ref* c, + CORBA_Environment *oe_env) +{ + + m_i_ref_test__rs* rs = NULL; + + strcpy((*a).node,(*b).node); + /*(*a).id = (*b).id;*/ + (*a).len = (*b).len; + (*a).n[0] = (*b).n[0]; + (*a).n[1] = (*b).n[1]; + (*a).n[2] = (*b).n[2]; + (*a).creation = 0; + + strcpy((*c).node,(*b).node); + /*(*c).id = (*b).id;*/ + (*c).len = (*b).len; + (*c).n[0] = (*b).n[0]; + (*c).n[1] = (*b).n[1]; + (*c).n[2] = (*b).n[2]; + (*c).creation = 0; + return rs; +} + +/* OK */ +m_i_term_test__rs* m_i_term_test__cb(CORBA_Object oe_obj, + ETERM** a, + ETERM** b, + ETERM** c, + CORBA_Environment *oe_env) +{ + m_i_term_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +m_i_typedef_test__rs* m_i_typedef_test__cb(CORBA_Object oe_obj, + long* a, + ETERM** b, + erlang_port* c, + ETERM** d , + erlang_port* e, + CORBA_Environment *oe_env) +{ + m_i_typedef_test__rs* rs = NULL; + + *d = *b; + strcpy((*e).node,(*c).node); + (*e).id = (*c).id; + (*e).creation = 0; + *a = 4711; + return rs; +} + +/* OK */ +m_i_inline_sequence_test__rs* m_i_inline_sequence_test__cb( + CORBA_Object oe_obj, + m_s** a, + m_s* b, + m_s** c, + CORBA_Environment *oe_env) +{ + m_i_inline_sequence_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_term_sequence_test__rs* m_i_term_sequence_test__cb( + CORBA_Object oe_obj, + m_etseq** a, + m_etseq* b, + m_etseq** c, + CORBA_Environment *oe_env) +{ + m_i_term_sequence_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_term_struct_test__rs* m_i_term_struct_test__cb(CORBA_Object oe_obj, + m_et* a, + m_et* b, + m_et* c, + CORBA_Environment *oe_env) +{ + m_i_term_struct_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl new file mode 100644 index 0000000000..e90d0dd5f0 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl @@ -0,0 +1,174 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2004-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +#include "erlang.idl" + + +const short TestConst = 1; + +module m { + + const short TestConst = 2; + + struct b { + long l; + char c; + }; + + struct simple { + long l; + b b_t; + }; + + enum fruit {orange, banana, apple, peach, pear}; + + typedef sequence<long> lseq; + + typedef sequence<b> bseq; + + struct a { + long l; + bseq y; + double d; + }; + + typedef sequence<a> aseq; + + typedef sequence<string> sseq; + typedef string str; + typedef long myLong; + + typedef long arr1[500], dd[2][3]; + + typedef erlang::term apa; + typedef erlang::port banan; + + typedef sequence<erlang::term> etseq; + + struct s { + long l; + sequence<long> sl; + }; + + struct es { + fruit f; + myLong l; + }; + + struct et { + erlang::term e; + long l; + }; + + + typedef sequence<char> str1; + typedef string<12> str2; + typedef char str3[3]; + + typedef sequence<string> sstr3; // sequence of string + typedef sequence<sstr3> ssstr3; // sequence of sequences of strings + + typedef long arr3[3]; // array of long + typedef sequence<arr3> sarr3; // sequence of array + typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings + + struct strRec{ + boolean bb; + string str4; + long str7[3][2]; + sequence<char> str5; + string<12> str6; + str3 str8; + str2 str9; + str1 str10; + }; + + + struct dyn { + long l; + sequence<long> sl; + }; + typedef dyn arr2[1][2]; + + + interface i { + + const short TestConst = 3; + + //arr2 suck(in arr2 x, out arr2 y ); + + ///////////////////////////////// attribute long l; + + // simple types + void void_test(); + long long_test(in long a, out long a1); + long long longlong_test(in long long a, out long long a1); + unsigned short ushort_test(in unsigned short a, out unsigned short a1); + unsigned long ulong_test(in unsigned long a, out unsigned long a1); + unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1); + double double_test(in double a, out double a1); + char char_test(in char a, out char a1); + wchar wchar_test(in wchar a, out wchar a1); + octet octet_test(in octet a, out octet a1); + boolean bool_test(in boolean a, out boolean a1); + + // Seq. and struct tests + b struct_test(in b a, out b a1); + es struct2_test(in es a, out es a1); + //simple struct3_test(in simple x, out simple y); + bseq seq1_test(in bseq a, out bseq a1); + aseq seq2_test(in aseq a, out aseq a1); + lseq seq3_test(in lseq a, out lseq a1); + ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1); + ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1); + + // Array tests + arr1 array1_test(in arr1 a, out arr1 a1); + dd array2_test(in dd a, out dd a1); + + // enum test + fruit enum_test(in fruit a, out fruit a1); + + // string tests + string string1_test(in string a, out string a1); + wstring wstring1_test(in wstring a, out wstring a1); + sseq string2_test(in sseq a, out sseq a1); + str string3_test(in str a, out str a1); + strRec string4_test(in strRec a, out strRec a1); + + // Special erlang types + erlang::pid pid_test(in erlang::pid a, out erlang::pid a1); + erlang::port port_test(in erlang::port a, out erlang::port a1); + erlang::ref ref_test(in erlang::ref a, out erlang::ref a1); + erlang::term term_test(in erlang::term a, out erlang::term a1); + + // typedef test + long typedef_test(in apa a, in banan b, out apa a1, out banan b1); + + // inlined seq. test + s inline_sequence_test(in s a, out s a1); + + // term seq. test + etseq term_sequence_test(in etseq a, out etseq a1); + // term struct test + et term_struct_test(in et a, out et a1); + + }; + +}; diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl new file mode 100644 index 0000000000..b5ee7af199 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl @@ -0,0 +1,331 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(erl_client). + +-export([void_test/2, long_test/2, longlong_test/2, ushort_test/2, + ulong_test/2, ulonglong_test/2, double_test/2, char_test/2, + wchar_test/2, octet_test/2, bool_test/2, struct_test/2, + struct2_test/2, seq1_test/2, seq2_test/2, seq3_test/2, + seq4_test/2, seq5_test/2, array1_test/2, array2_test/2, + enum_test/2, string1_test/2, wstring1_test/2, string2_test/2, + string3_test/2, string4_test/2, pid_test/2, port_test/2, + ref_test/2, term_test/2, typedef_test/2, + inline_sequence_test/2, term_sequence_test/2, + term_struct_test/2 + +]). + +-include("m.hrl"). +-include("m_i.hrl"). +-include("oe_erl_c_test.hrl"). + +%%b +void_test(Node, Timeout) -> + Ret = m_i:void_test({olsson, Node}, Timeout), + Ret == void. % XXX Not documented +%%e + +%%b +long_test(Node, Timeout) -> + In = max_long(), + {Ret, Out} = m_i:long_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +longlong_test(Node, Timeout) -> + In = 65537, + {Ret, Out} = m_i:longlong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ushort_test(Node, Timeout) -> + In = max_ushort(), + {Ret, Out} = m_i:ushort_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ulong_test(Node, Timeout) -> + In = max_ulong(), + {Ret, Out} = m_i:ulong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ulonglong_test(Node, Timeout) -> + In = 65537, + {Ret, Out} = m_i:ulonglong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +double_test(Node, Timeout) -> + In = 37768.93, + {Ret, Out} = m_i:double_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +char_test(Node, Timeout) -> + In = 80, + {Ret, Out} = m_i:char_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +wchar_test(Node, Timeout) -> + In = 4097, + {Ret, Out} = m_i:wchar_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +octet_test(Node, Timeout) -> + In = 255, + {Ret, Out} = m_i:octet_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +bool_test(Node, Timeout) -> + In = false, + {Ret, Out} = m_i:bool_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +struct_test(Node, Timeout) -> + In = #m_b{l = max_long(), c = $a}, + {Ret, Out} = m_i:struct_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +struct2_test(Node, Timeout) -> + In = #m_es{ f = banana, l = max_long()}, + {Ret, Out} = m_i:struct2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq1_test(Node, Timeout) -> + B1 = #m_b{l = max_long(), c = $a}, + B2 = #m_b{l = min_long(), c = $b}, + In = [B1, B2], + {Ret, Out} = m_i:seq1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq2_test(Node, Timeout) -> + B = #m_b{l = max_long(), c = $a}, + A = #m_a{l = min_long(), y = [B, B], d = 4711.31}, + In = [A, A, A], + {Ret, Out} = m_i:seq2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq3_test(Node, Timeout) -> + In = [max_long(), min_long(), max_long()], + {Ret, Out} = m_i:seq3_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq4_test(Node, Timeout) -> + In = [["hej", "hopp"], ["ditt", "feta", "nylle"]], + {Ret, Out} = m_i:seq4_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq5_test(Node, Timeout) -> + Arr3 = mk_array(3, max_long()), + In = [[Arr3, Arr3], [Arr3, Arr3, Arr3]], + {Ret, Out} = m_i:seq5_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +array1_test(Node, Timeout) -> + In = mk_array(500, min_long()), + {Ret, Out} = m_i:array1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +array2_test(Node, Timeout) -> + In = mk_array(2, mk_array(3, min_long())), + {Ret, Out} = m_i:array2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +enum_test(Node, Timeout) -> + In = banana, + {Ret, Out} = m_i:enum_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string1_test(Node, Timeout) -> + In = "Die Paula muss beim Tango immer weinen", + {Ret, Out} = m_i:string1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +wstring1_test(Node, Timeout) -> + In = [1047| "ie Paula muss beim Tango immer weinen"], + {Ret, Out} = m_i:wstring1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string2_test(Node, Timeout) -> + In = ["Lass doch die Blumen,", "Konrad!"], + {Ret, Out} = m_i:string2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string3_test(Node, Timeout) -> + In = "Seeman, lass uns freuden!", + {Ret, Out} = m_i:string3_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string4_test(Node, Timeout) -> + + In = #m_strRec{ + bb = true, + str4 = "Paula war zu Hause in ihrem Stadtchen als die beste Tanzerin" + "bekannt", + str7 = mk_array(3, mk_array(2, max_long())), + str5 = [$a, $b, $c, $d, $e, $f], + str6 = "123456789012", + str8 = {$x, $y, $x}, + str9 = "123456789012", + str10 = [$a, $b, $c, $d, $e, $f] + }, + {Ret, Out} = m_i:string4_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +pid_test(Node, Timeout) -> + In = self(), + {Ret, Out} = m_i:pid_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +port_test(Node, Timeout) -> + In = get(port_test_port), + {Ret, Out} = m_i:port_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ref_test(Node, Timeout) -> + In = make_ref(), + {Ret, Out} = m_i:ref_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_test(Node, Timeout) -> + In = {[a, b], 17, kalle}, + {Ret, Out} = m_i:term_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +typedef_test(Node, Timeout) -> + In1 = {nisse, [1, 2], olsson}, + In2 = get(port_test_port), + {Ret, Out1, Out2} = m_i:typedef_test({olsson, Node}, Timeout, In1, In2), + %% XXX Should check that Ret is an integer. + (Out1 == In1) and (Out2 == In2). +%%e + +%%b +inline_sequence_test(Node, Timeout) -> + In = #m_s{l = min_long(), sl = [max_long(), min_long()]}, + {Ret, Out} = m_i:inline_sequence_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_sequence_test(Node, Timeout) -> + In = lists:duplicate(17, {nisse, [1, 2], {kalle, olsson}}), + {Ret, Out} = m_i:term_sequence_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_struct_test(Node, Timeout) -> + In = #m_et{e = {nisse, ["abcde"], {kalle, olsson}}, l = 4711}, + {Ret, Out} = m_i:term_struct_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + + +%% Locals + +mk_array(Es) -> + list_to_tuple(Es). + +mk_array(N, E) -> + mk_array(lists:duplicate(N, E)). + +%% max_short() -> +%% power_of_two(15) - 1. +max_long() -> + power_of_two(31) - 1. +max_longlong() -> + power_of_two(63) - 1. +max_ushort() -> + power_of_two(16) - 1. +max_ulong() -> + power_of_two(32) - 1. +max_ulonglong() -> + power_of_two(64) - 1. + +%% min_short() -> +%% -power_of_two(15). +min_long() -> + -power_of_two(31). +%% min_longlong() -> +%% -power_of_two(63). +%% min_ushort() -> +%% 0. +%% min_ulong() -> +%% 0. +%% min_ulonglong() -> +%% 0. + +power_of_two(N) -> + round(math:pow(2, N)). + diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c new file mode 100644 index 0000000000..c0401b2621 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c @@ -0,0 +1,34 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ +#include "ic.h" +#include "m_i.h" + +int my_prepare_request_decoding(CORBA_Environment *env) +{ + return oe_prepare_request_decoding(env); +} + +int my_prepare_reply_encoding(CORBA_Environment *env) +{ + return oe_prepare_reply_encoding(env); +} + + + diff --git a/lib/ic/test/ic.spec b/lib/ic/test/ic.spec new file mode 100644 index 0000000000..280c2aba47 --- /dev/null +++ b/lib/ic/test/ic.spec @@ -0,0 +1 @@ +{topcase, {dir, "../ic_test"}}. diff --git a/lib/ic/test/ic.spec.vxworks b/lib/ic/test/ic.spec.vxworks new file mode 100644 index 0000000000..b15260ab70 --- /dev/null +++ b/lib/ic/test/ic.spec.vxworks @@ -0,0 +1,2 @@ +{topcase, {dir, "../ic_test"}}. +{skip,{ic_pp_SUITE,"Uses gcc"}}. diff --git a/lib/ic/test/ic_SUITE.erl b/lib/ic/test/ic_SUITE.erl new file mode 100644 index 0000000000..6682c82f01 --- /dev/null +++ b/lib/ic/test/ic_SUITE.erl @@ -0,0 +1,973 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%%---------------------------------------------------------------------- +%%% Purpose : Test suite for the IDL compiler +%%%---------------------------------------------------------------------- + +-module(ic_SUITE). +-include("test_server.hrl"). + +-export([all/1]). + + +-include_lib("orber/src/orber_ifr.hrl"). +-include_lib("orber/src/ifr_objects.hrl"). +-include_lib("orber/include/ifr_types.hrl"). + + +%% The type cases +-export([type/1, type_norm/1]). + +%% The syntax case +-export([syntax/1]). +-export([syntax1/1, syntax2/1, syntax3/1, syntax4/1, syntax5/1, syntax6/1]). + +%% The constant cases +-export([const/1]). +-export([const_norm/1, const_bad_tk/1, const_bad_type/1]). +-export([const_bad_comb/1]). + +%% The union cases +-export([union/1]). +-export([union_norm/1, union_type/1, union_mult_err/1, union_case_mult/1]). +-export([union_default/1]). + +%% The enum cases +-export([enum/1]). +-export([enum_norm/1]). + +%% The struct cases +-export([struct/1]). +-export([struct_norm/1]). + +%% The oneway cases +-export([oneway/1]). +-export([oneway_norm/1, oneway_raises/1, oneway_out/1, oneway_void/1, oneway_followed/1]). + +%% The attributes cases +-export([attr/1]). +-export([attr_norm/1]). + +%% The raises registration case +-export([raises_reg/1]). + + +%% The typeID case + +%% general stuff +-export([general/1]). +-export([typeid/1, undef_id/1, dir/1, nasty_names/1, coss/1, mult_ids/1]). +-export([forward/1, include/1, app_test/1]). + +%% inheritance stuff +-export([inherit/1, inherit_norm/1, inherit_warn/1, inherit_err/1]). + +%% Standard options to the ic compiler, NOTE unholy use of OutDir + +-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])). + + +%% Top of cases + +all(doc) -> + []; +all(suite) -> [app_test, const, union, enum, attr, type, struct, general, inherit, + oneway, syntax, raises_reg]. + + +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ok=test_server:app_test(ic), + ok. + +%%--------------------------------------------------------------------- +%% +%% Test of constant expressions. +%% + +const(suite) -> [const_norm, const_bad_tk, const_bad_type, const_bad_comb]. + + +const_norm(doc) -> + ["Checks normal constant types and values"]; +const_norm(suite) -> []; +const_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(const_norm), + File = filename:join(DataDir, c_norm), + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, const_norm_files()), + ok. + +const_bad_tk(doc) -> + ["Checks when the constant value doesn't match the declared type"]; +const_bad_tk(suite) -> []; +const_bad_tk(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, c_err1), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(18, bad_tk_match, R), + ok. + +const_bad_type(doc) -> + ["Checks operands of ops are of correct type"]; +const_bad_type(suite) -> []; +const_bad_type(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, c_err2), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(4, bad_type, R), + ok. + +const_bad_comb(doc) -> + ["Checks operands of ops are of conflicting types"]; +const_bad_comb(suite) -> []; +const_bad_comb(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, c_err3), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(3, bad_type_combination, R), + ok. + + + +union(suite) -> [union_norm, union_type, union_mult_err, union_case_mult, + union_default]; +union(doc) -> + ["Checks allowed usage of the union as well as the illegal cases"]. + + +union_norm(doc) -> + ["Checks that normal union declarations works."]; +union_norm(suite) -> []; +union_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(union_norm), + File = filename:join(DataDir, u_norm), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, union_norm_files()), + ok. + + +%% Checks OTP-2007 +union_default(doc) -> + ["Checks that default cases are correct in type code."]; +union_default(suite) -> []; +union_default(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(union_default), + File = filename:join(DataDir, u_default), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, union_default_files(), [load]), + TkList = i1:oe_get_interface(), + check_label("op0", 0, TkList), + check_label("op1", 1, TkList), + check_label("op2", 2, TkList), + check_label("op3", -1, TkList), + ok. + +check_label(Id, N, List) -> + case lists:keysearch(Id, 1, List) of + {value, {_, {{_, _, _, _, D, L}, _, _}}} -> + if D /= N -> + test_server:fail({bad_default_num, D, N}); + D /= -1 -> + case lists:nth(D+1, L) of + T when element(1, T) == default -> + ok; + _Que -> + test_server:fail({bad_default_list, D, L}) + end; + true -> + %% D = N = -1, just check that there is no default label + case lists:keysearch(default, 1, L) of + false -> + ok; + _ -> + test_server:fail({bad_default_label, D, L}) + end + end; + _ -> + test_server:fail({'no_such_op!', Id, List}) + end. + +union_type(doc) -> + ["Checks that errors are detected. Check that mismatch between case ", + "value and declared discriminator type is detected."]; +union_type(suite) -> []; +union_type(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, u_type), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(28, bad_case_type, R), + ok. + + +union_mult_err(doc) -> + ["Check that multiple declared declarators are caught.", + "Also check that if the discriminator is an enum, then the enum name", + "must not be used as a declarator in the union switch (declarator", + "as opposed to label)."]; +union_mult_err(suite) -> []; +union_mult_err(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, u_mult), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(8, multiply_defined, R), + ok. + +%% Checking mult cases. Now check that other errors are found in the +%% correct order XXXX + + +union_case_mult(doc) -> + ["Check that multiply defined case labels are found and reported."]; +union_case_mult(suite) -> []; +union_case_mult(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, u_case_mult), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(7, multiple_cases, R), + ok. + + +%%-------------------------------------------------------------------- +%% +%% Enum cases +%% + +enum(suite) -> [enum_norm]; +enum(doc) -> + ["Checks allowed usage of the enum as well as the illegal cases"]. + +enum_norm(doc) -> + ["Checks that normal enum declarations works."]; +enum_norm(suite) -> []; +enum_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(enum_norm), + File = filename:join(DataDir, enum), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, enum_norm_files()), + ok. + + +%%-------------------------------------------------------------------- +%% +%% Struct cases +%% + +struct(suite) -> [struct_norm]; +struct(doc) -> + ["Checks allowed usage of the struct as well as the illegal cases"]. + +struct_norm(doc) -> + ["Checks that normal struct declarations works."]; +struct_norm(suite) -> []; +struct_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(struct_norm), + File = filename:join(DataDir, struct), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, struct_norm_files()), + Mod = ridiculous_name_to_avoid_clash_svenne, + TestFile = filename:join(OutDir, Mod), + ?line ok = gen_struct_file(TestFile, Mod), + ?line ok = compile(OutDir, [Mod], [load]), +%% ?line {ok, Mod, []} = compile:file(TestFile, +%% [{i, OutDir}, {outdir, OutDir}, +%% return, load]), + ?line ok = Mod:test(), + ok. + + +%%-------------------------------------------------------------------- +%% +%% General cases +%% + +general(doc) -> + ["Check general things like directories and type identifier", + "detection."]; +general(suite) -> [typeid, undef_id, mult_ids, forward, include, nasty_names]. +%% coss (add sometimes, takes 440 seconds!) + +typeid(doc) -> + ["Check that type id's are generated correctly"]; +typeid(suite) -> []; +typeid(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(typeid), + File = filename:join(DataDir, typeid), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, typeid_files(), [load]), + ?line "IDL:I1:1.0" = 'I1':'typeID'(), + ?line "IDL:M1/I1:1.0" = 'M1_I1':'typeID'(), + ?line "IDL:M2/M1/I1:1.0" = 'M2_M1_I1':'typeID'(), + ?line "IDL:M3/M2/M1/I1:1.0" = 'M3_M2_M1_I1':'typeID'(), + ok. + + +%%% This test case is removed because there's no way to test this from +%%% an automated test suite. +dir(doc) -> + ["Check that relative directories work, absolute is used in", + "all other cases in the suite."]; +%%% xxxxxx +dir(suite) -> []; +dir(Config) when is_list(Config) -> +ok; +dir(Config) -> + DataDir = ?config(data_dir, Config), + + %% Needs a unique directory (any better way?) + OutDir = mk_unique("oe_the_dir"), + + %% More unique names + File = filename:join(DataDir, mk_unique("oe_the_file")), + Const = mk_unique("oe_the_constant"), + Mod = list_to_atom(File), + Func = list_to_atom(Const), + + %% Generate a unique IDL file with a single constant + gen_file(File, Const), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line ok = compile(OutDir, [load]), + ?line 19955 = Mod:Func(), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, [load]), + ?line 19955 = Mod:Func(), + + ?line ok = ic:gen(File), +%%% ?line ok = compile(".", [load]), + ok. + +undef_id(doc) -> + ["Check that various undefied id's are detected correctly"]; +undef_id(suite) -> []; +undef_id(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, undef_id), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(16, tk_not_found, R), + ok. + +mult_ids(doc) -> + ["Check that multiply defined ids are caught."]; +mult_ids(suite) -> []; +mult_ids(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, mult_ids), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(22, multiply_defined, R), + ok. + + +nasty_names(doc) -> + ["Check that various nasty names can be generated.", + "Try to provoke name clashes and name conflicts with", + "Erlang and IDL"]; +nasty_names(suite) -> []; +nasty_names(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(nasty_names), + File = filename:join(DataDir, nasty), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, nasty_names_files(), [load]), + ok. + +coss(doc) -> + ["Check that the Coss standard specification works."]; +coss(suite) -> []; +coss(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(coss), + File = filename:join(DataDir, 'Coss'), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, [_W1]} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, []), + ok. + +forward(doc) -> + ["Check that forward declaratios work."]; +forward(suite) -> []; +forward(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(forward), + File = filename:join(DataDir, forward), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, forward_files(), [load]), + ok. + +include(doc) -> + ["Check that various undefied id's are detected correctly"]; +include(suite) -> []; +include(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, include), + ?line error = ic:gen(File, stdopts(OutDir)++[{preproc_flags,"-I" ++ DataDir}]), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[{preproc_flags,"-I" ++ DataDir},silent2]), + case lists:map(fun(D) -> + filename:rootname(filename:basename(element(3, D))) + end, + lists:sort(R)) of + ["include", + "include2", + "include2", + "include3"] -> + ok; + RRR -> + test_server:fail({bad_include_file, RRR}) + end, + ok. + + + + +%%-------------------------------------------------------------------- +%% +%% Inhertit cases +%% + +inherit(doc) -> + ["Check the inheritance mechanism."]; +inherit(suite) -> [inherit_norm, inherit_warn, inherit_err]. + +inherit_norm(doc) -> + ["Checks that normal inheritance works."]; +inherit_norm(suite) -> []; +inherit_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(inherit_norm), + File = filename:join(DataDir, inherit), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, _Ws} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, inherit_norm_files(), [load]), + + %% Now check constant values: + ?line 9 = m1_I1:c1(), + + ?line 9 = m1_I2:c1(), + ?line 14 = m1_I2:c2(), + ?line 27 = m1_I2:c3(), + + ?line 50 = m1_I3:c1(), + ?line 14 = m1_I3:c2(), + ?line 27 = m1_I3:c3(), + ?line 91 = m1_I3:c4(), + ?line 100 = m1_I3:c5(), + ok. + +inherit_warn(doc) -> + ["Check that various inheritance shadowing is detected"]; +inherit_warn(suite) -> []; +inherit_warn(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, inherit_warn), + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(7, inherit_name_shadow, R), + ok. + +inherit_err(doc) -> + ["Check that various inheritance errors is detected"]; +inherit_err(suite) -> []; +inherit_err(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, inherit_err), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, _Ws, R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(21, inherit_name_collision, R), + ok. + + +oneway(doc) -> + ["Check the oneway operation mechanism."]; +oneway(suite) -> [oneway_norm, oneway_out, oneway_raises, oneway_void, oneway_followed ]. + +oneway_norm(doc) -> + ["Checks that normal oneway operations works."]; +oneway_norm(suite) -> []; +oneway_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(oneway_norm), + File = filename:join(DataDir, one), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line ok = compile(OutDir, oneway_norm_files(), [load]), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, oneway_norm_files(), [load]), + ok. + +oneway_void(doc) -> + ["Check that non-void oneways are detected."]; +oneway_void(suite) -> []; +oneway_void(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, one_void), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(2, bad_oneway_type, R), + ok. + +oneway_raises(doc) -> + ["Check that oneways cannot raise exceptions."]; +oneway_raises(suite) -> []; +oneway_raises(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, one_raises), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(3, oneway_raises, R), + ok. + +oneway_out(doc) -> + ["Check that illegal out parameters are detected"]; +oneway_out(suite) -> []; +oneway_out(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, one_out), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(2, oneway_outparams, R), + ok. + +oneway_followed(doc) -> + ["Checks that normal oneways, followed by other operations."]; +oneway_followed(suite) -> []; +oneway_followed(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(oneway_followed), + File = filename:join(DataDir, one_followed), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line ok = compile(OutDir, oneway_followed_files(), [load]), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, oneway_followed_files(), [load]), + ok. + +attr(doc) -> + ["Check that attributes work."]; +attr(suite) -> [attr_norm]. + +attr_norm(doc) -> + ["Checks that normal attr operations works."]; +attr_norm(suite) -> []; +attr_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(attr_norm), + File = filename:join(DataDir, attr), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line ok = compile(OutDir, attr_norm_files(), [load]), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, attr_norm_files(), [load]), + ok. + +type(doc) -> + ["Check that typeibutes work."]; +type(suite) -> [type_norm]. + +type_norm(doc) -> + ["Checks all types are handled."]; +type_norm(suite) -> []; +type_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(type_norm), + File = filename:join(DataDir, type), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line ok = compile(OutDir, type_norm_files(), [load]), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, type_norm_files(), [load]), + ok. + + +syntax(doc) -> + ["Check that syntax errors are discovered."]; +syntax(suite) -> [syntax1, syntax2, syntax3, syntax4, syntax5, syntax6]. + +syntax1(suite) -> []; +syntax1(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax1), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + +syntax2(suite) -> []; +syntax2(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax2), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + +syntax3(suite) -> []; +syntax3(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax3), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + +syntax4(suite) -> []; +syntax4(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax4), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + +syntax5(suite) -> []; +syntax5(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax5), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + +syntax6(suite) -> []; +syntax6(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax6), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + + + +%%-------------------------------------------------------------------- +%% +%% Checks RAISES to be registered under IFR operation registration +%% ( OTP-2102 ) +%% + +raises_reg(doc) -> + ["Check that exceptions are really registered to operations."]; +raises_reg(suite) -> []; +raises_reg(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(raises_reg_check), + File = filename:join(DataDir, raises_reg), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, raises_reg_files(), [load]), + + set_up('oe_raises_reg'), + + io:format("~n##### Starting the test case #####~n"), + io:format("Checking for existance of exception : ~s~n",["IDL:Raises_RegModule/Exception_1:1.0"]), + raises_register_check("IDL:Raises_RegModule/R_R/op:1.0","IDL:Raises_RegModule/Exception_1:1.0"), + + io:format("Checking for existance of exception : ~s~n",["IDL:Raises_RegModule/Exception_2:1.0"]), + raises_register_check("IDL:Raises_RegModule/R_R/op:1.0","IDL:Raises_RegModule/Exception_2:1.0"), + + io:format("Checking for existance of exception : ~s~n",["IDL:Raises_RegModule/XXXXXXXX:1.0"]), + raises_register_check("IDL:Raises_RegModule/R_R/op:1.0","IDL:RaisesModule/XXXXXXXX:1.0"), + + set_down('oe_raises_reg'), + + ok. + +set_up(Register) -> + io:format("Setting up.....~n"), + mnesia:stop(), + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + mnesia:start(), + orber:install([node()]), + orber:start(), + io:format("Running OE_register()~n"), + Register:'oe_register'(). + +set_down(Register) -> + io:format("Running OE_unregister()~n"), + Register:'oe_unregister'(), + io:format("Setting down.....~n"), + orber:stop(), + orber:uninstall(), + mnesia:stop(), + mnesia:delete_schema([node()]). + + +raises_register_check(OpId,ExcId) -> + case is_valid_exc(OpId,ExcId) of + true -> + ok; % Because right exception where found, + % the test succeeds for normal cases. + false -> + ok; % Because the exception tested, is not + % registered for that operation. + FailReason -> + test_server:fail({FailReason, OpId, ExcId}) + % Because the test descovered errors in a previous + % stage, or no exceptions where registered att all. + % ( This testcase assumes that operations to be + % checked allways raise excption(s) ) + end. + +is_valid_exc(OpId,ExcId) -> + OE_IFR = orber_ifr:find_repository(), + OpDef = orber_ifr:'Repository_lookup_id'(OE_IFR,OpId), + ExcDefList = orber_ifr:get_exceptions(OpDef), + case ExcDefList of + [] -> + no_exceptions_registered; + _ -> + ExcDef=orber_ifr:lookup_id(OE_IFR,ExcId), + lists:member(ExcDef,ExcDefList) + end. + +%%-------------------------------------------------------------------- +%% +%% Utilities + + +stdopts(OutDir) -> + [{outdir, OutDir},{maxerrs, infinity}]. + +mk_unique(Prefix) -> + {A,B,C} = now(), + Prefix++"_"++integer_to_list(A)++"_"++integer_to_list(B)++"_"++ + integer_to_list(C). + +gen_file(File, Const) -> + {ok, Fd} = file:open(File++".idl", [write]), + io:format(Fd, "interface ~s {~n", [File]), + io:format(Fd, " const long ~s = 19955;~n", [Const]), + io:format(Fd, "};~n", []), + file:close(Fd). + + +%% Compile all files in Dir. Used for checking that valid Erlang has +%% been generated. +%%compile(Dir) -> +%% compile(Dir, []). +%%compile(Dir, Opts) -> +%% {ok, Cwd} = file:get_cwd(), +%% catch do_compile(Dir, Opts), +%% file:set_cwd(Cwd). + +%%do_compile(Dir, Opts) -> +%% ok = file:set_cwd(Dir), +%% up_to_date = ts_make_erl:all(Opts), +%% ok. + +compile(Dir, Files) -> + compile(Dir, Files, []). + +compile(Dir, Files, Opts) -> + {ok, Cwd} = file:get_cwd(), + file:set_cwd(Dir), + io:format("Changing to ~p~n", [Dir]), + case catch do_compile(Files, Opts) of + ok -> + file:set_cwd(Cwd); + Err -> + file:set_cwd(Cwd), + test_server:fail(Err) + end. + +do_compile([], _Opts) -> ok; +do_compile([F | Fs], Opts) -> + io:format("Compiling ~p", [F]), + case compile:file(F, Opts) of + ok -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + Err -> + io:format(" error: ~p~n", [Err]), + Err + end. + +do_load(File, Opts) -> + case lists:member(load, Opts) of + true -> + io:format("Loading file ~p", [File]), + code:purge(File), + R = code:load_abs(File), + io:format("Loaded: ~p", [R]); + false -> + ok + end. + + +%% Check that ErrList consists of exactly Num errors of type ErrType +check_errors(Num, ErrType, ErrList) -> + Num = length(ErrList), + lists:foreach(fun(T) -> + case catch element(1, element(4, T)) of + ErrType -> ok; + Else -> + test_server:fail({bad, ErrType, Else}) + end end, ErrList). + +to_list(X) when is_atom(X) -> atom_to_list(X); +to_list(X) -> X. + + +%% File must be an atom +gen_struct_file(File, Mod) -> + + ?line {ok, Fd} = file:open(to_list(File)++".erl", [write]), + io:format(Fd, "~n", []), + io:format(Fd, "-module(~p).~n", [Mod]), + io:format(Fd, "-export([test/0]).~n", []), + io:format(Fd, "-include(\"oe_struct.hrl\").~n", []), + io:format(Fd, "test() ->~n", []), + io:format(Fd, " A = #'S1'{a=99, b=$a, s=\"123456789\"},~n", []), + io:format(Fd, " B = #'S2'{a=9, b=#'S2_S3'{a=1, b=9, b1=5, c=$2},~n", []), + io:format(Fd, " c=[#'S1'{a=1}, #'S1'{a=2}],~n", []), + io:format(Fd, +" c2=[#'S1'{a=2}, #'S1'{a=3}, #'S1'{a=2}, #'S1'{a=3}]},~n", []), + io:format(Fd, " C = #'S2_S3'{a=11, b=999, b1=19},~n", []), + io:format(Fd, " D = #s4{a=7},~n", []), + io:format(Fd, " E = {1, #'U1_S5'{a=3}},~n", []), + io:format(Fd, " F = {2, {$b, #'U1_U2_s6'{a=6, b=false}}},~n", []), + io:format(Fd, " ok.~n", []), + file:close(Fd). + + +union_norm_files() -> ['oe_u_norm']. +union_default_files() -> ['oe_u_default', i1]. + +typeid_files() -> ['oe_typeid', 'M3_M2_M1_I1', 'M2_M1_I1', 'M1_I1', 'I1']. + +struct_norm_files() -> ['oe_struct']. +oneway_norm_files() -> ['oe_one', 'I1']. +oneway_followed_files() -> ['oe_one_followed', 'I1']. +nasty_names_files() -> ['oe_nasty', 'I2', 'I1']. + +inherit_norm_files() -> [m1_I3, m1_I2, m1_I1, 'oe_inherit', 'I4', 'I3', + 'I2', 'I1']. + +forward_files() -> [i1, 'oe_forward']. +enum_norm_files() -> ['oe_enum']. +const_norm_files() -> ['oe_c_norm']. +attr_norm_files() -> ['oe_attr', 'I1', 'I2']. +type_norm_files() -> ['oe_type']. + +raises_reg_files() -> ['oe_raises_reg']. + + + + + + + + + + + + + + + + diff --git a/lib/ic/test/ic_SUITE_data/Corba.idl b/lib/ic/test/ic_SUITE_data/Corba.idl new file mode 100644 index 0000000000..6b81132500 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/Corba.idl @@ -0,0 +1,1013 @@ +// This file contains OMG IDL from CORBA V2.0, July 1995. +// Includes IDL for CORBA Core +// (Interface Repository, ORB Interface, Basic Object Adapter Interface) +// and CORBA Interoperability (IOP, GIOP, IIOP, and DCE CIOP modules) + +// Complete OMG IDL for Interface Repository starts on pg 6-42, CORBA V2.0 July 1995 +// IRObject interface described on pg 6-9 CORBA V2.0, July 1995 +// Contained interface: pg 6-11 CORBA V2, 7-95 +// Container interface: pg 6-12 thru 6-15 CORBA V2, 7-95 +// IDLType interface: pg 6-15 CORBA V2, 7-95 +// Repository interface: pg 6-16 CORBA V2, 7-95 +// ModuleDef interface: pg 6-17 CORBA V2, 7-95 +// ConstantDef interface: pg 6-18 CORBA V2, 7-95 +// TypeDef interface: pg 6-19 CORBA V2, 7-95 +// StructDef interface: pg 6-19 CORBA V2, 7-95 +// UnionDef interface: pg 6-19 CORBA V2, 7-95 +// EnumDef interface: pg 6-20 CORBA V2, 7-95 +// AliasDef interface: pg 6-21 CORBA V2, 7-95 +// PrimitiveDef interface: pg 6-21 CORBA V2, 7-95 +// StringDef interface: pg 6-22 CORBA V2, 7-95 +// SequenceDef interface: pg 6-22 CORBA V2, 7-95 +// ArrayDef interface: pg 6-23 CORBA V2, 7-95 +// ExceptionDef interface: pg 6-24 CORBA V2, 7-95 +// AttributeDef interface: pg 6-25 CORBA V2, 7-95 +// OperationDef interface: pg 6-26 CORBA V2, 7-95 +// InterfaceDef interface: pg 6-28 CORBA V2, 7-95 +// TypeCode interface (PIDL): pg 6-34 CORBA V2, 7-95 +// ORB interface: pg 6-40 CORBA V2, 7-95 + +#ifndef __CORBA_IDL +#define __CORBA_IDL + +// #pragma prefix "omg.org" +module CORBA { + + interface TypeCode; + typedef string Identifier; + typedef string ScopedName; + typedef string RepositoryId; + + /* + * start of section added by Christian Blum + */ + + typedef enum new_type {NO,USER,SYSTEM_EXCEPTION} exception_type; + + /** + * no definition for this type + */ + interface ImplementationDef + { + }; + + /** + * no definition for this type + */ + //interface Principal + struct Principal + { + string str; + }; + + /** + * no definition for this type + */ + interface Environment + { + + }; + + typedef unsigned long Flags; + typedef unsigned long Status; + + struct NamedValue // PIDL + { + Identifier name; // argument name + any argument; // argument + long len; // length/count of argument value + Flags arg_modes; // argument mode flags + + }; + + typedef sequence<NamedValue> NVList; /* C */ + + interface Request // PIDL + { + + Status add_arg ( + in Identifier name, // argument name + in TypeCode arg_type, // argument datatype + // in void * value, // argument value to be added + in any value_LOOK_AT_SOURCE, // changed by blum + in long len, // length/count of argument value + in Flags arg_flags // argument flags + ); + + Status invoke ( + in Flags invoke_flags // invocation flags + ); + + Status delete (); + Status send ( + in Flags invoke_flags // invocation flags + ); + + Status get_response ( + in Flags response_flags // response flags + ); + + }; + + + interface Context // PIDL + { + + Status set_one_value ( + in Identifier prop_name, // property name to add + in string value // property value to add + ); + + Status set_values ( + in NVList values // property values to be changed + ); + + Status get_values ( + in Identifier start_scope, // search scope + in Flags op_flags, // operation flags + in Identifier prop_name, // name of property(s) to retrieve + out NVList values // requested property(s) + ); + + Status delete_values ( + in Identifier prop_name // name of property(s) to delete + ); + + Status create_child ( + in Identifier ctx_name, // name of context object + out Context child_ctx // newly created context object + ); + + Status delete ( + in Flags del_flags // flags controlling deletion + ); + + }; + + /* + * end of section added by Christian Blum + */ + + + enum DefinitionKind { + dk_none, dk_all, + dk_Attribute, dk_Constant, dk_Exception, dk_Interface, + dk_Module, dk_Operation, dk_Typedef, + dk_Alias, dk_Struct, dk_Union, dk_Enum, + dk_Primitive, dk_String, dk_Sequence, dk_Array, + dk_Repository + }; + + + interface IRObject { + // read interface + readonly attribute DefinitionKind def_kind; + + // write interface + void destroy (); + }; + + + + typedef string VersionSpec; + + interface Contained; + interface Repository; + interface Container; + + interface Contained : IRObject { + // read/write interface + + attribute RepositoryId id; + attribute Identifier name; + attribute VersionSpec version; + + // read interface + + readonly attribute Container defined_in; + readonly attribute ScopedName absolute_name; + readonly attribute Repository containing_repository; + + struct Description { + DefinitionKind kind; + any value; + }; + + Description describe (); + + // write interface + + void move ( + in Container new_container, + in Identifier new_name, + in VersionSpec new_version + ); + }; + + + interface ModuleDef; + interface ConstantDef; + interface IDLType; + interface StructDef; + interface UnionDef; + interface EnumDef; + interface AliasDef; + interface InterfaceDef; + typedef sequence <InterfaceDef> InterfaceDefSeq; + + typedef sequence <Contained> ContainedSeq; + + struct StructMember { + Identifier name; + TypeCode type; + IDLType type_def; + }; + typedef sequence <StructMember> StructMemberSeq; + + struct UnionMember { + Identifier name; + any label; + TypeCode type; + IDLType type_def; + }; + typedef sequence <UnionMember> UnionMemberSeq; + + typedef sequence <Identifier> EnumMemberSeq; + + interface Container : IRObject { + // read interface + + Contained lookup ( in ScopedName search_name); + + ContainedSeq contents ( + in DefinitionKind limit_type, + in boolean exclude_inherited + ); + + ContainedSeq lookup_name ( + in Identifier search_name, + in long levels_to_search, + in DefinitionKind limit_type, + in boolean exclude_inherited + ); + + struct Description { + Contained contained_object; + DefinitionKind kind; + any value; + }; + + typedef sequence<Description> DescriptionSeq; + + DescriptionSeq describe_contents ( + in DefinitionKind limit_type, + in boolean exclude_inherited, + in long max_returned_objs + ); + + // write interface + + ModuleDef create_module ( + in RepositoryId id, + in Identifier name, + in VersionSpec version + ); + + ConstantDef create_constant ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in IDLType type, + in any value + ); + + StructDef create_struct ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in StructMemberSeq members + ); + + UnionDef create_union ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in IDLType discriminator_type, + in UnionMemberSeq members + ); + + EnumDef create_enum ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in EnumMemberSeq members + ); + + AliasDef create_alias ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in IDLType original_type + ); + + InterfaceDef create_interface ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in InterfaceDefSeq base_interfaces + ); + }; + + + + interface IDLType : IRObject { + readonly attribute TypeCode type; + }; + + + + interface PrimitiveDef; + interface StringDef; + interface SequenceDef; + interface ArrayDef; + + enum PrimitiveKind { + pk_null, pk_void, pk_short, pk_long, pk_ushort, pk_ulong, + pk_float, pk_double, pk_boolean, pk_char, pk_octet, + pk_any, pk_TypeCode, pk_Principal, pk_string, pk_objref + }; + + interface Repository : Container { + // read interface + + Contained lookup_id (in RepositoryId search_id); + + PrimitiveDef get_primitive (in PrimitiveKind kind); + + // write interface + + StringDef create_string (in unsigned long bound); + + SequenceDef create_sequence ( + in unsigned long bound, + in IDLType element_type + ); + + ArrayDef create_array ( + in unsigned long length, + in IDLType element_type + ); + }; + + + interface ModuleDef : Container, Contained { + }; + + struct ModuleDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + }; + + + interface ConstantDef : Contained { + readonly attribute TypeCode type; + attribute IDLType type_def; + attribute any value; + }; + + struct ConstantDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + TypeCode type; + any value; + }; + + + interface TypedefDef : Contained, IDLType { + }; + + struct TypeDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + TypeCode type; + }; + + + interface StructDef : TypedefDef { + attribute StructMemberSeq members; + }; + + + interface UnionDef : TypedefDef { + readonly attribute TypeCode discriminator_type; + attribute IDLType discriminator_type_def; + attribute UnionMemberSeq members; + }; + + + interface EnumDef : TypedefDef { + attribute EnumMemberSeq members; + }; + + + interface AliasDef : TypedefDef { + attribute IDLType original_type_def; + }; + + + interface PrimitiveDef: IDLType { + readonly attribute PrimitiveKind kind; + }; + + + interface StringDef : IDLType { + attribute unsigned long bound; + }; + + + interface SequenceDef : IDLType { + attribute unsigned long bound; + readonly attribute TypeCode element_type; + attribute IDLType element_type_def; + }; + + interface ArrayDef : IDLType { + attribute unsigned long length; + readonly attribute TypeCode element_type; + attribute IDLType element_type_def; + }; + + + interface ExceptionDef : Contained { + readonly attribute TypeCode type; + attribute StructMemberSeq members; + }; + struct ExceptionDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + TypeCode type; + }; + + + + enum AttributeMode {ATTR_NORMAL, ATTR_READONLY}; + + interface AttributeDef : Contained { + readonly attribute TypeCode type; + attribute IDLType type_def; + attribute AttributeMode mode; + }; + + struct AttributeDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + TypeCode type; + AttributeMode mode; + }; + + + + enum OperationMode {OP_NORMAL, OP_ONEWAY}; + + enum ParameterMode {PARAM_IN, PARAM_OUT, PARAM_INOUT}; + struct ParameterDescription { + Identifier name; + TypeCode type; + IDLType type_def; + ParameterMode mode; + }; + typedef sequence <ParameterDescription> ParDescriptionSeq; + + typedef Identifier ContextIdentifier; + typedef sequence <ContextIdentifier> ContextIdSeq; + + typedef sequence <ExceptionDef> ExceptionDefSeq; + typedef sequence <ExceptionDescription> ExcDescriptionSeq; + + interface OperationDef : Contained { + readonly attribute TypeCode result; + attribute IDLType result_def; + attribute ParDescriptionSeq params; + attribute OperationMode mode; + attribute ContextIdSeq contexts; + attribute ExceptionDefSeq exceptions; + }; + + struct OperationDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + TypeCode result; + OperationMode mode; + ContextIdSeq contexts; + ParDescriptionSeq parameters; + ExcDescriptionSeq exceptions; + }; + + + + typedef sequence <RepositoryId> RepositoryIdSeq; + typedef sequence <OperationDescription> OpDescriptionSeq; + typedef sequence <AttributeDescription> AttrDescriptionSeq; + + interface InterfaceDef : Container, Contained, IDLType { + // read/write interface + + attribute InterfaceDefSeq base_interfaces; + + // read interface + + boolean is_a (in RepositoryId interface_id); + + struct FullInterfaceDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + OpDescriptionSeq operations; + AttrDescriptionSeq attributes; + RepositoryIdSeq base_interfaces; + TypeCode type; + }; + + FullInterfaceDescription describe_interface(); + + // write interface + + AttributeDef create_attribute ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in IDLType type, + in AttributeMode mode + ); + + OperationDef create_operation ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in IDLType result, + in OperationMode mode, + in ParDescriptionSeq params, + in ExceptionDefSeq exceptions, + in ContextIdSeq contexts + ); + }; + + struct InterfaceDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + RepositoryIdSeq base_interfaces; + }; + + + + enum TCKind { + tk_null, tk_void, + tk_short, tk_long, tk_ushort, tk_ulong, + tk_float, tk_double, tk_boolean, tk_char, + tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref, + tk_struct, tk_union, tk_enum, tk_string, + tk_sequence, tk_array, tk_alias, tk_except + }; + + interface TypeCode { // PIDL + exception Bounds {}; + exception BadKind {}; + + // for all TypeCode kinds + boolean equal (in TypeCode tc); + TCKind kind (); + + // for tk_objref, tk_struct, tk_union, tk_enum, tk_alias, and tk_except + RepositoryId id () raises (BadKind); + + // for tk_objref, tk_struct, tk_union, tk_enum, tk_alias, and tk_except + Identifier name () raises (BadKind); + + // for tk_struct, tk_union, tk_enum, and tk_except + unsigned long member_count () raises (BadKind); + Identifier member_name (in unsigned long index) raises (BadKind, Bounds); + + // for tk_struct, tk_union, and tk_except + TypeCode member_type (in unsigned long index) raises (BadKind, Bounds); + + // for tk_union + any member_label (in unsigned long index) raises (BadKind, Bounds); + TypeCode discriminator_type () raises (BadKind); + long default_index () raises (BadKind); + + // for tk_string, tk_sequence, and tk_array + unsigned long length () raises (BadKind); + + // for tk_sequence, tk_array, and tk_alias + TypeCode content_type () raises (BadKind); + + // deprecated interface + long param_count (); + any parameter (in long index) raises (Bounds); + }; + + + /* + * following line added by Christian Blum + */ + interface BOA; + + interface ORB { + // other operations ... + + TypeCode create_struct_tc ( + in RepositoryId id, + in Identifier name, + in StructMemberSeq members + ); + + TypeCode create_union_tc ( + in RepositoryId id, + in Identifier name, + in TypeCode discriminator_type, + in UnionMemberSeq members + ); + + TypeCode create_enum_tc ( + in RepositoryId id, + in Identifier name, + in EnumMemberSeq members + ); + + TypeCode create_alias_tc ( + in RepositoryId id, + in Identifier name, + in TypeCode original_type + ); + + TypeCode create_exception_tc ( + in RepositoryId id, + in Identifier name, + in StructMemberSeq members + ); + + TypeCode create_interface_tc ( + in RepositoryId id, + in Identifier name + ); + + TypeCode create_string_tc ( + in unsigned long bound + ); + + TypeCode create_sequence_tc ( + in unsigned long bound, + in TypeCode element_type + ); + + TypeCode create_recursive_sequence_tc ( + in unsigned long bound, + in unsigned long offset + ); + + TypeCode create_array_tc ( + in unsigned long length, + in TypeCode element_type + ); + + /* + * following line commented out by Christian Blum + */ + // }; + + // The ORB interface (PIDL) is described in Chapter 7, CORBA V2.0 July 1995 + // Object interface (object reference operations): pg 7-3 CORBA V2, 7-95 + // ORB initialization: pg 7-7 CORBA V2, 7-95 + // Object Adapter and Basic Object Adapter initialization: pg 7-8 CORBA V2 7-95 + // Getting initial references: pg 7-10 CORBA V2 7-95 + //PIDL + + /* + * following line commented out by Christian Blum + */ + //interface ORB { + + + string object_to_string (in Object obj); + Object string_to_object (in string str); + + Status create_list ( + in long count, + out NVList new_list + ); + Status create_operation_list ( + in OperationDef oper, + out NVList new_list + ); + Status get_default_context (out Context ctx); + + // Initializing the ORB + typedef string ORBid; + typedef sequence <string> arg_list; + ORB ORB_init (inout arg_list argv, in ORBid orb_identifier); + + // Initializing an object adapter and the Basic Object Adapter + typedef string OAid; + + // Template for OA initialization operations + // <OA> <OA>_init (inout arg_list argv, + // in OAid oa_identifier); + + + + BOA BOA_init (inout arg_list argv, + in OAid boa_identifier); + + + + // Getting initial object references + typedef string ObjectId; + typedef sequence <ObjectId> ObjectIdList; + + exception InvalidName {}; + + ObjectIdList list_initial_services (); + + Object resolve_initial_references (in ObjectId identifier) + raises (InvalidName); + }; + + // had to be changed..., Gerald Brose 1996 + interface ORBject { + + ImplementationDef get_implementation (); + InterfaceDef get_interface (); + boolean is_nil(); + Object duplicate (); + void release (); + boolean is_a (in string logical_type_id); + boolean non_existent(); + boolean is_equivalent (in Object other_object); + unsigned long hash(in unsigned long maximum); + + + Status create_request ( + in Context ctx, + in Identifier operation, + in NVList arg_list, + inout NamedValue result, + out Request request, + in Flags req_flags + ); + }; + + + // Basic Object Adapter interface described in Chapter 8, CORBA V2.0, July 1995 + // interface InterfaceDef; // from Interface Repository // PIDL + // interface ImplementationDef; // from Implementation Repository + // interface Object; // an object reference + // interface Principal; // for the authentication service + typedef sequence <octet, 1024> ReferenceData; + + interface BOA { + Object create ( + in ReferenceData id, + in InterfaceDef intf, + in ImplementationDef impl + ); + void dispose (in Object obj); + ReferenceData get_id (in Object obj); + + void change_implementation (in Object obj, + in ImplementationDef impl + ); + + Principal get_principal (in Object obj, + in Environment ev + ); + + void set_exception (in exception_type major, // NO, USER, + //or SYSTEM_EXCEPTION + in string userid, // exception type id + in any param_LOOK_AT_SOURCE + // in void *param // pointer to associated data + ); + + void impl_is_ready (in ImplementationDef impl); + void deactivate_impl (in ImplementationDef impl); + void obj_is_ready (in Object obj, in ImplementationDef impl); + void deactivate_obj (in Object obj); + }; +}; + +// IOP module described in chap 10 CORBA V2, 7-95 +module IOP{ // IDL + // + // Standard Protocol Profile tag values + // + typedef unsigned long ProfileId; + const ProfileId TAG_INTERNET_IOP = 0; + const ProfileId TAG_MULTIPLE_COMPONENTS = 1; + + struct TaggedProfile { + ProfileId tag; + sequence <octet> profile_data; + }; + + // + // an Interoperable Object Reference is a sequence of + // object-specific protocol profiles, plus a type ID. + // + struct IOR { + string type_id; + sequence <TaggedProfile> profiles; + }; + + // + // Standard way of representing multicomponent profiles. + // This would be encapsulated in a TaggedProfile. + // + typedef unsigned long ComponentId; + struct TaggedComponent { + ComponentId tag; + sequence <octet> component_data; + }; + typedef sequence <TaggedComponent> MultipleComponentProfile; + + + typedef unsigned long ServiceID; + + struct ServiceContext { + ServiceID context_id; + sequence <octet> context_data; + }; + typedef sequence <ServiceContext> ServiceContextList; + + const ServiceID TransactionService = 0; + + + +}; +// GIOP module described in CORBA V2, 7-95 chap 12 +// Complete IDL for GIOP module in CORBA +// V2.0, 7-95 p 10-29 +// GIOP message header: CORBA V2, 7-95 p 12-16 +// GIOP request header: CORBA V2, 7-95 p 12-17 +// GIOP reply header: CORBA V2, 7-95 p 12-19 +// GIOP cancel request and locate request: CORBA V2, 7-95 pp 12-20 -- 12-21 +// GIOP locate reply: CORBA V2, 7-95 p 12-22 +module GIOP { // IDL + enum MsgType { + Request, Reply, CancelRequest, + LocateRequest, LocateReply, + CloseConnection, MessageError + }; + + struct Version { + char major; + char minor; + }; + + struct MessageHeader { + char magic [4]; + Version GIOP_version; + boolean byte_order; + octet message_type; + unsigned long message_size; + }; + + struct RequestHeader { + ::IOP::ServiceContextList service_context; + unsigned long request_id; + boolean response_expected; + sequence <octet> object_key; + string operation; + + /* + * ::CORBA:: added for correct scope + */ + ::CORBA::Principal requesting_principal; + }; + + enum ReplyStatusType { + NO_EXCEPTION, + USER_EXCEPTION, + SYSTEM_EXCEPTION, + LOCATION_FORWARD + }; + + struct ReplyHeader { + ::IOP::ServiceContextList service_context; + unsigned long request_id; + ReplyStatusType reply_status; + }; + + struct CancelRequestHeader { + unsigned long request_id; + }; + + struct LocateRequestHeader { + unsigned long request_id; + sequence <octet> object_key; + }; + + enum LocateStatusType { + UNKNOWN_OBJECT, + OBJECT_HERE, + OBJECT_FORWARD + }; + + struct LocateReplyHeader { + unsigned long request_id; + LocateStatusType locate_status; + }; +}; +// IIOP module described in CORBA V2, 7-95 chap 12 +// Complete IDL for IIOP module: CORBA V2, 7-95 p 12-31 +module IIOP { // IDL + struct Version { + char major; + char minor; + }; + + struct ProfileBody { + Version iiop_version; + string host; + unsigned short port; + sequence <octet> object_key; + }; +}; +// DCE CIOP module described in CORBA V2, 7-95 chap 13 +// IDL for DCE CIOP module: CORBA V2, 7-95 p 13-2 +module DCE_CIOP { + struct InvokeRequestHeader { + boolean byte_order; + ::IOP::ServiceContextList service_context; + sequence <octet> object_key; + string endpoint_id; + string operation; + ::CORBA::Principal principal; + sequence <string> client_context; + + // in and inout parameters follow + }; + enum InvokeResponseStatus { + INVOKE_NO_EXCEPTION, + INVOKE_USER_EXCEPTION, + INVOKE_SYSTEM_EXCEPTION, + INVOKE_LOCATION_FORWARD, + INVOKE_TRY_AGAIN + }; + + struct InvokeResponseHeader { + boolean byte_order; + ::IOP::ServiceContextList service_context; + InvokeResponseStatus status; + + // if status = INVOKE_NO_EXCEPTION, + // result then inouts and outs follow + + // if status = INVOKE_USER_EXCEPTION or + // INVOKE_SYSTEM_EXCEPTION, an exception follows + + // if status = INVOKE_LOCATION_FORWARD, an + // ::IOP::MultipleComponentsProfile follows + }; + + struct LocateRequestHeader { + boolean byte_order; + sequence <octet> object_key; + string endpoint_id; + string operation; + + // no body follows + }; + + module IOP { + + /* + * ::IOP:: added to get the right scope + */ + const ::IOP::ComponentId TAG_OBJECT_KEY = 10; + const ::IOP::ComponentId TAG_ENDPOINT_ID = 11; + const ::IOP::ComponentId TAG_LOCATION_POLICY = 12; + // illegal IDL + /* const octet LOCATE_NEVER = 0; + const octet LOCATE_OBJECT = 1; + const octet LOCATE_OPERATION = 2; + const octet LOCATE_ALWAYS = 3; + */ + }; +}; + +#endif diff --git a/lib/ic/test/ic_SUITE_data/Coss.idl b/lib/ic/test/ic_SUITE_data/Coss.idl new file mode 100644 index 0000000000..c84d4a8247 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/Coss.idl @@ -0,0 +1,1537 @@ +// This file contains OMG IDL and PIDL for the Common Object Services. +// CosNaming Module, p 3-6 CORBAservices, Naming Service V1.0, 3/94 + +// A few minor changes for the JacORB distribution: +// +// added am enclosing COSS module and changed scoped names accordingly +// +// corrected a few syntax errors +// +// commented out: +// #includes +// forward declaration of Object + +#include "Corba.idl" + +module COSS { + +module CosNaming { + + typedef string Istring; + struct NameComponent { + Istring id; + Istring kind; + }; + + typedef sequence <NameComponent> Name; + + enum BindingType {nobject, ncontext}; + + struct Binding { + Name binding_name; + BindingType binding_type; + }; + + typedef sequence <Binding> BindingList; + interface BindingIterator; + + interface NamingContext { + + enum NotFoundReason { missing_node, not_context, not_object}; + + exception NotFound { + NotFoundReason why; + Name rest_of_name; + }; + + exception CannotProceed { + NamingContext cxt; + Name rest_of_name; + }; + + exception InvalidName{}; + exception AlreadyBound {}; + exception NotEmpty{}; + + void bind(in Name n, in Object obj) + raises(NotFound, CannotProceed, InvalidName, AlreadyBound); + void rebind(in Name n, in Object obj) + raises(NotFound, CannotProceed, InvalidName); + void bind_context(in Name n, in NamingContext nc) + raises(NotFound, CannotProceed, InvalidName, AlreadyBound); + void rebind_context(in Name n, in NamingContext nc) + raises(NotFound, CannotProceed, InvalidName); + Object resolve (in Name n) + raises(NotFound, CannotProceed, InvalidName); + void unbind(in Name n) + raises(NotFound, CannotProceed, InvalidName); + NamingContext new_context(); + NamingContext bind_new_context(in Name n) + raises(NotFound, AlreadyBound, CannotProceed, InvalidName); + void destroy( ) + raises(NotEmpty); + void list (in unsigned long how_many, + out BindingList bl, out BindingIterator bi); + }; + + interface BindingIterator { + boolean next_one(out Binding b); + boolean next_n(in unsigned long how_many, + out BindingList bl); + void destroy(); + }; +}; + +// Names Library interface in PIDL, CORBAservices p 3- 14, Naming Service V1.0 3/94 +/* +interface LNameComponent { // PIDL + exception NotSet{}; + string get_id() + raises(NotSet); + void set_id(in string i); + string get_kind() + raises(NotSet); + void set_kind(in string k); + void destroy(); +}; + +interface LName { // PIDL + exception NoComponent{}; + exception OverFlow{}; + exception InvalidName{}; + LName insert_component(in unsigned long i, + in LNameComponent n) + raises(NoComponent, OverFlow); + LNameComponent get_component(in unsigned long i) + raises(NoComponent); + LNameComponent delete_component(in unsigned long i) + raises(NoComponent); + unsigned long num_components(); + boolean equal(in LName ln); + boolean less_than(in LName ln); + Name to_idl_form() + raises(InvalidName); + void from_idl_form(in Name n); + void destroy(); +}; + +LName create_lname(); // C/C++ +LNameComponent create_lname_component(); // C/C++ +*/ + +// CosEventComm Module, CORBAservices p 4-8, Event Service V1.0 3/94 + +module CosEventComm { + + exception Disconnected{}; + + interface PushConsumer { + void push (in any data) raises(Disconnected); + void disconnect_push_consumer(); + }; + + interface PushSupplier { + void disconnect_push_supplier(); + }; + + interface PullSupplier { + any pull () raises(Disconnected); + any try_pull (out boolean has_event) + raises(Disconnected); + void disconnect_pull_supplier(); + }; + + interface PullConsumer { + void disconnect_pull_consumer(); + }; + +}; + +// CosEventChannelAdmin Module, p 4-15 CORBAservices, Event +// Service V1.0, 3/94 + +// #include "CosEventComm.idl" + +module CosEventChannelAdmin { + + exception AlreadyConnected {}; + exception TypeError {}; + + interface ProxyPushConsumer: ::COSS::CosEventComm::PushConsumer { + void connect_push_supplier( + in ::COSS::CosEventComm::PushSupplier push_supplier) + raises(AlreadyConnected); + }; + + interface ProxyPullSupplier: ::COSS::CosEventComm::PullSupplier { + void connect_pull_consumer( + in ::COSS::CosEventComm::PullConsumer pull_consumer) + raises(AlreadyConnected); + }; + + interface ProxyPullConsumer: ::COSS::CosEventComm::PullConsumer { + void connect_pull_supplier( + in ::COSS::CosEventComm::PullSupplier pull_supplier) + raises(AlreadyConnected,TypeError); + }; + + interface ProxyPushSupplier: ::COSS::CosEventComm::PushSupplier { + void connect_push_consumer( + in ::COSS::CosEventComm::PushConsumer + push_consumer) + raises(AlreadyConnected, TypeError); + }; + + + interface ConsumerAdmin { + ProxyPushSupplier obtain_push_supplier(); + ProxyPullSupplier obtain_pull_supplier(); + }; + + interface SupplierAdmin { + ProxyPushConsumer obtain_push_consumer(); + ProxyPullConsumer obtain_pull_consumer(); + }; + + interface EventChannel { + ConsumerAdmin for_consumers(); + SupplierAdmin for_suppliers(); + void destroy(); + }; + +}; + + +// CosTyped Event Module, p 4-22 CORBAservices, Event Service +// V1.0, 3/94 + +// // #include "CosEventComm.idl" + +module CosTypedEventComm { + + interface TypedPushConsumer : ::COSS::CosEventComm::PushConsumer { + Object get_typed_consumer(); + }; + + interface TypedPullSupplier : ::COSS::CosEventComm::PullSupplier { + Object get_typed_supplier(); + }; + +}; + +// CosTypedEventChannelAdmin Module, p 4- 25 CORBAservices, +// Event Service V1.0, 3/94 + +// // #include "CosEventChannel.idl" +// // #include "CosTypedEventComm.idl" +module CosTypedEventChannelAdmin { + exception InterfaceNotSupported {}; + exception NoSuchImplementation {}; + typedef string Key; + + interface TypedProxyPushConsumer : + ::COSS::CosEventChannelAdmin::ProxyPushConsumer, + ::COSS::CosTypedEventComm::TypedPushConsumer { }; + + interface TypedProxyPullSupplier : + ::COSS::CosEventChannelAdmin::ProxyPullSupplier, + ::COSS::CosTypedEventComm::TypedPullSupplier { }; + + interface TypedSupplierAdmin : + ::COSS::CosEventChannelAdmin::SupplierAdmin { + TypedProxyPushConsumer obtain_typed_push_consumer( + in Key supported_interface) + raises(InterfaceNotSupported); + ::COSS::CosEventChannelAdmin::ProxyPullConsumer obtain_typed_pull_consumer ( + in Key uses_interface) + raises(NoSuchImplementation); + }; + + interface TypedConsumerAdmin : + ::COSS::CosEventChannelAdmin::ConsumerAdmin { + TypedProxyPullSupplier obtain_typed_pull_supplier( + in Key supported_interface) + raises (InterfaceNotSupported); + ::COSS::CosEventChannelAdmin::ProxyPushSupplier obtain_typed_push_supplier( + in Key uses_interface) + raises(NoSuchImplementation); + }; + + interface TypedEventChannel { + TypedConsumerAdmin for_consumers(); + TypedSupplierAdmin for_suppliers(); + void destroy (); + }; +}; + + +// CosPersistencePID Module, p 5-20 CORBAservices, +// Persistent Object Service V1.0, 3/94 + +//#ifndef __COSPERSISTENCE +//#define __COSPERSISTENCE + +module CosPersistencePID { + + interface PID { + attribute string datastore_type; + string get_PIDString(); + }; +}; + + +// CosPersistencePDS Module, p 5-20 CORBAservices, +// Persistent Object Service V1.0, 3/94 + +// #include "CosPersistencePID.idl" + +module CosPersistencePDS { + +// interface Object; + interface PDS { + PDS connect (in Object obj, + in ::COSS::CosPersistencePID::PID p); + void disconnect (in Object obj, + in ::COSS::CosPersistencePID::PID p); + void store (in Object obj, + in ::COSS::CosPersistencePID::PID p); + void restore (in Object obj, + in ::COSS::CosPersistencePID::PID p); + void delete (in Object obj, + in ::COSS::CosPersistencePID::PID p); + }; +}; + + +// CosPersistencePO Module, p 5-12 CORBAservices, +// Persistent Object Service V1.0, 3/94 + +// // #include "CosPersistencePDS.idl" +// CosPersistencePDS.idl +// // #includes CosPersistencePID.idl + +module CosPersistencePO { + + interface PO { + attribute ::COSS::CosPersistencePID::PID p; + ::COSS::CosPersistencePDS::PDS connect ( + in ::COSS::CosPersistencePID::PID p); + void disconnect (in ::COSS::CosPersistencePID::PID p); + void store (in ::COSS::CosPersistencePID::PID p); + void restore (in ::COSS::CosPersistencePID::PID p); + void delete (in ::COSS::CosPersistencePID::PID p); + }; + + interface SD { + void pre_store(); + void post_restore(); + }; +}; + + +// CosPersistencePOM Module, p 5-15 CORBAservices, +// Persistent Object Service V1.0, 3/94 + +// #include "CosPersistencePDS.idl" + +// CosPersistencePDS.idl // #includes CosPersistencePID.idl + +module CosPersistencePOM { + +// interface Object; + + interface POM { + ::COSS::CosPersistencePDS::PDS connect ( + in Object obj, + in ::COSS::CosPersistencePID::PID p); + void disconnect ( + in Object obj, + in ::COSS::CosPersistencePID::PID p); + void store ( + in Object obj, + in ::COSS::CosPersistencePID::PID p); + void restore ( + in Object obj, + in ::COSS::CosPersistencePID::PID p); + void delete ( + in Object obj, + in ::COSS::CosPersistencePID::PID p); + }; + }; + +// CosPersistencePDS_DA Module, p 5-22 CORBAservices, +// Persistent Object Service, V1.0, 3/94 + +// #include "CosPersistencePDS.idl" +// CosPersistencePDS.idl // #includes CosPersistencePID.idl + +module CosPersistencePDS_DA { + + typedef string DAObjectID; + + interface PID_DA : ::COSS::CosPersistencePID::PID { + attribute DAObjectID oid; + }; + + interface DAObject { + boolean dado_same(in DAObject d); + DAObjectID dado_oid(); + PID_DA dado_pid(); + void dado_remove(); + void dado_free(); + }; + + interface DAObjectFactory { + DAObject create(); + }; + + interface DAObjectFactoryFinder { + DAObjectFactory find_factory(in string key); + }; + + interface PDS_DA : ::COSS::CosPersistencePDS::PDS { + DAObject get_data(); + void set_data(in DAObject new_data); + DAObject lookup(in DAObjectID id); + PID_DA get_pid(); + PID_DA get_object_pid(in DAObject dao); + DAObjectFactoryFinder data_factories(); + }; + + typedef sequence<string> AttributeNames; + interface DynamicAttributeAccess { + AttributeNames attribute_names(); + any attribute_get(in string name); + void attribute_set(in string name, in any value); + }; + + typedef string ClusterID; + typedef sequence<ClusterID> ClusterIDs; + interface PDS_ClusteredDA : PDS_DA{ + ClusterID cluster_id(); + string cluster_kind(); + ClusterIDs clusters_of(); + PDS_ClusteredDA create_cluster(in string kind); + PDS_ClusteredDA open_cluster(in ClusterID cluster); + PDS_ClusteredDA copy_cluster( + in PDS_DA source); + }; +}; + +// CosPersistenceDDO Module, p 5-32 CORBAservices, Persistent Object Service V1.0, 3/94 + +// #include "CosPersistencePID.idl" +module CosPersistenceDDO { + + interface DDO { + attribute string object_type; + attribute ::COSS::CosPersistencePID::PID p; + short add_data(); + short add_data_property (in short data_id); + short get_data_count(); + short get_data_property_count (in short data_id); + void get_data_property (in short data_id, + in short property_id, + out string property_name, + out any property_value); + void set_data_property (in short data_id, + in short property_id, + in string property_name, + in any property_value); + void get_data (in short data_id, + out string data_name, + out any data_value); + void set_data (in short data_id, + in string data_name, + in any data_value); + }; +}; + +// CosPersistenceDS_CLI module, p 5-34 CORBAservices, +// Persistent Object Service V1.0, 3/94 + +// #include "CosPersistenceDDO.idl" +// CosPersistenceDDO.idl // #includes CosPersistencePID.idl + +module CosPersistenceDS_CLI { + interface UserEnvironment { + void set_option (in long option,in any value); + void get_option (in long option,out any value); + void release(); + }; + + interface Connection { + void set_option (in long option,in any value); + void get_option (in long option,out any value); + }; + + interface ConnectionFactory { + Connection create_object ( + in UserEnvironment user_envir); + }; + + interface Cursor { + void set_position (in long position,in any value); + ::COSS::CosPersistenceDDO::DDO fetch_object(); + }; + + interface CursorFactory { + Cursor create_object ( + in Connection connection); + }; + + interface PID_CLI : ::COSS::CosPersistencePID::PID { + attribute string datastore_id; + attribute string id; + }; + + + + interface Datastore_CLI { + void connect (in Connection connection, + in string datastore_id, + in string user_name, + in string authentication); + void disconnect (in Connection connection); + Connection get_connection ( + in string datastore_id, + in string user_name); + void add_object (in Connection connection, + in ::COSS::CosPersistenceDDO::DDO data_obj); + void delete_object ( + in Connection connection, + in ::COSS::CosPersistenceDDO::DDO data_obj); + void update_object ( + in Connection connection, + in ::COSS::CosPersistenceDDO::DDO data_obj); + void retrieve_object( + in Connection connection, + in ::COSS::CosPersistenceDDO::DDO data_obj); + Cursor select_object( + in Connection connection, + in string key); + void transact (in UserEnvironment user_envir, + in short completion_type); + void assign_PID (in PID_CLI p); + void assign_PID_relative ( + in PID_CLI source_pid, + in PID_CLI target_pid); + boolean is_identical_PID ( + in PID_CLI pid_1, + in PID_CLI pid_2); + string get_object_type (in PID_CLI p); + void register_mapping_schema (in string schema_file); + Cursor execute (in Connection connection, + in string command); + }; + +}; + + +// CosLifeCycle Module, p 6-10 CORBAservices, LifeCycle Service V1.0, 3/94 + +// #include "Naming.idl" + +module CosLifeCycle +{ + typedef ::COSS::CosNaming::Name Key; + typedef Object Factory; + typedef sequence <Factory> Factories; + typedef struct NVP { + ::COSS::CosNaming::Istring name; + any value; + } NameValuePair; + typedef sequence <NameValuePair> Criteria; + + exception NoFactory { + Key search_key; + }; + exception NotCopyable { string reason; }; + exception NotMovable { string reason; }; + exception NotRemovable { string reason; }; + exception InvalidCriteria{ + Criteria invalid_criteria; + }; + exception CannotMeetCriteria { + Criteria unmet_criteria; + }; + + + interface FactoryFinder { + Factories find_factories(in Key factory_key) + raises(NoFactory); + }; + + interface LifeCycleObject { + LifeCycleObject copy(in FactoryFinder there, + in Criteria the_criteria) + raises(NoFactory, NotCopyable, InvalidCriteria, + CannotMeetCriteria); + void move(in FactoryFinder there, + in Criteria the_criteria) + raises(NoFactory, NotMovable, InvalidCriteria, + CannotMeetCriteria); + void remove() + raises(NotRemovable); + }; + + interface GenericFactory { + boolean supports(in Key k); + Object create_object( + in Key k, + in Criteria the_criteria) + raises (NoFactory, InvalidCriteria, + CannotMeetCriteria); + }; +}; + + + +// LifeCycleService Module, p 6- 55 CORBAservices, Life Cycle +// Service V1.0, 3/94 + +// #include "LifeCycle.idl" + +module LifeCycleService { + + typedef sequence <::COSS::CosLifeCycle::NameValuePair> PolicyList; + typedef sequence <::COSS::CosLifeCycle::Key> Keys; + typedef sequence <::COSS::CosLifeCycle::NameValuePair> PropertyList; + typedef sequence <::COSS::CosNaming::NameComponent> NameComponents; + + interface LifeCycleServiceAdmin { + + attribute PolicyList policies; + + void bind_generic_factory( + in ::COSS::CosLifeCycle::GenericFactory gf, + in ::COSS::CosNaming::NameComponent name, + in Keys key_set, + in PropertyList other_properties) + raises (::COSS::CosNaming::NamingContext::AlreadyBound, ::COSS::CosNaming::NamingContext::InvalidName); + + void unbind_generic_factory( + in ::COSS::CosNaming::NameComponent name) + raises (::COSS::CosNaming::NamingContext::NotFound, ::COSS::CosNaming::NamingContext::InvalidName); + + ::COSS::CosLifeCycle::GenericFactory resolve_generic_factory( + in ::COSS::CosNaming::NameComponent name) + raises (::COSS::CosNaming::NamingContext::NotFound, ::COSS::CosNaming::NamingContext::InvalidName); + + NameComponents list_generic_factories(); + + boolean match_service (in ::COSS::CosLifeCycle::GenericFactory f); + + string get_hint(); + + void get_link_properties( + in ::COSS::CosNaming::NameComponent name, + out Keys key_set, + out PropertyList other_properties) + raises (::COSS::CosNaming::NamingContext::NotFound, ::COSS::CosNaming::NamingContext::InvalidName); + }; +}; + +// CosTransactions Module, p 10-66 +// CORBAservices, Transaction Service V1.0, 3/94 + +module CosTransactions { +// DATATYPES +enum Status { + StatusActive, + StatusMarkedRollback, + StatusPrepared, + StatusCommitted, + StatusRolledBack, + StatusUnknown, + StatusNoTransaction +}; + +enum Vote { + VoteCommit, + VoteRollback, + VoteReadOnly +}; + +// Standard exceptions +exception TransactionRequired {}; +exception TransactionRolledBack {}; +exception InvalidTransaction {}; + +// Heuristic exceptions +exception HeuristicRollback {}; +exception HeuristicCommit {}; +exception HeuristicMixed {}; +exception HeuristicHazard {}; + +// Exception from Orb operations +exception WrongTransaction {}; + +// Other transaction-specific exceptions +exception SubtransactionsUnavailable {}; +exception NotSubtransaction {}; +exception Inactive {}; +exception NotPrepared {}; +exception NoTransaction {}; +exception InvalidControl {}; +exception Unavailable {}; + +// Forward references for interfaces defined later in module +interface Control; +interface Terminator; +interface Coordinator; +interface Resource; +interface RecoveryCoordinator; +interface SubtransactionAwareResource; +interface TransactionFactory; +interface TransactionalObject; +interface Current; + +// Current transaction pseudo object (PIDL) + interface Current { + void begin() + raises(SubtransactionsUnavailable); + void commit(in boolean report_heuristics) + raises( + NoTransaction, + HeuristicMixed, + HeuristicHazard + ); + void rollback() + raises(NoTransaction); + void rollback_only() + raises(NoTransaction); + + Status get_status(); + string get_transaction_name(); + void set_timeout(in unsigned long seconds); + + Control get_control(); + Control suspend(); + void resume(in Control which) + raises(InvalidControl); + }; + + interface TransactionFactory { + Control create(in unsigned long time_out); + }; + + interface Control { + Terminator get_terminator() + raises(Unavailable); + Coordinator get_coordinator() + raises(Unavailable); + }; + + interface Terminator { + void commit(in boolean report_heuristics) + raises( + HeuristicMixed, + HeuristicHazard + ); + void rollback(); + }; + + + interface Coordinator { + + Status get_status(); + Status get_parent_status(); + Status get_top_level_status(); + + boolean is_same_transaction(in Coordinator tc); + boolean is_related_transaction(in Coordinator tc); + boolean is_ancestor_transaction(in Coordinator tc); + boolean is_descendant_transaction(in Coordinator tc); + boolean is_top_level_transaction(); + + unsigned long hash_transaction(); + unsigned long hash_top_level_tran(); + + RecoveryCoordinator register_resource(in Resource r) + raises(Inactive); + + void register_subtran_aware(in SubtransactionAwareResource r) + raises(Inactive, NotSubtransaction); + + void rollback_only() + raises(Inactive); + + string get_transaction_name(); + + Control create_subtransaction() + raises(SubtransactionsUnavailable, Inactive); + }; + + interface RecoveryCoordinator { + Status replay_completion(in Resource r) + raises(NotPrepared); + }; + +}; // end module CosTransactions + + +// CosConcurrency Control Module, p 7-8 CORBAservices, +// Concurrency Control Service V1.0, 3/94 + +// #include <CosTransactions.idl> +module CosConcurrencyControl { + + enum lock_mode { + read, + write, + upgrade, + intention_read, + intention_write + }; + + exception LockNotHeld{}; + + interface LockCoordinator + { + void drop_locks(); + }; + + interface LockSet + { + void lock(in lock_mode mode); + boolean try_lock(in lock_mode mode); + + void unlock(in lock_mode mode) + raises(LockNotHeld); + void change_mode(in lock_mode held_mode, + in lock_mode new_mode) + raises(LockNotHeld); + LockCoordinator get_coordinator( + in ::COSS::CosTransactions::Coordinator which); + }; + + interface TransactionalLockSet + { + void lock(in ::COSS::CosTransactions::Coordinator current, + in lock_mode mode); + boolean try_lock(in ::COSS::CosTransactions::Coordinator current, + in lock_mode mode); + void unlock(in ::COSS::CosTransactions::Coordinator current, + in lock_mode mode) + raises(LockNotHeld); + void change_mode(in ::COSS::CosTransactions::Coordinator current, + in lock_mode held_mode, + in lock_mode new_mode) + raises(LockNotHeld); + LockCoordinator get_coordinator( + in ::COSS::CosTransactions::Coordinator which); + }; + + interface LockSetFactory + { + LockSet create(); + LockSet create_related(in LockSet which); + TransactionalLockSet create_transactional(); + TransactionalLockSet create_transactional_related(in + TransactionalLockSet which); + }; +}; + +// CosObjectIdentity Module, p 9-19 CORBAservices, Relationship +// Service V1.0, 3/94 + + +module CosObjectIdentity { + + typedef unsigned long ObjectIdentifier; + + interface IdentifiableObject { + readonly attribute ObjectIdentifier constant_random_id; + boolean is_identical ( + in IdentifiableObject other_object); + }; + +}; + + +// CosRelationships Module, p 9-21 CORBAservices, Relationship +// Service V1.0, 3/94 + +// #include <ObjectIdentity.idl> + +module CosRelationships { + + interface RoleFactory; + interface RelationshipFactory; + interface Relationship; + interface Role; + interface RelationshipIterator; + + typedef Object RelatedObject; + typedef sequence<Role> Roles; + typedef string RoleName; + typedef sequence<RoleName> RoleNames; + + struct NamedRole {RoleName name; Role aRole;}; + typedef sequence<NamedRole> NamedRoles; + + struct RelationshipHandle { + Relationship the_relationship; + ::COSS::CosObjectIdentity::ObjectIdentifier constant_random_id; + }; + typedef sequence<RelationshipHandle> RelationshipHandles; + + interface RelationshipFactory { + struct NamedRoleType { + RoleName name; + ::CORBA::InterfaceDef named_role_type; + }; + typedef sequence<NamedRoleType> NamedRoleTypes; + readonly attribute ::CORBA::InterfaceDef relationship_type; + readonly attribute unsigned short degree; + readonly attribute NamedRoleTypes named_role_types; + exception RoleTypeError {NamedRoles culprits;}; + exception MaxCardinalityExceeded { + NamedRoles culprits;}; + exception DegreeError {unsigned short required_degree;}; + exception DuplicateRoleName {NamedRoles culprits;}; + exception UnknownRoleName {NamedRoles culprits;}; + + Relationship create (in NamedRoles named_roles) + raises (RoleTypeError, + MaxCardinalityExceeded, + DegreeError, + DuplicateRoleName, + UnknownRoleName); + }; + + interface Relationship : + ::COSS::CosObjectIdentity::IdentifiableObject { + exception CannotUnlink { + Roles offending_roles; + }; + readonly attribute NamedRoles named_roles; + void destroy () raises(CannotUnlink); + }; + + interface Role { + exception UnknownRoleName {}; + exception UnknownRelationship {}; + exception RelationshipTypeError {}; + exception CannotDestroyRelationship { + RelationshipHandles offenders; + }; + exception ParticipatingInRelationship { + RelationshipHandles the_relationships; + }; + readonly attribute RelatedObject related_object; + RelatedObject get_other_related_object ( + in RelationshipHandle rel, + in RoleName target_name) + raises (UnknownRoleName, + UnknownRelationship); + Role get_other_role (in RelationshipHandle rel, + in RoleName target_name) + raises (UnknownRoleName, UnknownRelationship); + void get_relationships ( + in unsigned long how_many, + out RelationshipHandles rels, + out RelationshipIterator iterator); + void destroy_relationships() + raises(CannotDestroyRelationship); + void destroy() raises(ParticipatingInRelationship); + boolean check_minimum_cardinality (); + void link (in RelationshipHandle rel, + in NamedRoles named_roles) + raises(RelationshipFactory::MaxCardinalityExceeded, + RelationshipTypeError); + void unlink (in RelationshipHandle rel) + raises (UnknownRelationship); + }; + + interface RoleFactory { + exception NilRelatedObject {}; + exception RelatedObjectTypeError {}; + readonly attribute ::CORBA::InterfaceDef role_type; + readonly attribute unsigned long max_cardinality; + readonly attribute unsigned long min_cardinality; +// the following isn't allowed in IDL, +// readonly attribute sequence <::CORBA::InterfaceDef> related_object_types; + typedef sequence <::CORBA::InterfaceDef> InterfaceDefSeq; + readonly attribute InterfaceDefSeq related_object_types; + Role create_role (in RelatedObject related_object) + raises (NilRelatedObject, RelatedObjectTypeError); + }; + + interface RelationshipIterator { + boolean next_one (out RelationshipHandle rel); + boolean next_n (in unsigned long how_many, + out RelationshipHandles rels); + void destroy (); + }; + +}; + +// CosCompoundExternalization Module, p 8-20 CORBAservices, +// Externalization Service V1.0, 3/94 + +// #include <Graphs.idl> +// #include <Stream.idl> + +// CosGraphs Module, p 9-39 CORBAservices, Relationship Service +// V1.0, 3/94 + +// #include <Relationships.idl> +// #include <ObjectIdentity.idl> + +module CosGraphs { + + interface TraversalFactory; + interface Traversal; + interface TraversalCriteria; + interface Node; + interface NodeFactory; + interface Role; + interface EdgeIterator; + + struct NodeHandle { + Node the_node; + ::COSS::CosObjectIdentity::ObjectIdentifier constant_random_id; + }; + typedef sequence<NodeHandle> NodeHandles; + + struct NamedRole { + Role the_role; + ::COSS::CosRelationships::RoleName the_name; + }; + typedef sequence<NamedRole> NamedRoles; + + struct EndPoint { + NodeHandle the_node; + NamedRole the_role; + }; + typedef sequence<EndPoint> EndPoints; + + struct Edge { + EndPoint from; + ::COSS::CosRelationships::RelationshipHandle the_relationship; + EndPoints relatives; + }; + typedef sequence<Edge> Edges; + + enum PropagationValue {deep, shallow, none, inhibit}; + enum Mode {depthFirst, breadthFirst, bestFirst}; + + interface TraversalFactory { + Traversal create_traversal_on ( + in NodeHandle root_node, + in TraversalCriteria the_criteria, + in Mode how); + }; + + interface Traversal { + typedef unsigned long TraversalScopedId; + struct ScopedEndPoint { + EndPoint point; + TraversalScopedId id; + }; + typedef sequence<ScopedEndPoint> ScopedEndPoints; + struct ScopedRelationship { + ::COSS::CosRelationships::RelationshipHandle + scoped_relationship; + TraversalScopedId id; + }; + struct ScopedEdge { + ScopedEndPoint from; + ScopedRelationship the_relationship; + ScopedEndPoints relatives; + }; + typedef sequence<ScopedEdge> ScopedEdges; + boolean next_one (out ScopedEdge the_edge); + boolean next_n (in short how_many, + out ScopedEdges the_edges); + void destroy (); + }; + + interface TraversalCriteria { + struct WeightedEdge { + Edge the_edge; + unsigned long weight; + sequence<NodeHandle> next_nodes; + }; + typedef sequence<WeightedEdge> WeightedEdges; + void visit_node(in NodeHandle a_node, + in Mode search_mode); + boolean next_one (out WeightedEdge the_edge); + boolean next_n (in short how_many, + out WeightedEdges the_edges); + void destroy(); + }; + + interface Node: ::COSS::CosObjectIdentity::IdentifiableObject { + typedef sequence<Role> Roles; + exception NoSuchRole {}; + exception DuplicateRoleType {}; + + readonly attribute ::COSS::CosRelationships::RelatedObject + related_object; + readonly attribute Roles roles_of_node; + Roles roles_of_type ( + in ::CORBA::InterfaceDef role_type); + void add_role (in Role a_role) + raises (DuplicateRoleType); + void remove_role (in ::CORBA::InterfaceDef of_type) + raises (NoSuchRole); + }; + + interface NodeFactory { + Node create_node (in Object related_object); + }; + + interface Role : ::COSS::CosRelationships::Role { + void get_edges ( in long how_many, + out Edges the_edges, + out EdgeIterator the_rest); + }; + + interface EdgeIterator { + boolean next_one (out Edge the_edge); + boolean next_n ( in unsigned long how_many, + out Edges the_edges); + void destroy (); + }; + +}; + + + +// CosStream Module, 8-15 CORBAservices, +// Externalization Service V1.0, 3/94 + +// #include <LifeCycle.idl> +// #include <ObjectIdentity.idl> +// #include <CompoundExternalization.idl> +module CosStream { + exception ObjectCreationError{}; + exception StreamDataFormatError{}; + interface StreamIO; + + interface Streamable: ::COSS::CosObjectIdentity::IdentifiableObject + { + readonly attribute ::COSS::CosLifeCycle::Key external_form_id; + void externalize_to_stream( + in StreamIO targetStreamIO); + void internalize_from_stream( + in StreamIO sourceStreamIO, + in ::COSS::CosLifeCycle::FactoryFinder there) + raises( ::COSS::CosLifeCycle::NoFactory, + ObjectCreationError, + StreamDataFormatError ); + }; + + interface StreamableFactory { + Streamable create_uninitialized(); + }; + + + interface StreamIO { + void write_string(in string aString); + void write_char(in char aChar); + void write_octet(in octet anOctet); + void write_unsigned_long( + in unsigned long anUnsignedLong); + void write_unsigned_short( + in unsigned short anUnsignedShort); + void write_long(in long aLong); + void write_short(in short aShort); + void write_float(in float aFloat); + void write_double(in double aDouble); + void write_boolean(in boolean aBoolean); + void write_object(in Streamable aStreamable); + // void write_graph(in ::COSS::CosCompoundExternalization::Node aNode); + string read_string() + raises(StreamDataFormatError); + char read_char() + raises(StreamDataFormatError ); + octet read_octet() + raises(StreamDataFormatError ); + unsigned long read_unsigned_long() + raises(StreamDataFormatError ); + unsigned short read_unsigned_short() + raises( StreamDataFormatError ); + long read_long() + raises(StreamDataFormatError ); + short read_short() + raises(StreamDataFormatError ); + float read_float() + raises(StreamDataFormatError ); + double read_double() + raises(StreamDataFormatError ); + boolean read_boolean() + raises(StreamDataFormatError ); + Streamable read_object( + in ::COSS::CosLifeCycle::FactoryFinder there, + in Streamable aStreamable) + raises(StreamDataFormatError ); +// void read_graph( +// in ::COSS::CosCompoundExternalization::Node starting_node, +// in ::COSS::CosLifeCycle::FactoryFinder there) +// raises(StreamDataFormatError ); + }; +}; + +module CosCompoundExternalization { + interface Node; + interface Role; + interface Relationship; + interface PropagationCriteriaFactory; + + struct RelationshipHandle { + Relationship theRelationship; + ::COSS::CosObjectIdentity::ObjectIdentifier constantRandomId; + }; + + interface Node : ::COSS::CosGraphs::Node, ::COSS::CosStream::Streamable{ + void externalize_node (in ::COSS::CosStream::StreamIO sio); + void internalize_node (in ::COSS::CosStream::StreamIO sio, + in ::COSS::CosLifeCycle::FactoryFinder there, + out ::COSS::CosGraphs::Node::Roles rolesOfNode) + raises (::COSS::CosLifeCycle::NoFactory); + }; + + interface Role : ::COSS::CosGraphs::Role { + void externalize_role (in ::COSS::CosStream::StreamIO sio); + void internalize_role (in ::COSS::CosStream::StreamIO sio); + ::COSS::CosGraphs::PropagationValue externalize_propagation ( + in RelationshipHandle rel, + in ::COSS::CosRelationships::RoleName toRoleName, + out boolean sameForAll); + }; + + interface Relationship : + ::COSS::CosRelationships::Relationship { + void externalize_relationship ( + in ::COSS::CosStream::StreamIO sio); + void internalize_relationship( + in ::COSS::CosStream::StreamIO sio, + in ::COSS::CosGraphs::NamedRoles newRoles); + ::COSS::CosGraphs::PropagationValue externalize_propagation ( + in ::COSS::CosRelationships::RoleName fromRoleName, + in ::COSS::CosRelationships::RoleName toRoleName, + out boolean sameForAll); + }; + + interface PropagationCriteriaFactory { + ::COSS::CosGraphs::TraversalCriteria create_for_externalize( ); + }; + +}; + +// CosExternalization Module, 8-12 CORBAservices, +// Externalization Service V1.0, 3/94 + + +// #include <LifeCycle.idl> +// #include <Stream.idl> +module CosExternalization { + exception InvalidFileNameError{}; + exception ContextAlreadyRegistered{}; + interface Stream: ::COSS::CosLifeCycle::LifeCycleObject{ + void externalize( + in ::COSS::CosStream::Streamable theObject); + ::COSS::CosStream::Streamable internalize( + in ::COSS::CosLifeCycle::FactoryFinder there) + raises( ::COSS::CosLifeCycle::NoFactory, + ::COSS::CosStream::StreamDataFormatError ); + void begin_context() + raises( ContextAlreadyRegistered); + void end_context(); + void flush(); + }; + interface StreamFactory { + Stream create(); + }; + interface FileStreamFactory { + Stream create( + in string theFileName) + raises( InvalidFileNameError ); + }; +}; + +// CosContainment Module, p 9- 48 CORBAservices, Relationship +// Service V1.0, 3/94 + +// #include <Graphs.idl> + +module CosContainment { + + interface Relationship : + ::COSS::CosRelationships::Relationship {}; + + interface ContainsRole : ::COSS::CosGraphs::Role {}; + + interface ContainedInRole : ::COSS::CosGraphs::Role {}; + +}; + +// CosExternalizationContainment Module, p 8-26 CORBAservices, +// Externalization Service V1.0, 3/94 + +// #include <Containment.idl> +// #include <CompoundExternalization.idl> + +module CosExternalizationContainment { + + interface Relationship : + ::COSS::CosCompoundExternalization::Relationship, + ::COSS::CosContainment::Relationship {}; + + interface ContainsRole : + ::COSS::CosCompoundExternalization::Role, + ::COSS::CosContainment::ContainsRole {}; + + interface ContainedInRole : + ::COSS::CosCompoundExternalization::Role, + ::COSS::CosContainment::ContainedInRole {}; +}; + +// CosReference Module, p 9-50 CORBAservices, +// Relationship Service V1.0, 3/94 + +// #include <Graphs.idl> + +module CosReference { + + interface Relationship : + ::COSS::CosRelationships::Relationship {}; + + interface ReferencesRole : ::COSS::CosGraphs::Role {}; + + interface ReferencedByRole : ::COSS::CosGraphs::Role {}; + +}; + +// CosExternalizationReference Module, p 8-28 CORBAservices, +// Externalization Service V1.0, 3/94 + +// #include <Reference.idl> +// #include <CompoundExternalization.idl> + +module CosExternalizationReference { + + interface Relationship : + ::COSS::CosCompoundExternalization::Relationship, + ::COSS::CosReference::Relationship {}; + + interface ReferencesRole : + ::COSS::CosCompoundExternalization::Role, + ::COSS::CosReference::ReferencesRole {}; + + interface ReferencedByRole : + ::COSS::CosCompoundExternalization::Role, + ::COSS::CosReference::ReferencedByRole {}; +}; + +// PIDL for CosTSInteroperation Module, p 10-59 +// CORBAservices, Transaction Service V1.0, 3/94 +module CosTSInteroperation { // PIDL + struct otid_t { + long formatID; /*format identifier. 0 is OSI TP */ + long bequal_length; + sequence <octet> tid; + }; + struct TransIdentity { + ::COSS::CosTransactions::Coordinator coordinator; + ::COSS::CosTransactions::Terminator terminator; + otid_t otid; + }; + struct PropagationContext { + unsigned long timeout; + TransIdentity current; + sequence <TransIdentity> parents; + any implementation_specific_data; + }; +}; + +// PIDL for CosTSPortability Module, p 10-63 +// CORBAservices, Transaction Service V1.0, 3/94 + +module CosTSPortability { // PIDL + typedef long ReqId; + + interface Sender { + void sending_request(in ReqId id, + out ::COSS::CosTSInteroperation::PropagationContext ctx); + void received_reply(in ReqId id, + in ::COSS::CosTSInteroperation::PropagationContext ctx, + in ::CORBA::Environment env); + }; + + interface Receiver { + void received_request(in ReqId id, + in ::COSS::CosTSInteroperation::PropagationContext ctx); + void sending_reply(in ReqId id, + out::COSS::CosTSInteroperation::PropagationContext ctx); + }; +}; + +// CosCompoundLifeCycle Module, p 6-30 CORBAservices, +// Life Cycle Service V1.0, 3/94 + +// #include <LifeCycle.idl> +// #include <Relationships.idl> +// #include <Graphs.idl> + +module CosCompoundLifeCycle { + interface OperationsFactory; + interface Operations; + interface Node; + interface Role; + interface Relationship; + interface PropagationCriteriaFactory; + + enum Operation {copy, move, remove}; + + struct RelationshipHandle { + Relationship the_relationship; + ::COSS::CosObjectIdentity::ObjectIdentifier constant_random_id; + }; + + interface OperationsFactory { + Operations create_compound_operations(); + }; + + interface Operations { + Node copy ( + in Node starting_node, + in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotCopyable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void move ( + in Node starting_node, + in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotMovable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void remove (in Node starting_node) + raises (::COSS::CosLifeCycle::NotRemovable); + void destroy(); + }; + + interface Node : ::COSS::CosGraphs::Node { + exception NotLifeCycleObject {}; + void copy_node ( in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria, + out Node new_node, + out ::COSS::CosGraphs::Node::Roles roles_of_new_node) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotCopyable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void move_node (in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotMovable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void remove_node () + raises (::COSS::CosLifeCycle::NotRemovable); + ::COSS::CosLifeCycle::LifeCycleObject get_life_cycle_object() + raises (NotLifeCycleObject); + }; + + interface Role : ::COSS::CosGraphs::Role { + Role copy_role (in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotCopyable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void move_role (in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotMovable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + ::COSS::CosGraphs::PropagationValue life_cycle_propagation ( + in Operation op, + in RelationshipHandle rel, + in ::COSS::CosRelationships::RoleName to_role_name, + out boolean same_for_all); + }; + + interface Relationship : + ::COSS::CosRelationships::Relationship { + Relationship copy_relationship ( + in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria, + in ::COSS::CosGraphs::NamedRoles new_roles) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotCopyable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void move_relationship ( + in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotMovable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + ::COSS::CosGraphs::PropagationValue life_cycle_propagation ( + in Operation op, + in ::COSS::CosRelationships::RoleName from_role_name, + in ::COSS::CosRelationships::RoleName to_role_name, + out boolean same_for_all); + }; + + interface PropagationCriteriaFactory { + ::COSS::CosGraphs::TraversalCriteria create(in Operation op); + }; + +}; + +// CosLifeCycleContainment Module, p 6-42 CORBAservices, +// Life Cycle Service V1.0, 3/94 + +// #include <Containment.idl> +// #include <CompoundLifeCycle.idl> + +module CosLifeCycleContainment { + + interface Relationship : + ::COSS::CosCompoundLifeCycle::Relationship, + ::COSS::CosContainment::Relationship {}; + + interface ContainsRole : + ::COSS::CosCompoundLifeCycle::Role, + ::COSS::CosContainment::ContainsRole {}; + + interface ContainedInRole : + ::COSS::CosCompoundLifeCycle::Role, + ::COSS::CosContainment::ContainedInRole {}; +}; + +// CosLifeCycleReference Module, p 6-44 CORBAservices, +// Life Cycle Service V1.0, 3/94 + +// #include <Reference.idl> +// #include <CompoundLifeCycle.idl> + +module CosLifeCycleReference { + + interface Relationship : + ::COSS::CosCompoundLifeCycle::Relationship, + ::COSS::CosReference::Relationship {}; + + interface ReferencesRole : + ::COSS::CosCompoundLifeCycle::Role, + ::COSS::CosReference::ReferencesRole {}; + + interface ReferencedByRole : + ::COSS::CosCompoundLifeCycle::Role, + ::COSS::CosReference::ReferencedByRole {}; +}; + + +}; // end module COSS diff --git a/lib/ic/test/ic_SUITE_data/attr.idl b/lib/ic/test/ic_SUITE_data/attr.idl new file mode 100644 index 0000000000..c74223eca6 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/attr.idl @@ -0,0 +1,29 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +interface I1 { + attribute long a1, a2; + attribute char a3; +}; + +interface I2 : I1 { + attribute short a4; + readonly attribute char a5; +}; + diff --git a/lib/ic/test/ic_SUITE_data/c_err1.idl b/lib/ic/test/ic_SUITE_data/c_err1.idl new file mode 100644 index 0000000000..e1bc93dae8 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/c_err1.idl @@ -0,0 +1,63 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// This file forces the bad_tk_match. This triggers when the type of +// the expression does not match the declared type of the constant +// + +const long c1 = TRUE; +const unsigned short c1b= TRUE; +const boolean c2 = +5; +const long c3 = 'c'; +const float c5 = 3; +const unsigned long c6 = -2; // Maybe not checked in compiler or suite + +const boolean c4 = 1 | 2; + + +// Now define some correct constants for use in reference checking + +const long longC = -9; +const short shortC = -9; +const unsigned long ulongC = 1; +const unsigned short ushortC = 0; + +const float floatC = 5.1; +const double doubleC = -2.111; + +const boolean boolC = TRUE; + +const char charC = 'f'; +const string stringC = "hej"; +const string<9> stringCb = "hejdu"; + +// Check the reference errors + +const long c19 = floatC; +const short c20 = doubleC; +const unsigned long c21 = charC; +const unsigned short c22 = stringC; +const float c23 = stringCb; +const double c24 = boolC; +const boolean c25 = longC; +const char c26 = shortC; +const string c27 = ushortC; +const string<9> c28 = ulongC; +const long c29 = 3+floatC; diff --git a/lib/ic/test/ic_SUITE_data/c_err2.idl b/lib/ic/test/ic_SUITE_data/c_err2.idl new file mode 100644 index 0000000000..8dac241c7f --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/c_err2.idl @@ -0,0 +1,30 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Checks bad type of operands +// + + +const long c1 = 1 + TRUE; +const boolean c3 = TRUE | FALSE | 19.8; +const long c4 = 1 << TRUE; +const long c5 = TRUE >> TRUE; + + diff --git a/lib/ic/test/ic_SUITE_data/c_err3.idl b/lib/ic/test/ic_SUITE_data/c_err3.idl new file mode 100644 index 0000000000..dde9539f6f --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/c_err3.idl @@ -0,0 +1,28 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Checks ill-formed expressions (type conflict in operands) +// + + +const long c1 = 5|TRUE; +const long c2 = 5&TRUE; +const long c3 = 5^TRUE; + diff --git a/lib/ic/test/ic_SUITE_data/c_norm.idl b/lib/ic/test/ic_SUITE_data/c_norm.idl new file mode 100644 index 0000000000..6f6ef8ff79 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/c_norm.idl @@ -0,0 +1,163 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Check normal values and expressions for constants +// + +// Integer types +const long co1 = 077; +const long ch1 = 0xf1; +const long ch2 = 0XAB; +const long c1 = 1; +const short c2 = 3; +const unsigned long c3 = 1; +const unsigned short c4 = 3; + +// Unary ops +const long c1hb = -0x1; +const long c1b = -1; +const short c2b = -3; +const long c1c = +1; +const short c2c = +3; +// ~ not supported + +// Check binary ops +const long c1d = 9+1-3; +const long c1hd = 9+1-0xf3; +const short c2d = 7+3; +const short c2e = 7*3; +const long c1e = 1 | 7; +const long c1f = 7 & 9; +const long c1g = (1 | 7) & 9; +const long c1h = 1^7; + +//floats +const float c5 = 1.9; +const double c6 = 1.9; +const float c5b = -1.9; +const double c6b = -1.9; + +// Check type operand casting +const float c5c = 1/(9+2) * 2; +const double c6c = 1.9-1; +//const double c6d = 1; // Does not work yet + +// Booleans and expressions +const boolean c7 = TRUE; +const boolean c7b = FALSE; +const boolean c7c = TRUE | FALSE; +const boolean c7d = TRUE & FALSE; +const boolean c7e = TRUE&TRUE | FALSE&TRUE; +const boolean c7f = TRUE&TRUE ^ FALSE&TRUE; + +// Character and string +const char c8 = 'c'; +const char c8b = '\n'; +const string c9 = "hej"; +const string<9> c9b = "hejdu"; + + +// +// Check that value references work +// + +const long rc1 = c1g; +const long rc1h = c1h + 9; +const short rc2 = c2; +const unsigned long rc3 = c3; +const unsigned short rc4 = c4; + + +const float rc5c = c5c; +const double rc6c = c6c; +const double rc6d = c6c+1.3; + +const boolean rc7 = c7; +const boolean rc7c = c7c | TRUE; + +const char rc8 = c8; +const char rc8b = c8b; +const string rc9 = c9; +const string<9> rc9b = c9b; + + + + +// +// Now check that all typerefs work +// + +typedef long longT; +typedef short shortT; +typedef unsigned long ulongT; +typedef unsigned short ushortT; + +typedef float floatT; +typedef double doubleT; + +typedef char charT; +typedef string stringT; + +typedef boolean booleanT; + +const longT cc1 = 1; +const shortT cc2 = 3; +const ::longT cc1b = -1; +const ::shortT cc2b = -3; + +const floatT cc5 = 1.9; +const doubleT cc6 = 1.9; +const floatT cc5b = -1.9; +const doubleT cc6b = -1.9; +const floatT cc5c = 1/(9+2) * 2; +const doubleT cc6c = 1.9-1; + +const booleanT cc7 = TRUE; +const booleanT cc7b = TRUE; +const booleanT cc7c = TRUE | FALSE; +const booleanT cc7d = TRUE & FALSE; +const booleanT cc7e = TRUE&TRUE | FALSE&TRUE; + + +const charT cc8 = 'c'; +const charT cc8b = '\n'; +const stringT cc9 = "hej"; +const stringT cc9b = "hejdu"; + + +// +// Check value casting +// +const long longC = -9; +const short shortC = -9; +const unsigned long ulongC = 1; +const unsigned short ushortC = 0; + +const float floatC = 5.1; +const double doubleC = -2.111; + +const long c20 = shortC; +const long c21 = ulongC; +const long c22 = ushortC; +const short c23 = ushortC; +const double c34 = floatC; + + + diff --git a/lib/ic/test/ic_SUITE_data/enum.idl b/lib/ic/test/ic_SUITE_data/enum.idl new file mode 100644 index 0000000000..c164e4bf74 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/enum.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + + +enum E1 {kalle, sune}; + +enum E2 { el0, el1, el2, el3, el4, el5, el6, el7, el8, el9, el10, el11, el12, el13, +el14, el15, el16, el17, el18, el19, el20, el21, el22, el23, el24, el25, el26, el27, +el28, el29, el30, el31, el32, el33, el34, el35, el36, el37, el38, el39, el40, el41, +el42, el43, el44, el45, el46, el47, el48, el49, el50, el51, el52, el53, el54, el55, +el56, el57, el58, el59}; + + + + + diff --git a/lib/ic/test/ic_SUITE_data/forward.idl b/lib/ic/test/ic_SUITE_data/forward.idl new file mode 100644 index 0000000000..1e16265af5 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/forward.idl @@ -0,0 +1,34 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Check that forward declarations are handled correctly +// + + +interface i1; + + +interface i1 { + typedef long T; +}; + + +interface i1; + diff --git a/lib/ic/test/ic_SUITE_data/include.idl b/lib/ic/test/ic_SUITE_data/include.idl new file mode 100644 index 0000000000..24022bfa1e --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/include.idl @@ -0,0 +1,30 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Check that errors are given with the correct file name reference + +#include "include2.idl" + + +typedef T1 T7; +typedef long T7; +typedef long T111; + + + diff --git a/lib/ic/test/ic_SUITE_data/include2.idl b/lib/ic/test/ic_SUITE_data/include2.idl new file mode 100644 index 0000000000..2f8f7fd62c --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/include2.idl @@ -0,0 +1,26 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Check that errors are given with the correct file name reference + +#include "include3.idl" + + +typedef T7 T1; + diff --git a/lib/ic/test/ic_SUITE_data/include3.idl b/lib/ic/test/ic_SUITE_data/include3.idl new file mode 100644 index 0000000000..c5f89c6c63 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/include3.idl @@ -0,0 +1,25 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Check that errors are given with the correct file name reference + +typedef T7 T1; + + + diff --git a/lib/ic/test/ic_SUITE_data/inherit.idl b/lib/ic/test/ic_SUITE_data/inherit.idl new file mode 100644 index 0000000000..71b79c8748 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/inherit.idl @@ -0,0 +1,68 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + + +interface I1 { + typedef long T1; + typedef struct S1 {long a; boolean b;} T2; + typedef string StringT, StringT_arr[10]; + + T1 op1( in StringT a, inout char b, out StringT_arr c ); + T2 op2( in char a, inout char b, out StringT_arr c ); + + const T1 LongC = 10; + const StringT StringC = "Hola bambino"; + +}; + + +interface I2 : I1 { + T1 op3( in long a); + + const long c1 = LongC; + const string c2 = StringC; +}; + +interface I3 : I1 {}; + +interface I4 : I3, I2 {}; // Check that branced inherit works + + + +// Now use cnstants to check that inheritance works as expected + +module m1 { + interface I1 { + typedef long T1; + + const T1 c1 = 9; + }; + + interface I2 : I1 { + const T1 c2 = c1+5; // c2 = 14 + const long c3 = c2+c1+4; // c3 = 27 + }; + + interface I3 : I2, I1 { + const long c1 = 50; // Overrides I1::c1 + const T1 c4 = c1+c2+c3; // c4=91 + const T1 c5 = I1::c1+c1+c2+c3; // 100 + }; +}; + diff --git a/lib/ic/test/ic_SUITE_data/inherit_err.idl b/lib/ic/test/ic_SUITE_data/inherit_err.idl new file mode 100644 index 0000000000..4cfc3ffbff --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/inherit_err.idl @@ -0,0 +1,71 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Ops and attributes must not be redefined (shadowed) + +interface I1 { + long op1( in long a, inout char b, out boolean c ); + long op2( in char a, inout char b, out boolean c ); + attribute long a1, a2; + readonly attribute char a3; +}; + +interface I2 : I1 { + long op1( in float a, inout char b, out boolean c ); + long op2( in char a, inout char b, out boolean c ); + attribute long a1, a2; + readonly attribute char a3; +}; + +interface I3 : I1 { + long op3 (in string<19> b); +}; + + +interface I4 : I3 { + long op1( in float a, inout char b, out boolean c ); + long op2( in char a, inout char b, out boolean c ); + attribute long a1, a2; + readonly attribute char a3; + + long op3 (in string<19> b); +}; + + +interface I11 { + long op1( in float a, inout char b, out boolean c ); + long op2( in char a, inout char b, out boolean c ); + attribute long a1, a2; + readonly attribute char a3; +}; + + + +interface I5 : I1, I11 {}; + +interface I6 : I1 { + const long op1=0; + const long op2=0; + const long a1=0; + const long a2=0; + const long a3=0; +}; + + diff --git a/lib/ic/test/ic_SUITE_data/inherit_warn.idl b/lib/ic/test/ic_SUITE_data/inherit_warn.idl new file mode 100644 index 0000000000..502bfac8d4 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/inherit_warn.idl @@ -0,0 +1,64 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Checks that shadow warnings comes out as expected +// + + +interface I1 { + typedef long T1; + typedef struct S1 {long a; boolean b;} T2; + typedef string StringT, StringT_arr[10]; + + T1 op1( in StringT a, inout char b, out StringT_arr c ); + T2 op2( in char a, inout char b, out StringT_arr c ); + + const T1 LongC = 10; + const StringT StringC = "Hola bambino"; + +}; + + +interface I2 : I1 { + typedef char T1; // Shadows I1::T1 + const boolean StringC = FALSE; // shadows I1::StringC + + T1 op3( in long a); + + const long c1 = LongC; + const boolean c2 = StringC; +}; + +interface I3 : I2 {}; // More shadows + +interface I4 : I1 { + T1 op4(); + const T1 c2 = 66; +}; + +interface I5 : I4 { + typedef string T1; // Shadows I1::T1 + const char LongC = 'a'; // Shadows I1::LongC +}; + + +interface I6 : I4, I3 { +}; + diff --git a/lib/ic/test/ic_SUITE_data/mult_ids.idl b/lib/ic/test/ic_SUITE_data/mult_ids.idl new file mode 100644 index 0000000000..46deaa9f55 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/mult_ids.idl @@ -0,0 +1,92 @@ + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// +// Check that multiply defined identifiers are detected +// + +typedef long T1; +typedef long T1; +typedef long T2; +exception T2 {}; + + +//Exceptions +exception Exc1 {}; +exception Exc1 {}; + + +// Enums +enum E1 {kalle}; +enum E1 {kalle}; +enum E2 {kalle, sune, kalle}; + + +// Structs +struct S1 {long a;}; +struct S1 {long a;}; +struct S2 {long a; short a;}; +struct S3 {long a,b; short a;}; +struct S4 {long a,a; short a;}; + + +// Constants +const long c1 = 0; +const long c1 = 0; + + +// Interfaces + +interface i1 {}; +interface i1 {}; + +interface i2 { + attribute long a1; + attribute long a1; +}; + +interface i3 { + attribute long a1, a2; + attribute long a2; +}; + +interface i4 { + attribute long a1, a1; +}; + +interface i5 { + long op1(); + long op1(); + + long op2(in long a, inout char a); +}; + + +// Unions + +union U1 switch (long) {case 1: long a;}; +union U1 switch (long) {case 1: long a;}; + +union U2 switch (long) { +case 1: long a; +default: char a; +}; + + + + + diff --git a/lib/ic/test/ic_SUITE_data/nasty.idl b/lib/ic/test/ic_SUITE_data/nasty.idl new file mode 100644 index 0000000000..15fd523c0f --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/nasty.idl @@ -0,0 +1,60 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Checks nasty name collisions +// + +typedef string T; + + +#define nasty01 version +#define nasty02 preproc +#define nasty03 pragma +#define nasty04 compile +#define nasty05 if +#define nasty06 receive +#define nasty07 foldr +#define nasty08 length +#define nasty09 ID + +interface I1 { + attribute T nasty01; + attribute T nasty02; + attribute T nasty03; + attribute T nasty04; + attribute T nasty05; + attribute T nasty06; + attribute T nasty07; + attribute T nasty08; + attribute T nasty09; +}; + +interface I2 { + T nasty01(); + T nasty02(); + T nasty03(); + T nasty04(); + T nasty05(); + T nasty06(); + T nasty07(); + T nasty08(); + T nasty09(); +}; + diff --git a/lib/ic/test/ic_SUITE_data/one.idl b/lib/ic/test/ic_SUITE_data/one.idl new file mode 100644 index 0000000000..99281d6079 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/one.idl @@ -0,0 +1,29 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Test oneway operations + +interface I1 { + long op1(in char a, inout boolean b, out string c); + oneway void op2(in char a, in boolean b, in string c); + oneway void op3(); +}; + + + diff --git a/lib/ic/test/ic_SUITE_data/one_followed.idl b/lib/ic/test/ic_SUITE_data/one_followed.idl new file mode 100644 index 0000000000..da8ee74e25 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/one_followed.idl @@ -0,0 +1,54 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Test oneway operations followed by other operations + +interface I1 { + oneway void op1(); + oneway void op2(in char a, in boolean b, in string c); + long op3(in char a, inout boolean b, out string c); +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/ic/test/ic_SUITE_data/one_out.idl b/lib/ic/test/ic_SUITE_data/one_out.idl new file mode 100644 index 0000000000..65f177ff22 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/one_out.idl @@ -0,0 +1,28 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Test oneway operations not using in out params + +interface I1 { + oneway void op1(in char a, inout boolean b, in string c); + oneway void op2(in char a, out boolean b, in string c); +}; + + + diff --git a/lib/ic/test/ic_SUITE_data/one_raises.idl b/lib/ic/test/ic_SUITE_data/one_raises.idl new file mode 100644 index 0000000000..8290877363 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/one_raises.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Test oneway operations not using in out params + +exception hell {boolean burn; unsigned long for_how_long;}; +exception high_water {long mark;}; + +interface I1 { + oneway void op1(in char a) raises (hell); + oneway void op2(in char a) raises (hell); + oneway void op3() raises (hell, high_water); +}; + + + diff --git a/lib/ic/test/ic_SUITE_data/one_void.idl b/lib/ic/test/ic_SUITE_data/one_void.idl new file mode 100644 index 0000000000..e1d51c7abb --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/one_void.idl @@ -0,0 +1,30 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Test oneway operations not using in out params + +typedef long T; + +interface I1 { + oneway char op1(in char a); + oneway T op2(in char a); +}; + + + diff --git a/lib/ic/test/ic_SUITE_data/raises_reg.idl b/lib/ic/test/ic_SUITE_data/raises_reg.idl new file mode 100644 index 0000000000..d4458811dc --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/raises_reg.idl @@ -0,0 +1,52 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#ifndef _RAISES_REG_IDL +#define _RAISES_REG_IDL + +module Raises_RegModule { + + exception Exception_1 {}; + + exception Exception_2 {}; + + interface R_R { + + void op() + raises(Raises_RegModule::Exception_1,Raises_RegModule::Exception_2); + + }; + +}; + +#endif + + + + + + + + + + + + + + + diff --git a/lib/ic/test/ic_SUITE_data/struct.idl b/lib/ic/test/ic_SUITE_data/struct.idl new file mode 100644 index 0000000000..337ee170e3 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/struct.idl @@ -0,0 +1,53 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + + +struct S1 { + long a; + char b; + string<9> s; +}; + +struct S2 { + long a; + struct S3 { + long a; + short b, b1; + char c; + } b; + sequence <S1> c, c2, c3, c4, c5, c6, c7; +}; + + +// Check that structs are detected down in other types + + +typedef struct s4 {long a;} T1; +union U1 switch (long) { +case 1: + struct S5 {unsigned short a;} a; +case 2: + union U2 switch (char) { + case 'a': + boolean a; + case 'b': + struct s6 {long a; boolean b;} c; + } b; +}; + diff --git a/lib/ic/test/ic_SUITE_data/syntax1.idl b/lib/ic/test/ic_SUITE_data/syntax1.idl new file mode 100644 index 0000000000..83c7de7943 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax1.idl @@ -0,0 +1,28 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Check syntax errors +// + + +typedef long T1 _; + + + diff --git a/lib/ic/test/ic_SUITE_data/syntax2.idl b/lib/ic/test/ic_SUITE_data/syntax2.idl new file mode 100644 index 0000000000..10498206c1 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax2.idl @@ -0,0 +1,27 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +struct S2 { + long a_arr[99]; + struct S3 { + long a;_arr[99] + boolean b_arr[99]; + } b; +}; + + diff --git a/lib/ic/test/ic_SUITE_data/syntax3.idl b/lib/ic/test/ic_SUITE_data/syntax3.idl new file mode 100644 index 0000000000..69ab6b9783 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax3.idl @@ -0,0 +1,20 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +typdef long T1; + diff --git a/lib/ic/test/ic_SUITE_data/syntax4.idl b/lib/ic/test/ic_SUITE_data/syntax4.idl new file mode 100644 index 0000000000..077a251729 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax4.idl @@ -0,0 +1,23 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +union U1 switch (long) { +case 1: long a; +2: short b; +}; + diff --git a/lib/ic/test/ic_SUITE_data/syntax5.idl b/lib/ic/test/ic_SUITE_data/syntax5.idl new file mode 100644 index 0000000000..10af9fc18c --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax5.idl @@ -0,0 +1,22 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +union U1 switch (enum E1 {kalle, sune}) { +case kalle: long a; +sune: short b; +}; diff --git a/lib/ic/test/ic_SUITE_data/syntax6.idl b/lib/ic/test/ic_SUITE_data/syntax6.idl new file mode 100644 index 0000000000..dc15704d94 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax6.idl @@ -0,0 +1,20 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +constant long c1 = 0; diff --git a/lib/ic/test/ic_SUITE_data/type.idl b/lib/ic/test/ic_SUITE_data/type.idl new file mode 100644 index 0000000000..67e1d502bd --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/type.idl @@ -0,0 +1,190 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Check all types in IDL +// + +typedef long T01; +typedef unsigned long T02; +typedef short T03; +typedef unsigned short T04; +typedef float T05; +typedef double T06; +typedef char T07; +typedef boolean T08; +typedef octet T09; +typedef any T10; +typedef Object T11; +typedef T01 T12; + +// Template types +typedef sequence <long> T21; +typedef sequence <unsigned long> T22; +typedef sequence <short, 2> T23; +typedef sequence <unsigned short, 6> T24; +typedef sequence <float, 12> T25; +typedef sequence <double> T26; +typedef sequence <char, 1> T27; +typedef sequence <boolean> T28; +typedef sequence <octet, 9> T29; +typedef sequence <any> T30; +typedef sequence <Object,2 > T31; +typedef sequence <T01> T32; +typedef sequence <sequence <sequence <T32> > > T33; + +struct S1 { + long a; + boolean b; +}; + +struct S2 { + long a; + struct S3 { + long a; + boolean b; + } b; +}; + +union U1 switch (enum E1 {kalle1, sune1}) { +case kalle1: long a; +default: boolean b; +case sune1: octet c; +}; + +union U2 switch (enum E2 {kalle2, sune2}) { +case kalle2: long a; +default: struct S4 { long a; short b;} b; +case sune2: octet c; +}; + +// Typedefs of above types + +typedef struct S11 { + long a; + boolean b; +} T41; + +typedef struct S21 { + long a; + struct S3 { + long a; + boolean b; + } b; +} T42; + +typedef union U11 switch (enum E3 {kalle3, sune3}) { +case kalle3: long a; +default: boolean b; +case sune3: octet c; +} T43; + +typedef union U21 switch (enum E4 {kalle4, sune4}) { +case kalle4: long a; +default: struct S4 { long a; short b;} b; +case sune4: octet c; +} T44; + + + + +// Array versions + +typedef long T01_arr[99]; +typedef unsigned long T02_arr[99]; +typedef short T03_arr[99]; +typedef unsigned short T04_arr[99]; +typedef float T05_arr[99]; +typedef double T06_arr[99]; +typedef char T07_arr[99]; +typedef boolean T08_arr[99]; +typedef octet T09_arr[99]; +typedef any T10_arr[99]; +typedef Object T11_arr[99]; +typedef T01 T12_arr[99]; + +typedef sequence <long> T21_arr[99]; +typedef sequence <unsigned long> T22_arr[99]; +typedef sequence <short, 2> T23_arr[99]; +typedef sequence <unsigned short, 6> T24_arr[99]; +typedef sequence <float, 12> T25_arr[99]; +typedef sequence <double> T26_arr[99]; +typedef sequence <char, 1> T27_arr[99]; +typedef sequence <boolean> T28_arr[99]; +typedef sequence <octet, 9> T29_arr[99]; +typedef sequence <any> T30_arr[99]; +typedef sequence <Object,2 > T31_arr[99]; +typedef sequence <T01> T32_arr[99]; +typedef sequence <sequence <sequence <T32> > > T33_arr[99]; + +struct S12 { + long a; + boolean b_arr[99]; +}; + +struct S22 { + long a_arr[99]; + struct S3 { + long a_arr[99]; + boolean b_arr[99]; + } b; +}; + +union U12 switch (enum E12 {kalle12, sune12}) { +case kalle12: long a_arr[99]; +default: boolean b; +case sune12: octet c; +}; + +union U22 switch (enum E22 {kalle22, sune22}) { +case kalle22: long a; +default: struct S4 { long a; short b;} b_arr[99]; +case sune22: octet c; +}; + +// Typedefs of above types + +typedef struct S13 { + long a_arr[99]; + boolean b; +} T41_arr[99]; + +typedef struct S23 { + long a; + struct S3 { + long a; + boolean b_arr[99]; + char c; + } b; +} T42_arr[99]; + +typedef union U13 switch (enum E13 {kalle13, sune13}) { +case kalle13: long a; +default: boolean b_arr[99]; +case sune13: octet c; +} T43_arr[99]; + +typedef union U23 switch (enum E23 {kalle23, sune23}) { +case kalle23: long a_arr[99]; +default: struct S4 { long a; short b;} b_arr[99]; +case sune23: octet c_arr[99]; +} T44_arr[99]; + + + diff --git a/lib/ic/test/ic_SUITE_data/typeid.idl b/lib/ic/test/ic_SUITE_data/typeid.idl new file mode 100644 index 0000000000..6e99f4a50d --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/typeid.idl @@ -0,0 +1,28 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +interface I1 {}; + +module M1 { interface I1 {};}; + +module M2 { module M1 { interface I1 {};};}; + +module M3 { module M2 { module M1 { interface I1 {};};};}; + + diff --git a/lib/ic/test/ic_SUITE_data/u_case_mult.idl b/lib/ic/test/ic_SUITE_data/u_case_mult.idl new file mode 100644 index 0000000000..3c30e144d8 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/u_case_mult.idl @@ -0,0 +1,54 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Check that case labels are not duplicated + +union U1 switch (long) { +case 1 : long a; +case 1 : short b; +}; + +union U2 switch (char) { +case 'c' : long a; +case 'c' : short b; +}; + +union U2b switch (char) { +case 'c' : +case 'c' : long a; +case 'e': long b; +case 'c': long c; +}; + +union U3 switch (enum E1 {kalle, kula}) { +case kula : long a; +case kula : short b; +}; + +union U4 switch (boolean) { +case TRUE : long a; +case TRUE : short b; +}; + +union U5 switch (boolean) { +case TRUE : long a; +default: short p; +default: short pp; +}; + diff --git a/lib/ic/test/ic_SUITE_data/u_default.idl b/lib/ic/test/ic_SUITE_data/u_default.idl new file mode 100644 index 0000000000..e5d94a5e54 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/u_default.idl @@ -0,0 +1,51 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Checking that default labels are correct in TK +// + +interface i1 { + union U1 switch (long) { + default: long a; + case 1: case 2: long b; + }; + + union U2 switch (long) { + case 0: default: long a; + case 1: case 2: long b; + }; + + union U3 switch (long) { + case -1: long aa; + case 0: default: long a; + case 1: case 2: long b; + }; + + union U4 switch (long) { + case -1: long aa; + case 0: long a; + case 1: case 2: long b; + }; + + U1 op0(); + U2 op1(); + U3 op2(); + U4 op3(); +}; diff --git a/lib/ic/test/ic_SUITE_data/u_mult.idl b/lib/ic/test/ic_SUITE_data/u_mult.idl new file mode 100644 index 0000000000..b916861eec --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/u_mult.idl @@ -0,0 +1,61 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + + +// Check multiply defined declarators + +enum E2 {kal, kula, E1}; // legal, but used below + +// Now check that declarator a is multiply defined in all unions below +union U0 switch (long) { +case 0: long a; +case 1: short a; +}; +union U00 switch (char) { +case 'c' : long a; +case 'f' : char c; +case 'b' : short a; +}; +union U000 switch (boolean) { +case TRUE: long a; +case FALSE: short a; +}; +union U0000 switch (E2) { +case kal: long a; +case kula: short a; +}; + + + + +// Check that enum name duplication is found. + +union U1 switch (enum E1 {kalle, kula, E1}) { +case E1 : long a; // legal +case kalle : short E1; // illegal +}; + + +// This is legal, but ended up here anyway + +union U2 switch(::E2) { +case kal : long a; +case kula : short b; +default : boolean E1; +}; diff --git a/lib/ic/test/ic_SUITE_data/u_norm.idl b/lib/ic/test/ic_SUITE_data/u_norm.idl new file mode 100644 index 0000000000..e23796b8ca --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/u_norm.idl @@ -0,0 +1,63 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + + +union U1 switch (long) { +case 1: long a; +case 2: case 3: short b; +}; + + +union U2 switch (unsigned short) { +case 10: boolean a; +case 188: char b; +default: string c; +}; + + +union U3 switch (enum E1 {kalle, kula, boll}) { +case kalle: long a; +case kula: U2 b; +}; + +enum E2 {Cissi, Anders}; + +union U4 switch (::E2) { +case Cissi: U1 a; +default: case Anders: unsigned long b; +}; + +union U5 switch(char) { +case 'e': long a; +case 'b': case 'f': char b; +default: struct S {long a; boolean b;} c; +}; + + +// Now check that references can be used as case values + +const long c1 = 9; +const long c2 = 10; + +union U6 switch (long) { +case c1: boolean a; +case ::c2: boolean b; +}; + + diff --git a/lib/ic/test/ic_SUITE_data/u_type.idl b/lib/ic/test/ic_SUITE_data/u_type.idl new file mode 100644 index 0000000000..44e3326305 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/u_type.idl @@ -0,0 +1,82 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + + +// +// Check that case values match declared discriminator type +// + + +const long longC = 0; +const short shortC = 0; +const char charC = 'c'; +const string stringC = "Yacht"; + +enum E1 {kalle, kula}; + +union U1 switch (long) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case kalle : long f; +}; + +union U2 switch (unsigned long) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case kalle : long f; +}; + +union U3 switch (short) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case kalle : long f; +}; + +union U4 switch (unsigned short) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case kalle : long f; +}; + +union U5 switch (char) { +case TRUE : long b; +case stringC : long d; +case shortC : long e; +case kalle : long f; +}; + + +union U6 switch (E1) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case shortC : long e; +}; + +union U7 switch (enum E2 {ja, nej, kanske}) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case shortC : long e; +}; + diff --git a/lib/ic/test/ic_SUITE_data/undef_id.idl b/lib/ic/test/ic_SUITE_data/undef_id.idl new file mode 100644 index 0000000000..01a35c4ef8 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/undef_id.idl @@ -0,0 +1,63 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// +// Check that undefined ids are detected +// + +typedef T7 T1; + +const char c1 = ::c0; +const T01 c2 = 'h'; +const T7 c3 = 9; + +interface i1 { + T17 op(); + long op2( in T7 a); + attribute T7 a1, a2; + readonly attribute T17 a3; +}; + +union U1 switch (long) { +case 1: long a; +case ::g : short b; +}; + +union U2 switch (enum E1 {kalle, kula}) { +case kula1: long a; +case kalle : short b; +}; + +union U3 switch (long) { +case kula2: long a; +case ::E3::kalle : short b; +case ::E4::kalle : short c; +}; + +enum E2 {kalle2, kula2}; + +union U4 switch (E2) { +case kula1: long a; +case kula1: long b; +case c3: short c; +}; + + + + diff --git a/lib/ic/test/ic_be_SUITE.erl b/lib/ic/test/ic_be_SUITE.erl new file mode 100644 index 0000000000..e3caf7bdff --- /dev/null +++ b/lib/ic/test/ic_be_SUITE.erl @@ -0,0 +1,69 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%%---------------------------------------------------------------------- +%%% Purpose : Test suite for the backends of the IDL compiler +%%%---------------------------------------------------------------------- + +-module(ic_be_SUITE). +-include("test_server.hrl"). + + +-export([all/1,plain/1]). + + +-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])). + + +%% Top of cases + +all(suite) -> [plain]. + + + +plain(doc) -> + ["Checking code for the plain backend."]; +plain(suite) -> []; +plain(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, plain), + + ?line ok = ic:gen(File,stdopts(OutDir)++[{be,erl_plain}]), + + ok. + + + + +%%-------------------------------------------------------------------- +%% +%% Utilities + + +stdopts(OutDir) -> + [{outdir, OutDir}, {maxerrs, infinity}]. + + + + + +to_list(X) when is_atom(X) -> atom_to_list(X); +to_list(X) -> X. + diff --git a/lib/ic/test/ic_be_SUITE_data/plain.idl b/lib/ic/test/ic_be_SUITE_data/plain.idl new file mode 100644 index 0000000000..ee0a995807 --- /dev/null +++ b/lib/ic/test/ic_be_SUITE_data/plain.idl @@ -0,0 +1,33 @@ + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +module m { + + struct s { + long x; + long y; + }; + + interface i { + + void foo( in s a, out short b ); + + }; + +}; + diff --git a/lib/ic/test/ic_pp_SUITE.erl b/lib/ic/test/ic_pp_SUITE.erl new file mode 100644 index 0000000000..d68242bf3a --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE.erl @@ -0,0 +1,647 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% Purpose : Test suite for the IDL preprocessor +%%---------------------------------------------------------------------- + +-module(ic_pp_SUITE). +-include("test_server.hrl"). + + + +%% Standard options to the ic compiler, NOTE unholy use of OutDir + +-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])). +-define(GCC, "g++"). +-define(GCC_VER, "2.95.3"). + +-export([all/1]). +-export([arg/1]). +-export([arg_norm/1]). +-export([cascade/1]). +-export([cascade_norm/1]). +-export([comment/1]). +-export([comment_norm/1]). +-export([concat/1]). +-export([concat_norm/1]). +-export([define/1]). +-export([define_norm/1]). +-export(['if'/1]). +-export([if_norm/1]). +-export([if_zero/1]). +-export([misc/1]). +-export([misc_norm/1]). +-export([improp_nest_constr/1]). +-export([improp_nest_constr_norm/1]). +-export([inc/1]). +-export([inc_norm/1]). +-export([line/1]). +-export([line_norm/1]). +-export([nopara/1]). +-export([nopara_norm/1]). +-export([predef/1]). +-export([predef_norm/1]). +-export([predef_time/1]). +-export([predef_time_norm/1]). +-export([self_ref/1]). +-export([self_ref_norm/1]). +-export([separate/1]). +-export([separate_norm/1]). +-export([swallow_sc/1]). +-export([swallow_sc_norm/1]). +-export([unintended_grp/1]). +-export([unintended_grp_norm/1]). +-export([cases/0, init_all/1, finish_all/1]). + + +all(doc) -> ["Preprocessing tests for IC"]; +all(suite) -> + {req, [], {conf, init_all, cases(), finish_all}}. + +init_all(Config) -> + if + is_list(Config) -> + case os:type() of + {win32, _} -> + {skipped, "Very unplesent to run on windows"}; + _ -> + check_gcc(Config) + end; + true -> + exit("Config not a list") + end. + +check_gcc(Config) -> + case os:find_executable(?GCC) of + false -> + {skipped, + lists:flatten(io_lib:format("Can not run without ~s in path", + [?GCC]))}; + _ -> + case trim(os:cmd(?GCC++" --version")) of + ?GCC_VER++[] -> + Config; + ?GCC_VER++[D|_] when is_integer(D), D>=$0, D=<$9 -> + fail_gcc(?GCC_VER++[D]); + ?GCC_VER++_ -> + Config; + Ver -> + fail_gcc(Ver) + end + end. + +fail_gcc(Ver) -> + {skipped, lists:flatten(io_lib:format("Need ~s v~s, not ~s", + [?GCC, ?GCC_VER, Ver]))}. + +trim(S) -> lists:reverse(skip_white(lists:reverse(skip_white(S)))). + +skip_white([$\s|T]) -> skip_white(T); +skip_white([$\n|T]) -> skip_white(T); +skip_white([$\r|T]) -> skip_white(T); +skip_white([$\t|T]) -> skip_white(T); +skip_white(L) -> L. + + +finish_all(Config) -> + Config. + + +cases() -> + [arg, cascade, comment, concat, define, misc, 'if', improp_nest_constr, inc, + line, nopara, predef, predef_time, self_ref, separate, swallow_sc, + unintended_grp]. + + + +%%-------------------------------------------------------------------- +%% arg +%%-------------------------------------------------------------------- + +arg(suite) -> [arg_norm]; +arg(doc) -> ["Check #define with some arguments"]. + +arg_norm(doc) -> ["Checks arguments for #define."]; +arg_norm(suite) -> []; +arg_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(arg_norm), + File = filename:join(DataDir, arg), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% cascade +%%-------------------------------------------------------------------- + +cascade(suite) -> [cascade_norm]; +cascade(doc) -> ["Check cascade #define"]. + +cascade_norm(doc) -> ["Check cascade #define."]; +cascade_norm(suite) -> []; +cascade_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(cascade_norm), + File = filename:join(DataDir, cascade), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% comment +%%-------------------------------------------------------------------- + +comment(suite) -> [comment_norm]; +comment(doc) -> ["Check comments"]. + +comment_norm(doc) -> ["Check comments."]; +comment_norm(suite) -> []; +comment_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(comment_norm), + File = filename:join(DataDir, comment), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% concat +%%-------------------------------------------------------------------- + +concat(suite) -> [concat_norm]; +concat(doc) -> ["Check concatinations, i.e ## "]. + +concat_norm(doc) -> ["Check concatinations, i.e ## ."]; +concat_norm(suite) -> []; +concat_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(concat_norm), + File = filename:join(DataDir, concat), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% define +%%-------------------------------------------------------------------- + +define(suite) -> [define_norm]; +define(doc) -> ["Check misceleaneous #define"]. + +define_norm(doc) -> ["Check misceleaneous #define."]; +define_norm(suite) -> []; +define_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(define_norm), + File = filename:join(DataDir, define), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% if +%%-------------------------------------------------------------------- + +'if'(suite) -> [if_norm, if_zero]; +'if'(doc) -> ["Check #if, #elif, and #endif. Note these are not implementen and will ~n + result in an error message from internal_pp"]. + +if_norm(doc) -> ["Check #if, #elif, and #endif. ."]; +if_norm(suite) -> []; +if_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(if_norm), + File = filename:join(DataDir, 'if'), + + ?line ok = test_file(File, DataDir), + ok. + +if_zero(doc) -> ["Check #if 0"]; +if_zero(suite) -> []; +if_zero(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(if_zero), + File = filename:join(DataDir, if_zero), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% inc +%%-------------------------------------------------------------------- + +inc(suite) -> [inc_norm]; +inc(doc) -> ["Check #include"]. + +inc_norm(doc) -> ["Check #include."]; +inc_norm(suite) -> []; +inc_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(inc_norm), + File = filename:join(DataDir, inc), + + ?line ok = test_file(File, DataDir), + ok. + + + +%%-------------------------------------------------------------------- +%% improp_nest_constr +%%-------------------------------------------------------------------- + +improp_nest_constr(suite) -> [improp_nest_constr_norm]; +improp_nest_constr(doc) -> ["Check improperly nested constructs"]. + +improp_nest_constr_norm(doc) -> ["Check improperly nested constructs."]; +improp_nest_constr_norm(suite) -> []; +improp_nest_constr_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(improp_nest_constr_norm), + File = filename:join(DataDir, improp_nest_constr), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% misc +%%-------------------------------------------------------------------- + +misc(suite) -> [misc_norm]; +misc(doc) -> ["Misceleaneous checks"]. + +misc_norm(doc) -> ["Misceleaneous checks."]; +misc_norm(suite) -> []; +misc_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(misc_norm), + File = filename:join(DataDir, misc), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% line +%%-------------------------------------------------------------------- + +line(suite) -> [line_norm]; +line(doc) -> ["Checks #line"]. + +line_norm(doc) -> ["Checks #line."]; +line_norm(suite) -> []; +line_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(line_norm), + File = filename:join(DataDir, line), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% nopara +%%-------------------------------------------------------------------- + +nopara(suite) -> [nopara_norm]; +nopara(doc) -> ["Checks #define with no parameters"]. + +nopara_norm(doc) -> ["Checks #define with no parameters."]; +nopara_norm(suite) -> []; +nopara_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(nopara_norm), + File = filename:join(DataDir, nopara), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% predef +%%-------------------------------------------------------------------- + +predef(suite) -> [predef_norm]; +predef(doc) -> ["Checks predefined macros. Note: not __TIME__ and __DATE__"]. + +predef_norm(doc) -> ["Checks predefined macros. Note: not __TIME__ and __DATE__."]; +predef_norm(suite) -> []; +predef_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(predef_norm), + File = filename:join(DataDir, predef), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% predef_time +%%-------------------------------------------------------------------- + +predef_time(suite) -> [predef_time_norm]; +predef_time(doc) -> ["Checks the predefined macros __TIME__ and __DATE__"]. + +predef_time_norm(doc) -> ["Checks the predefined macros __TIME__ and __DATE__."]; +predef_time_norm(suite) -> []; +predef_time_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(predef_time_norm), + File = filename:join(DataDir, predef_time), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% self_ref +%%-------------------------------------------------------------------- + +self_ref(suite) -> [self_ref_norm]; +self_ref(doc) -> ["Checks self referring macros"]. + +self_ref_norm(doc) -> ["Checks self referring macros."]; +self_ref_norm(suite) -> []; +self_ref_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(self_ref_norm), + File = filename:join(DataDir, self_ref), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% separate +%%-------------------------------------------------------------------- + +separate(suite) -> [separate_norm]; +separate(doc) -> ["Checks separete expansion of macro arguments"]. + +separate_norm(doc) -> ["Checks separete expansion of macro arguments."]; +separate_norm(suite) -> []; +separate_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(separate_norm), + File = filename:join(DataDir, separate), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% swallow_sc +%%-------------------------------------------------------------------- + +swallow_sc(suite) -> [swallow_sc_norm]; +swallow_sc(doc) -> ["Checks swallowing an undesirable semicolon"]. + +swallow_sc_norm(doc) -> ["Checks swallowing an undesirable semicolon."]; +swallow_sc_norm(suite) -> []; +swallow_sc_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(swallow_sc_norm), + File = filename:join(DataDir, swallow_sc), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% unintended_grp +%%-------------------------------------------------------------------- + +unintended_grp(suite) -> [unintended_grp_norm]; +unintended_grp(doc) -> ["Checks unintended grouping of arithmetic"]. + +unintended_grp_norm(doc) -> ["Checks unintended grouping of arithmetic."]; +unintended_grp_norm(suite) -> []; +unintended_grp_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(unintended_grp_norm), + File = filename:join(DataDir, unintended_grp), + + ?line ok = test_file(File, DataDir), + ok. + + + + + +test_file(FileT, DataDir) -> + case test_file_1(FileT, DataDir) of + ok -> ok; + Chars -> + io:put_chars(Chars), + {error,{FileT,DataDir}} + end. + +test_file_1(FileT, DataDir) -> + Tok = string:tokens(FileT, "/"), + FileName = lists:last(Tok), + File = FileT++".idl", + + ?line test_server:format("File ~p~n",[File]), + ?line test_server:format("FileName ~p~n",[FileName]), + + Flags = "-I"++DataDir, + + ?line test_server:format("Flags ~p~n",[Flags]), + + ?line Erl = pp_erl(File, Flags), + ?line Gcc = pp_gcc(File, Flags), + + ?line case Erl of + {error,_ErlError} -> + ?line test_server:format("Internal_pp Result ~n==================~n~p~n~n",[Erl]); + {warning, _ErlWar} -> + ?line test_server:format("Internal_pp Result ~n==================~n~p~n~n",[Erl]); + _ -> + ?line test_server:format("Internal_pp Result ~n==================~n~s~n~n",[Erl]) + end, + + ?line case Gcc of + {error,GccError} -> + Error = string:tokens(GccError, "\n"), + ?line test_server:format(?GCC" Result ~n==========~n~p~n~n", + [Error]); + _ -> + ?line test_server:format(?GCC" Result ~n==========~n~s~n~n",[Gcc]) + end, + + + + ?line case {Erl,Gcc} of + {{warning,W}, {error,X}} -> + ?line case is_ok(W,X) of + yes -> + ok; + no -> + io_lib:format("Internal_pp found Warning = ~p ~n" + ?GCC" found Error = ~p~n",[W,X]) + end; + + + {{warning,W}, _} -> + io_lib:format(?GCC" did not find warnings while ~n" + "Internal_pp found the following Warning = ~p~n",[W]); + + {{error,E}, {error,X}} -> + ?line case is_ok(E,X) of + yes -> + ok; + no -> + io_lib:format("Internal_pp found Error = ~p ~n" + ?GCC" found Error = ~p~n",[E,X]) + end; + + {{error,E}, _} -> + ?line case FileName of + "if" -> + ?line case if_res(E) of + ok -> + ok; + _ -> + io_lib:format(?GCC" did not find errors while ~n" + "Internal_pp found the following Error = ~p~n",[E]) + end; + _ -> + io_lib:format(?GCC" did not find errors while ~n" + "Internal_pp found the following Error = ~p~n",[lists:flatten(E)]) + end; + + {_, {error,X}} -> + io_lib:format("Internal_pp did not find errors while ~n" + ?GCC" found the following Error = ~p~n",[X]); + + _ -> + + ?line file:write_file("/tmp/Erl.pp",list_to_binary(Erl)), + ?line file:write_file("/tmp/Gcc.pp",list_to_binary(Gcc)), + + ?line Res = os:cmd("diff -b -w /tmp/Erl.pp /tmp/Gcc.pp"), + ?line test_server:format("///////////{error,E} E ~p FileName~p~n",[Res,FileName]), + ?line case {Res, FileName} of + {[], _} -> + ?line test_server:format("Diff = [] OK!!!!!!~n"), + ok; + {_, "predef_time"} -> + Tokens = string:tokens(Res,"\n"), + ?line test_server:format("///////////{error,E} Tokens~p~n",[Tokens]), + case Tokens of + ["3c3",_,"---",_,"5c5",_,"---",_,"9c9",_,"---",_] -> + ok; + _ -> + io_lib:format("Diff Result = ~p~n",[Res]) + end; + _ -> + io_lib:format("Diff Result = ~p~n",[Res]) + end + end. + + + + + +pp_erl(File, Flags) -> + case ic_pp:run(File,Flags) of + {ok, [$#, $ , $1 | Rest], []} -> + [$#, $ , $1 | Rest]; + {ok, [$#, $ , $1 | _Rest], Warning} -> + {warning,Warning}; + {error,Error} -> + {error,Error} + end. + +pp_gcc(File, Flags) -> + Cmd = ?GCC" -x c++ -E", + Line = Cmd++" "++Flags++" "++File, + + case os:cmd(Line) of + [$#, $ , $1 | Rest] -> + [$#, $ , $1 | Rest]; + Res -> + + case string:str(Res,"# 1 \"") of + 0 -> + {error,Res}; + X -> + {error, string:sub_string(Res, 1, X-1)} + end + end. + + +is_ok([],_Gcc) -> + yes; +is_ok([{FileName,Line,Text}|T],Gcc) -> + Str = FileName++":"++integer_to_list(Line)++": "++Text, + case string:str(Gcc,Str) of + 0 -> + io:format("~n is_ok Internal_pp missed Error = ~s~n",[Str]), + no; + _X -> + is_ok(T,Gcc) + end; +is_ok([Str|T],Gcc) -> + case string:str(Gcc,Str) of + 0 -> + io:format("~n is_ok Internal_pp missed Error = ~s~n",[Str]), + no; + _X -> + is_ok(T,Gcc) + end. + + +to_list(X) when is_atom(X) -> atom_to_list(X); +to_list(X) -> X. + + + +if_res(E) -> + if_res(E,1). + +if_res([H|T],Nr) -> + %% Dir = "/clearcase/otp/libraries/ic/test/ic_pp_SUITE_data/if.idl", + case {Nr, H} of + {1, {_Dir, 2, "only '#if 0' is implemented at present"}} -> + if_res(T,Nr+1); + {2, {_Dir, 3, "only '#if 0' is implemented at present"}} -> + if_res(T,Nr+1); + {3, {_Dir, 5, "`else' command is not implemented at present"}} -> + if_res(T,Nr+1); + {4, {_Dir, 9, "`elif' command is not implemented at present"}} -> + if_res(T,Nr+1); + {5, {_Dir, 11, "`else' command is not implemented at present"}} -> + ok; + _ -> + error + end; +if_res(_, _) -> + error. + + + diff --git a/lib/ic/test/ic_pp_SUITE_data/arg.idl b/lib/ic/test/ic_pp_SUITE_data/arg.idl new file mode 100644 index 0000000000..b4d266121d --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/arg.idl @@ -0,0 +1,38 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define xstr (s) str(s) +#define str(s) #s +#define foo 4 + +xstr(foo); + +#define x(kalle)stina +x(kurt) +x + +#define y(kalle) stina +y(kurt) +y + +#define a(kalle) stina +a(kurt) +a + +#define b (kalle) stina +b(kurt) diff --git a/lib/ic/test/ic_pp_SUITE_data/cascade.idl b/lib/ic/test/ic_pp_SUITE_data/cascade.idl new file mode 100644 index 0000000000..8dff1ee99f --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/cascade.idl @@ -0,0 +1,29 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define BUFS 1020 +#define TABS BUFS +#undef BUFS +#define BUFS 37 + + +main() +{ + TABS; + +} diff --git a/lib/ic/test/ic_pp_SUITE_data/comment.idl b/lib/ic/test/ic_pp_SUITE_data/comment.idl new file mode 100644 index 0000000000..d2ca3e7872 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/comment.idl @@ -0,0 +1,72 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define T 12 +#define F T + +//comment +/*exception except {};*/ + +// comment + // comment +/* another */ + /* another */ +/* still +another */ + /* still + another */ +__LINE__ +/* yet \ + another */ +// yet \ + another +__LINE__ + +#include "all.c" +#include <all.c> +#include /* comment */ "all.c" +#include /* comment */ <all.c> +#include "all.c" /* comment */ +#include <all.c> /* comment */ +#include // "all.c" +#include // <all.c> +#include "all.c" // comment +#include <all.c> // comment +#include "all/*cc*/.c" +#include <all/*cc*/.c> + +main() +{ + printf(" %d \n",F); + a(); + +} +//comment +/*exception hell {};*/ +#undef T +#define T "3/*com\ +ment*/4" +a() +{ + printf(" %d \n",F); + printf(" %d \n",T); +} + +b() +{} + diff --git a/lib/ic/test/ic_pp_SUITE_data/concat.idl b/lib/ic/test/ic_pp_SUITE_data/concat.idl new file mode 100644 index 0000000000..b8527fadfc --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/concat.idl @@ -0,0 +1,60 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define sune kurt +#define a(name) a #name name##_command +#define b(name) b #name name## _command +#define c(name) c #name name ##_command +#define d(name) d #name name ## _command +#define e(name) e #name command ## _command +#define f(name) f #name command ## %_command +#define g(name) g #name name ## %_command +#define h(name) h #name %_command ## name +#define i(name) i #name name ## _ ## name +#define j(name) j #name name ## name +#define k(name) k #name name ## name +#define l(name) l #name !name ## name +#define m(name) m #name name ## !name +#define n(name) n #name !name ## !name +#define o(name) stina +#define p(name) name +#define q1(name) q1 #name j(name) ## j(name) +#define q2(name) q2 #name j(name) +#define q3(name) q3 #name !! ## j(name) +#define q4(name) q4 #name ## j(name) + +a(quit) +b(quit) +c(quit) +d(quit) +e(quit) +f(quit) +g(sune) +h(sune) +i(sune) +j(sune) +l(sune) +m(sune) +n(sune) +k(j(sune)) +k(o(sune)) +k(p(sune)) +q1(sune) +q2(sune) +q3(sune) +q4(sune) diff --git a/lib/ic/test/ic_pp_SUITE_data/define.idl b/lib/ic/test/ic_pp_SUITE_data/define.idl new file mode 100644 index 0000000000..6aac63dd1e --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/define.idl @@ -0,0 +1,41 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define 8 +#define +#define a +#define _a +#define b dfs +#define 9 fdas +#define a8 +#define A +#define (c) fadfas +#define )c) fadfas +#define % c) fadfas +#define d(p) kfdsa +#define e(p) sinus(p) +#warning warning line +#define w%er percent +#define q() no_para +#warning warning line +#undef +#undef 8 +#undef a +#undef b +#undef _a d(kk) + diff --git a/lib/ic/test/ic_pp_SUITE_data/if.idl b/lib/ic/test/ic_pp_SUITE_data/if.idl new file mode 100644 index 0000000000..c381fa73ee --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/if.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define kurt 12 +#if !true +#if X == 1 +ett +#else +else +#endif +true +#elif kurt +trueelif +#else +trueelse +#endif +end diff --git a/lib/ic/test/ic_pp_SUITE_data/if_zero.idl b/lib/ic/test/ic_pp_SUITE_data/if_zero.idl new file mode 100644 index 0000000000..d715f9d61e --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/if_zero.idl @@ -0,0 +1,31 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#if 0 +pelle = mallan +#endif +pelle = stina +#if 0 +kalle = stina +#endif +kalle = mallan +#if 0 +kurt = fia +#endif +fia = kurt + diff --git a/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl b/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl new file mode 100644 index 0000000000..463ee3c695 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl @@ -0,0 +1,30 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define double(x) (2*(x)) +#define call_with_1(x) x(1) + +#define strange(file) fprintf (file, "%s %d", + +main() +{ + call_with_1(double); + strange(stderr) p, 35) + +} + diff --git a/lib/ic/test/ic_pp_SUITE_data/inc.idl b/lib/ic/test/ic_pp_SUITE_data/inc.idl new file mode 100644 index 0000000000..0dcd637082 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/inc.idl @@ -0,0 +1,68 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +int x; + +#include "head.h" +#warning line nr +main() +{ + printf(test()); +} + + + + + + + + +#define C false +#define Z on +#include "inc2.h" +#undef Z +"Ca" C +"Za" Z +#include "inc2.h" +"Cb" C +"Zb" Z + +main() +{ +#define Q(a,b) sinus(a,b kurt ## b) + if (Q(34,56)=='NULL') printf(" T AAA%sEEEE \n",Q); + printf(" %d \n",F); + a(); +} +//comment +/*exception +hell {};*/ +#undef T +#define T "3/*com\ment*/4" +#define T 33 +#define F again +a () +{ + printf(" %d \n",F); + printf(" %d \n",T); +} + +b() +{} + diff --git a/lib/ic/test/ic_pp_SUITE_data/included1.idl b/lib/ic/test/ic_pp_SUITE_data/included1.idl new file mode 100644 index 0000000000..4cd26c4543 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/included1.idl @@ -0,0 +1,35 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2000-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#ifndef INCLUDED1_IDL +#define INCLUDED1_IDL + + +#ifndef SOMETHING +#endif + + +struct s { + + long l; + +}; + + + +#endif diff --git a/lib/ic/test/ic_pp_SUITE_data/included2.idl b/lib/ic/test/ic_pp_SUITE_data/included2.idl new file mode 100644 index 0000000000..7cc44eef3e --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/included2.idl @@ -0,0 +1,41 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2000-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#ifndef INCLUDED2_IDL +#define INCLUDED2_IDL + +#include "included1.idl" + + +#ifdef SOMETHING +#endif + + +module m { + + struct t { + + s st; + + }; + + +}; + + +#endif diff --git a/lib/ic/test/ic_pp_SUITE_data/includer.idl b/lib/ic/test/ic_pp_SUITE_data/includer.idl new file mode 100644 index 0000000000..c6ebc234e8 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/includer.idl @@ -0,0 +1,45 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2000-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#ifndef INCLUDER_IDL +#define INCLUDER_IDL + +#include "included1.idl" +#include "included2.idl" + +#ifdef SOMETHING +#endif + + + +module n { + + interface j { + + s op(in m::t inpar); + + }; + +}; + + + + +#endif + + diff --git a/lib/ic/test/ic_pp_SUITE_data/line.idl b/lib/ic/test/ic_pp_SUITE_data/line.idl new file mode 100644 index 0000000000..5bd9c9446d --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/line.idl @@ -0,0 +1,45 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#line +#line 8 +#line 8a +#line 12 abc.c +#line 12 "kurt.c" +#warning fdafdsaf + + +#define T 12 +#define F T +#define Q(a) sinus(a) +#undef Q +# +#line 12 +#warning test of warning +#warning second of warning +#warning third of warning +#pragma kurt +#ident kurt +#kurt fdsafd +#line 20 +main() +{ + if (Q(34,56)=='NULL') printf(" T AAA%sEEEE \n",Q); + printf(" %d \n",F); +} +sune diff --git a/lib/ic/test/ic_pp_SUITE_data/misc.idl b/lib/ic/test/ic_pp_SUITE_data/misc.idl new file mode 100644 index 0000000000..9c18610fcf --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/misc.idl @@ -0,0 +1,44 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define str(s) #s +str(fool); +str(foo); +str(kurt); +#define xstr(s) str(s) +#define foo 4 +#define kurt sune +#define sune 17 + +xstr(fool); +xstr(foo); +xstr(kurt); + +#define a(b) b #8b +#define r(b) b # +#define t(b) b ## a +a(sinus) + +#define ww #www +ww + +#define x 14 + y +#define y 12 + #x +x + +#define e(a) cosinus(a) diff --git a/lib/ic/test/ic_pp_SUITE_data/nopara.idl b/lib/ic/test/ic_pp_SUITE_data/nopara.idl new file mode 100644 index 0000000000..1bb137da11 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/nopara.idl @@ -0,0 +1,35 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#11a +#define xstr str(s) + kurt*2; +#define asdf pragma +#asdf +#define asd #pragma asd + +#10 +#12 8kurt + +#define sss "stringing in the rain" +#define ddd "string +ing in the rain" asd +#line 20 +#include "head.h" qqqq +#include %!# +#include <sys.h> + diff --git a/lib/ic/test/ic_pp_SUITE_data/predef.idl b/lib/ic/test/ic_pp_SUITE_data/predef.idl new file mode 100644 index 0000000000..d8abcb25d5 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/predef.idl @@ -0,0 +1,33 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define b(q,w) kurt q w + + +b(__LINE__, __FILE__) +__LINE__ +__FILE__ + + + +b(__INCLUDE_LEVEL__, __BASE_FILE__) +__INCLUDE_LEVEL__ +__BASE_FILE__ + +Line __LINE__ +#include "predef.h" diff --git a/lib/ic/test/ic_pp_SUITE_data/predef_time.idl b/lib/ic/test/ic_pp_SUITE_data/predef_time.idl new file mode 100644 index 0000000000..05e3ba9175 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/predef_time.idl @@ -0,0 +1,24 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define b(q,w) kurt q w +b(__DATE__, __TIME__) +__DATE__ +__TIME__ + +#include "predef_time.h" diff --git a/lib/ic/test/ic_pp_SUITE_data/self_ref.idl b/lib/ic/test/ic_pp_SUITE_data/self_ref.idl new file mode 100644 index 0000000000..a44666272e --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/self_ref.idl @@ -0,0 +1,26 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define foo (4 + foo) + + +main() +{ + foo; + +} diff --git a/lib/ic/test/ic_pp_SUITE_data/separate.idl b/lib/ic/test/ic_pp_SUITE_data/separate.idl new file mode 100644 index 0000000000..a3faf9b986 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/separate.idl @@ -0,0 +1,37 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define xstr(s) str(s) +#define str(s) #s +#define foo 4 +#define str1(s) #s lose(s) +#define foo1 4 + +main() +{ + str(foo); + str1(foo1); + xstr(foo); + +#define qxstr(s) qstr(s) + qxstr(qfoo); +#define qstr(s) #s + qstr( 4 ) ; +#define qfoo 4 + qstr(qfoo); +} diff --git a/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl b/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl new file mode 100644 index 0000000000..71ed329ca6 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl @@ -0,0 +1,37 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +/* comment \ + ends */ +// comment\ +ends +Line __LINE__ +#define SKIP_SPACES(p, limit) \ +{register char *lim = (limit); \ + while (p != lim) { \ + if (*p++ != ' ') { \ + p--; break; }}} + + +main() +{ + if (*p != 0) + SKIP_SPACES (ppp, lim); + else + a = 17; +} diff --git a/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl b/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl new file mode 100644 index 0000000000..3618bab1bc --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl @@ -0,0 +1,29 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +#define ceil_div( xz, yz) (xz + yz - 1) / yz +#define ceil_div2(xz, yz) ((xz) + (yz) - 1) / (yz) + +#define b kurt + +main() +{ + ceil_div(b & c, sizeof(int)); + ceil_div2(b & c, sizeof(int)); + +} diff --git a/lib/ic/test/ic_pragma_SUITE.erl b/lib/ic/test/ic_pragma_SUITE.erl new file mode 100644 index 0000000000..0edb5d4717 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE.erl @@ -0,0 +1,295 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File: ic_pragma_SUITE.erl +%% +%% Description: +%% Test suite for the IFR object registration when +%% pragmas are engaged +%% +%%----------------------------------------------------------------- +-module(ic_pragma_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, init_all/1, finish_all/1]). +-export([ifr_pragma_reg/1, pragma_error/1, uggly_pragmas/1]). + + +%%----------------------------------------------------------------- +%% Macros +%%----------------------------------------------------------------- +-define(REMAP_EXCEPT(F), case catch F of + {'EXCEPTION', E} -> exit(E); + R -> R + end). +%% Standard options to the ic compiler, NOTE unholy use of OutDir + +-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])). + + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [ifr_pragma_reg,pragma_error,uggly_pragmas]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_all(Config) -> + io:format("Setting up.....~n"), + mnesia:stop(), + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + mnesia:start(), + orber:install([node()]), + orber:start(), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + io:format("Setting down.....~n"), + orber:stop(), + orber:uninstall(), + mnesia:stop(), + mnesia:delete_schema([node()]), + Config. + + + + +%%----------------------------------------------------------------- +%% Test Case: IFR registration with pragmas +%%----------------------------------------------------------------- +ifr_pragma_reg(doc) -> + ["Checks that IFR object is correctly registered under pragma engagement."]; +ifr_pragma_reg(suite) -> []; +ifr_pragma_reg(Config) when is_list(Config) -> + ?REMAP_EXCEPT(ifr_pragma_reg_run(Config)). + +ifr_pragma_reg_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_pragma_reg), + File0 = filename:join(DataDir, reg_m0), + ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}]), + ?line ok = compile(OutDir, ifr_pragma_files()), + code:add_pathz(OutDir), + + %% OE_register for all files + ?line ok = 'oe_reg_m0':'oe_register'(), + + %% Pragma registration test + OE_IFR = orber_ifr:find_repository(), + io:format("~n##### Starting the test case #####~n"), + check_pragma_effect(OE_IFR,"IDL:M1/T1:1.0"), + check_pragma_effect(OE_IFR,"DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3"), + check_pragma_effect(OE_IFR,"IDL:P2/T3:1.0"), + check_pragma_effect(OE_IFR,"IDL:P1/M2/T4:2.4"), + + %% OE_unregister for all files + ?line ok = 'oe_reg_m0':'oe_unregister'(), + code:del_path(OutDir), + ok. + + +ifr_pragma_files() -> ['oe_reg_m0']. + + +check_pragma_effect(OE_IFR,ID) -> + io:format("Checking for existance of : ~s~n",[ID]), + case orber_ifr:lookup_id(OE_IFR,ID) of + [] -> + test_server:fail(ID ++ " does not exist"), + false; + {Def,_} -> + io:format("Id refers to = {~p,#Bin}~n",[Def]), + true + end. + + + + +%%----------------------------------------------------------------- +%% Test Case: Syntactical / Semantical error pragma definitions +%%----------------------------------------------------------------- +pragma_error(doc) -> + ["Finds errornous pragma definitions under compilation."]; +pragma_error(suite) -> []; +pragma_error(Config) when is_list(Config) -> + ?REMAP_EXCEPT(pragma_error_run(Config)). + +pragma_error_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(pragma_error), + File1 = filename:join(DataDir, reg_m1), + File2 = filename:join(DataDir, reg_m2), + File3 = filename:join(DataDir, reg_m3), + File4 = filename:join(DataDir, reg_m4), + File5 = filename:join(DataDir, reg_m5), + File6 = filename:join(DataDir, reg_m6), + + ?line error = ic:gen(File1, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + + ?line error = ic:gen(File2, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + + ?line error = ic:gen(File3, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + + ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + + ?line error = ic:gen(File5, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + + ?line error = ic:gen(File6, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ok. + + + + +%%----------------------------------------------------------------- +%% Test Case: IFR registration with realy uggly placed pragmas +%%----------------------------------------------------------------- +uggly_pragmas(doc) -> + ["Checks that IFR object is correctly registered under really uggly pragma engagement."]; +uggly_pragmas(suite) -> []; +uggly_pragmas(Config) when is_list(Config) -> + ?REMAP_EXCEPT(uggly_pragmas_run(Config)). + +uggly_pragmas_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_pragma_reg), + File0 = filename:join(DataDir, uggly), + + ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}]), + + ?line ok = compile(OutDir, uggly_pragma_files()), + code:add_pathz(OutDir), + + %% OE_register for all files + ?line ok = 'oe_uggly':'oe_register'(), + + %% Pragma registration test + OE_IFR = orber_ifr:find_repository(), + io:format("~n##### Starting the test case #####~n"), + + check_pragma_effect(OE_IFR, "IDL:M:1.0"), + check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:10"), + check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:11"), + check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:17"), + check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:34"), + check_pragma_effect(OE_IFR, "IDL:Exc1:2.2"), + check_pragma_effect(OE_IFR, "IDL:Exc2:2.2"), + check_pragma_effect(OE_IFR, "IDL:S:1.0"), + check_pragma_effect(OE_IFR, "IDL:U:1.0"), + check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:23"), + + %% OE_unregister for all files + ?line ok = 'oe_uggly':'oe_unregister'(), + + code:del_path(OutDir), + ok. + + +uggly_pragma_files() -> ['oe_uggly']. + + + + +%%---------------------------- + + +stdopts(OutDir) -> + [{outdir, OutDir}, {maxerrs, infinity}]. + + +compile(Dir, Files) -> + compile(Dir, Files, []). + +compile(Dir, Files, Opts) -> + {ok, Cwd} = file:get_cwd(), + file:set_cwd(Dir), + io:format("Changing to ~p~n", [Dir]), + case catch do_compile(Files, Opts) of + ok -> + file:set_cwd(Cwd); + Err -> + file:set_cwd(Cwd), + test_server:fail(Err) + end. + +do_compile([], _Opts) -> ok; +do_compile([F | Fs], Opts) -> + io:format("Compiling ~p", [F]), + case compile:file(F, Opts) of + ok -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + Err -> + io:format(" error: ~p~n", [Err]), + Err + end. + +do_load(File, Opts) -> + case lists:member(load, Opts) of + true -> + io:format("Loading file ~p", [File]), + code:purge(File), + R = code:load_abs(File), + io:format("Loaded: ~p", [R]); + false -> + ok + end. + + +to_list(X) when is_atom(X) -> atom_to_list(X); +to_list(X) -> X. + + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl new file mode 100644 index 0000000000..80f0f2cdd1 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl @@ -0,0 +1,77 @@ + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Normal pragmas + +module M1 { + + typedef long T1; + + typedef long T2; + +#pragma ID T2 "DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3" + +}; + + +#pragma prefix "P1" + +module M2 { + + module M3 { + +#pragma prefix "P2" + + interface I1 { + void Op( in short b, + out short c); + }; + typedef long T3; + }; + + + typedef long T4; + +#pragma version T4 2.4 + +}; + + + +/* + + Specified types with the following scoped names + and RepositoryIds + + ::M1::T1 IDL:M1/T1:1.0 + + ::M1::T2 DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3 + + ::M2::M3::T3 IDL:P2/T3:1.0 + + ::M2::T4 IDL:P1/M2/T4:2.4 + +*/ + + + + + + + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl new file mode 100644 index 0000000000..6c22788290 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl @@ -0,0 +1,75 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// Bad pragma IDs + +// Completelly bad id +module M1 { + + typedef long T1; + + typedef long T2; + +#pragma ID T2 "CompletelyBadId" + +}; + + +// Bad id, should start with DCE +module M2 { + + typedef long T1; + + typedef long T2; + +#pragma ID T2 "BAD:d62207a2-011e-11ce-88b4-0800090b5d3e:3" + +}; + + +// Bad version in ID : not a short number +module M3 { + + typedef long T1; + + typedef long T2; + +#pragma ID T2 "DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:ABCD" + +}; + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl new file mode 100644 index 0000000000..1751751295 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl @@ -0,0 +1,40 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// Bad pragma versions + + +// Bad major version : not a short number +module M1 { + + typedef long T4; + +#pragma version T4 2000000000.4 + +}; + +// Bad minor version : not a short number +module M2 { + + typedef long T4; + +#pragma version T4 2.4000000000000 + +}; + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl new file mode 100644 index 0000000000..b7c9da249f --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl @@ -0,0 +1,38 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// Bad pragma prefixs + +module M2 { + + module M3 { + +#pragma prefix P2 // Should be "P2" + + interface I1 { + void foo( in short b, + out short c); + }; + typedef long T3; + }; + + + typedef long T4; +}; + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl new file mode 100644 index 0000000000..0c7079e3dd --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl @@ -0,0 +1,64 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// Unrecognmizable pragmas + +module M1 { + + typedef long T1; + + typedef long T2; + + + // Should be ID directive + +#pragma ShouldBeId T2 "DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3" + +}; + + // Should be prefix directive + +#pragma ShouldBePrefix "P1" + +module M2 { + + module M3 { + + // Should be prefix directive + +#pragma ShouldBePrefix "P2" + + interface I1 { + void foo( in short b, + out short c); + }; + typedef long T3; + }; + + + typedef long T4; + + + // Should be version + +#pragma ShouldBeVersion T4 2.4 + +}; + + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl new file mode 100644 index 0000000000..cbf053fac4 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl @@ -0,0 +1,28 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Version not in valid form : major.ninor + +module M1 { + + typedef long T4; + + #pragma version T4 2 + +}; diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl new file mode 100644 index 0000000000..b7c9da249f --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl @@ -0,0 +1,38 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// Bad pragma prefixs + +module M2 { + + module M3 { + +#pragma prefix P2 // Should be "P2" + + interface I1 { + void foo( in short b, + out short c); + }; + typedef long T3; + }; + + + typedef long T4; +}; + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl new file mode 100644 index 0000000000..349c13b244 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl @@ -0,0 +1,62 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% + +// Very uggly pragmas + + +#pragma prefix "P1" // Normal pragma + +module M4 { + + module M5 { + +#pragma prefix "P2" // Inside a parameter list + + interface I1 { + void Op( + #pragma prefix "P2" // Inside a parameter list + in short b, + #pragma prefix "P2" // Inside a parameter list + out short c + #pragma prefix "P2" // Inside a parameter list + ); + }; + typedef long T3; + }; + +}; + + + +/* + + Specified types with the following scoped names + and RepositoryIds + + ::M4::M5::T3 IDL:P2/T3:1.0 + +*/ + + + + + + + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/uggly.idl b/lib/ic/test/ic_pragma_SUITE_data/uggly.idl new file mode 100644 index 0000000000..8ed3ac57ec --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/uggly.idl @@ -0,0 +1,204 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// Really uggly pragmas + + +struct S { + +#pragma ID TDL1 "LOCAL:SomeLocalId:1" +#pragma ID TDL1 "LOCAL:SomeLocalId:2" + +long a + +#pragma ID TDL1 "LOCAL:SomeLocalId:3" +#pragma ID TDL1 "LOCAL:SomeLocalId:4" + +; + +#pragma ID TDL1 "LOCAL:SomeLocalId:5" +#pragma ID TDL1 "LOCAL:SomeLocalId:6" + +long b + +#pragma ID TDL1 "LOCAL:SomeLocalId:7" +#pragma ID TDL1 "LOCAL:SomeLocalId:8" + +; + + +#pragma ID TDL1 "LOCAL:SomeLocalId:9" +#pragma ID TDL1 "LOCAL:SomeLocalId:10" + +}; + + +typedef long TDL1; + + +exception Exc1{ + +#pragma version Exc1 2.2 +#pragma ID TDL2 "LOCAL:SomeLocalId:11" + +}; + + +typedef long TDL2; + + +exception Exc2 { + +#pragma version Exc2 2.2 +#pragma ID TDL3 "LOCAL:SomeLocalId:11" + + long a + +#pragma ID TDL3 "LOCAL:SomeLocalId:12" +#pragma ID TDL3 "LOCAL:SomeLocalId:13" + + ; + +#pragma ID TDL3 "LOCAL:SomeLocalId:14" +#pragma ID TDL3 "LOCAL:SomeLocalId:15" + + long b + +#pragma ID TDL3 "LOCAL:SomeLocalId:16" + + ; + +#pragma ID TDL3 "LOCAL:SomeLocalId:17" + + +}; + +typedef long TDL3; + +enum E { +#pragma ID E "LOCAL:SomeLocalId:18" + a +#pragma ID E "LOCAL:SomeLocalId:19" + , +#pragma ID E "LOCAL:SomeLocalId:20" + b +#pragma ID E "LOCAL:SomeLocalId:21" +, +#pragma ID E "LOCAL:SomeLocalId:22" + c +#pragma ID E "LOCAL:SomeLocalId:23" +}; + + + +union U switch (long) { + +#pragma ID TDL4 "LOCAL:SomeLocalId:24" + + case 1: + +#pragma ID TDL4 "LOCAL:SomeLocalId:25" + + long a + +#pragma ID TDL4 "LOCAL:SomeLocalId:26" + +; + +#pragma ID TDL4 "LOCAL:SomeLocalId:27" + + case 2: + +#pragma ID TDL4 "LOCAL:SomeLocalId:28" + + case 3: + +#pragma ID TDL4 "LOCAL:SomeLocalId:29" + +long b + +#pragma ID TDL4 "LOCAL:SomeLocalId:30" + +; + +#pragma ID TDL4 "LOCAL:SomeLocalId:31" + + default : + +#pragma ID TDL4 "LOCAL:SomeLocalId:32" + +long c + +#pragma ID TDL4 "LOCAL:SomeLocalId:33" + +; + +#pragma ID TDL4 "LOCAL:SomeLocalId:34" + +}; + + +typedef long TDL4; + + + +module M { + + interface I { + + void fun1( + +#pragma version fun1 3.0 +#pragma ID TDL5 "LOCAL:SomeLocalId:35" + + in short b + +#pragma ID TDL5 "LOCAL:SomeLocalId:36" +#pragma ID TDL5 "LOCAL:SomeLocalId:37" + + , + +#pragma ID TDL5 "LOCAL:SomeLocalId:38" +#pragma ID TDL5 "LOCAL:SomeLocalId:39" + + out short c + +#pragma ID TDL5 "LOCAL:SomeLocalId:40" +#pragma ID TDL5 "LOCAL:SomeLocalId:41" + + ); + + + typedef long TDL5; + + + void fun2( + +#pragma ID TDL6 "LOCAL:SomeLocalId:42" +#pragma ID TDL6 "LOCAL:SomeLocalId:43" + + ); + + typedef long TDL6; + + }; + + + +}; + diff --git a/lib/ic/test/ic_register_SUITE.erl b/lib/ic/test/ic_register_SUITE.erl new file mode 100644 index 0000000000..ae7578199a --- /dev/null +++ b/lib/ic/test/ic_register_SUITE.erl @@ -0,0 +1,425 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File: ic_register_SUITE.erl +%% +%% Description: +%% Test suite for the IFR object registration +%% +%%----------------------------------------------------------------- +-module(ic_register_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, init_all/1, finish_all/1, ifr_reg_unreg/1]). +-export([ifr_inheritence_reg/1,ifr_reg_unreg_with_inheritence/1]). +-export([ifr_reg_unreg_with_inheritence_bad_order/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). + +%%----------------------------------------------------------------- +%% Macros +%%----------------------------------------------------------------- +-define(REMAP_EXCEPT(F), case catch F of + {'EXCEPTION', E} -> exit(E); + R -> R + end). +%% Standard options to the ic compiler, NOTE unholy use of OutDir + +-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])). + + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [ifr_reg_unreg,ifr_reg_unreg_with_inheritence, + ifr_reg_unreg_with_inheritence_bad_order,ifr_inheritence_reg]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_all(Config) -> + io:format("Setting up.....~n"), + mnesia:stop(), + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + mnesia:start(), + orber:install([node()]), + orber:start(), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + io:format("Setting down.....~n"), + orber:stop(), + orber:uninstall(), + mnesia:stop(), + mnesia:delete_schema([node()]), + Config. + + + +%%----------------------------------------------------------------- +%% Test Case: IFR type registration +%%----------------------------------------------------------------- +ifr_reg_unreg(doc) -> + ["Checks that the generated register/unregister " + "code for the IFR is correct."]; +ifr_reg_unreg(suite) -> []; +ifr_reg_unreg(Config) when is_list(Config) -> + ?REMAP_EXCEPT(ifr_reg_unregt_run(Config)). + +ifr_reg_unregt_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_reg_unreg), + File0 = filename:join(DataDir, reg_m8), + File1 = filename:join(DataDir, reg_m9), + File2 = filename:join(DataDir, reg_m10), + ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File0, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = compile(OutDir, ifr_reg_unreg_files()), + code:add_pathz(OutDir), + ?line ok = 'oe_reg_m8':'oe_register'(), + ?line ok = 'oe_reg_m9':'oe_register'(), + ?line ok = 'oe_reg_m10':'oe_register'(), + ?line ok = 'oe_reg_m10':'oe_unregister'(), + ?line ok = 'oe_reg_m9':'oe_unregister'(), + ?line ok = 'oe_reg_m8':'oe_unregister'(), + code:del_path(OutDir), + ok. + +ifr_reg_unreg_files() -> ['oe_reg_m8', 'oe_reg_m9', 'oe_reg_m10']. + + + +%%----------------------------------------------------------------- +%% Test Case: IFR registration when object inheritence +%% is applied and registered. +%%----------------------------------------------------------------- +ifr_reg_unreg_with_inheritence(doc) -> + ["Checks that the generated register/unregister " + "code for the IFR is correct, and works even when" + "the object inheritence is registered. This fixes" + "two bugs in ifr that caused crash when trying to" + "use OE_register/OE_unregister in a sequence of" + "compiled files that contained interfaces who" + "inherited others in sequence."]; +ifr_reg_unreg_with_inheritence(suite) -> []; +ifr_reg_unreg_with_inheritence(Config) when is_list(Config) -> + ?REMAP_EXCEPT(ifr_reg_unreg_with_inheritence_run(Config)). + +ifr_reg_unreg_with_inheritence_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_reg_unreg), + File0 = filename:join(DataDir, reg_m8), + File1 = filename:join(DataDir, reg_m9), + File2 = filename:join(DataDir, reg_m10), + File3 = filename:join(DataDir, reg_m11), + File4 = filename:join(DataDir, reg_m12), + ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File0, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File3, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File3, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File4, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = compile(OutDir, ifr_reg_unreg_with_inheritence_files()), + code:add_pathz(OutDir), + ?line ok = 'oe_reg_m8':'oe_register'(), + ?line ok = 'oe_reg_m9':'oe_register'(), + ?line ok = 'oe_reg_m10':'oe_register'(), + ?line ok = 'oe_reg_m11':'oe_register'(), + ?line ok = 'oe_reg_m12':'oe_register'(), + ?line ok = 'oe_reg_m8':'oe_unregister'(), + ?line ok = 'oe_reg_m9':'oe_unregister'(), + ?line ok = 'oe_reg_m10':'oe_unregister'(), + ?line ok = 'oe_reg_m11':'oe_unregister'(), + ?line ok = 'oe_reg_m12':'oe_unregister'(), + code:del_path(OutDir), + ok. + +ifr_reg_unreg_with_inheritence_files() -> + ['oe_reg_m8', 'oe_reg_m9', 'oe_reg_m10', 'oe_reg_m11', 'oe_reg_m12']. + + + + + +%%----------------------------------------------------------------- +%% Test Case: IFR registration when object inheritence +%% is applied and registered in a bad order. +%% Modules included and used from an ifr object +%% are not allready registered when the current +%% object is getting registered. +%%----------------------------------------------------------------- +ifr_reg_unreg_with_inheritence_bad_order(doc) -> + ["This tests that ifr registration is done with + the right write order." + "Modules included and used from an ifr object" + "are tested if allready registered when the " + "current object is getting registered."]; +ifr_reg_unreg_with_inheritence_bad_order(suite) -> []; +ifr_reg_unreg_with_inheritence_bad_order(Config) when is_list(Config) -> + ?REMAP_EXCEPT(ifr_reg_unreg_with_inheritence_bad_order_run(Config)). + +ifr_reg_unreg_with_inheritence_bad_order_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_reg_unreg), + File1 = filename:join(DataDir, reg_m9), + File2 = filename:join(DataDir, reg_m10), + File4 = filename:join(DataDir, reg_m12), + ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File4, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = compile(OutDir, ifr_reg_unreg_with_inheritence_files()), + code:add_pathz(OutDir), + case catch 'oe_reg_m12':'oe_register'() of + {'EXIT',Reason1} -> + io:format("IFR object missing detected : ~p~n",[Reason1]), + true; + _ -> + test_server:fail("Failed to detect object missing : IDL:M1:1.0~n") + end, + ?line ok = 'oe_reg_m9':'oe_register'(), + case catch 'oe_reg_m10':'oe_register'() of + {'EXIT',Reason2} -> + io:format("IFR object missing detected : ~p~n",[Reason2]), + true; + _ -> + test_server:fail("Failed to detect object missing : IDL:M0:1.0~n") + end, + ?line ok = 'oe_reg_m9':'oe_unregister'(), + code:del_path(OutDir), + ok. + + + +%%----------------------------------------------------------------- +%% Test Case: IFR registration with inheritence +%%----------------------------------------------------------------- +ifr_inheritence_reg(doc) -> + ["Checks that IFR object inheritence is correctly registered."]; +ifr_inheritence_reg(suite) -> []; +ifr_inheritence_reg(Config) when is_list(Config) -> + ?REMAP_EXCEPT(ifr_inh_reg_run(Config)). + +ifr_inh_reg_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_reg_unreg), + File0 = filename:join(DataDir, reg_m8), + File1 = filename:join(DataDir, reg_m9), + File2 = filename:join(DataDir, reg_m10), + File3 = filename:join(DataDir, reg_m11), + File4 = filename:join(DataDir, reg_m12), + ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File0, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File3, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File3, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File4, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = compile(OutDir, ifr_reg_unreg_with_inheritence_files()), + code:add_pathz(OutDir), + %% OE_register for all files + ?line ok = 'oe_reg_m8':'oe_register'(), + ?line ok = 'oe_reg_m9':'oe_register'(), + ?line ok = 'oe_reg_m10':'oe_register'(), + ?line ok = 'oe_reg_m11':'oe_register'(), + ?line ok = 'oe_reg_m12':'oe_register'(), + + %% Inheritence registration test + OE_IFR = orber_ifr:find_repository(), + %% Interfaces that not inherit from other interfaces + ?line [] = get_inh(OE_IFR, "IDL:m0/i0:1.0"), + ?line [] = get_inh(OE_IFR, "IDL:m1/i1:1.0"), + ?line [] = get_inh(OE_IFR, "IDL:m3/i3:1.0"), + %% Interfaces that inherit from other interfaces + ?line ["IDL:m1/i1:1.0"] = get_inh(OE_IFR, "IDL:m2/i2:1.0"), + ?line ["IDL:m1/i1:1.0","IDL:m2/i2:1.0"] = get_inh(OE_IFR, "IDL:m4/i4:1.0"), + ?line ["IDL:m3/i3:1.0"] = get_inh(OE_IFR, "IDL:m4/i5:1.0"), + + %% OE_unregister for all files + ?line ok = 'oe_reg_m8':'oe_unregister'(), + ?line ok = 'oe_reg_m9':'oe_unregister'(), + ?line ok = 'oe_reg_m10':'oe_unregister'(), + ?line ok = 'oe_reg_m11':'oe_unregister'(), + ?line ok = 'oe_reg_m12':'oe_unregister'(), + code:del_path(OutDir), + ok. + + +get_inh(OE_IFR,ID) -> + OE_CURRENT = orber_ifr:lookup_id(OE_IFR,ID), + INH_LIST = orber_ifr:get_base_interfaces(OE_CURRENT), + case INH_LIST of + [] -> + io:format("~nInterface ~p inherits from nobody.~n",[ID]), + []; + _ -> + print_inh_list_ids(ID, INH_LIST, []) + end. + +print_inh_list_ids(_ID, [], Acc) -> + lists:reverse(Acc); +print_inh_list_ids(ID, [H|T], Acc) -> + io:format("~n"), + Parent = orber_ifr:get_id(H), + io:format("Interface ~p inherits from ~p.~n", [ID, Parent]), + print_inh_list_ids(ID, T, [Parent|Acc]). + + + + +stdopts(OutDir) -> + [{outdir, OutDir}, {maxerrs, infinity}]. + + +compile(Dir, Files) -> + compile(Dir, Files, []). + +compile(Dir, Files, Opts) -> + {ok, Cwd} = file:get_cwd(), + file:set_cwd(Dir), + io:format("Changing to ~p~n", [Dir]), + case catch do_compile(Files, Opts) of + ok -> + file:set_cwd(Cwd); + Err -> + file:set_cwd(Cwd), + test_server:fail(Err) + end. + +do_compile([], _Opts) -> ok; +do_compile([F | Fs], Opts) -> + io:format("Compiling ~p", [F]), + case compile:file(F, Opts) of + ok -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + Err -> + io:format(" error: ~p~n", [Err]), + Err + end. + +do_load(File, Opts) -> + case lists:member(load, Opts) of + true -> + io:format("Loading file ~p", [File]), + code:purge(File), + R = code:load_abs(File), + io:format("Loaded: ~p", [R]); + false -> + ok + end. + + +to_list(X) when is_atom(X) -> atom_to_list(X); +to_list(X) -> X. + + + + + + + + + + + + + + + + + + diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m10.idl b/lib/ic/test/ic_register_SUITE_data/reg_m10.idl new file mode 100644 index 0000000000..9c1f126b64 --- /dev/null +++ b/lib/ic/test/ic_register_SUITE_data/reg_m10.idl @@ -0,0 +1,37 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// +// IDL for testing register/unregister in the IFR when using included specs +// +#include "reg_m9.idl" + +typedef sequence<long> Sequence1; + +#include "reg_m8.idl" + +module m2 { + + interface i2 : m1::i1 + { + short op3( in long a, inout char b, out long c ); + }; + + +}; + diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m11.idl b/lib/ic/test/ic_register_SUITE_data/reg_m11.idl new file mode 100644 index 0000000000..607d695357 --- /dev/null +++ b/lib/ic/test/ic_register_SUITE_data/reg_m11.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// +// IDL for testing register/unregister in the IFR when using included specs +// + +module m3 { + + interface i3 + { + short op4( in long a, inout char b, out long c ); + }; + + +}; + diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m12.idl b/lib/ic/test/ic_register_SUITE_data/reg_m12.idl new file mode 100644 index 0000000000..3dd9267655 --- /dev/null +++ b/lib/ic/test/ic_register_SUITE_data/reg_m12.idl @@ -0,0 +1,40 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// +// IDL for testing register/unregister in the IFR when using included specs +// Special case with multiple inheritence. +// +#include "reg_m10.idl" +#include "reg_m11.idl" + +module m4 { + + interface i4 : m2::i2 + { + short op5( in long a, inout char b, out long c ); + }; + + interface i5 : m3::i3 + { + short op6( in long a, inout char b, out long c ); + }; + + +}; + diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m8.idl b/lib/ic/test/ic_register_SUITE_data/reg_m8.idl new file mode 100644 index 0000000000..dc7432c05d --- /dev/null +++ b/lib/ic/test/ic_register_SUITE_data/reg_m8.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// +// IDL for testing register/unregister in the IFR when using included specs +// +module m0 { + + interface i0 { + void op1( in short c ); + float op2( in char a); + + }; + + +}; + diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m9.idl b/lib/ic/test/ic_register_SUITE_data/reg_m9.idl new file mode 100644 index 0000000000..e937c41608 --- /dev/null +++ b/lib/ic/test/ic_register_SUITE_data/reg_m9.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// +// IDL for testing register/unregister in the IFR when using included specs +// +module m1 { + + interface i1 { + void op1( in short c ); + float op2( in char a); + + }; + + +}; + diff --git a/lib/ic/test/java_client_erl_server_SUITE.erl b/lib/ic/test/java_client_erl_server_SUITE.erl new file mode 100644 index 0000000000..ee77ef0c4e --- /dev/null +++ b/lib/ic/test/java_client_erl_server_SUITE.erl @@ -0,0 +1,330 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%%---------------------------------------------------------------------- +%%% Purpose : Test suite for the backends of the IDL compiler +%%%---------------------------------------------------------------------- + +-module(java_client_erl_server_SUITE). +-include("test_server.hrl"). + + +-export([all/1,init_all/1,finish_all/1,init_per_testcase/2,fin_per_testcase/2]). +-export([marshal_ll/1,marshal_ull/1, + marshal_l/1,marshal_ul/1, + marshal_s/1,marshal_us/1, + marshal_c/1,marshal_wc/1, + marshal_str/1, + marshal_any_3/1,marshal_any_2/1]). + + +%% Top of cases + +all(doc) -> + "Test of IC with a Java-client and an Erlang generic server. " + "The communication is via Erlang distribution."; +all(suite) -> {conf,init_all,cases(),finish_all}. + +cases() -> [marshal_ll,marshal_ull, + marshal_l,marshal_ul, + marshal_s,marshal_us, + marshal_c,marshal_wc, + marshal_str, + marshal_any_3,marshal_any_2]. + +init_all(Config) when is_list(Config) -> + case case code:priv_dir(jinterface) of + {error,bad_name} -> + false; + P -> + filelib:is_dir(P) + end + of + true -> + case find_executable(["java"]) of + false -> + {skip,"Found no Java VM"}; + Path -> + [{java,Path}|Config] + end; + false -> + {skip,"No jinterface application"} + end. + + +find_executable([]) -> + false; +find_executable([E|T]) -> + case os:find_executable(E) of + false -> find_executable(T); + Path -> Path + end. + +finish_all(Config) -> Config. + + + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i et,al, we have + %% to make sure we are using the right modules. + code:purge(m_i), + code:purge(m_i_impl), + code:purge(oe_java_erl_test), + code:load_file(m_i), + code:load_file(m_i_impl), + code:load_file(oe_java_erl_test), + + WatchDog = test_server:timetrap(test_server:seconds(20)), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + + + +%%-------------------------------------------------------------------- +%% +%% Test cases + +marshal_ll(doc) -> + ["Testing marshalling of IDL long long"]; +marshal_ll(suite) -> []; +marshal_ll(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_ll}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_ll]), + ?line ok = m_i:stop(Server), + ok. + +marshal_ull(doc) -> + ["Testing marshalling of IDL unsigned long long"]; +marshal_ull(suite) -> []; +marshal_ull(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_ull}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_ull]), + ?line ok = m_i:stop(Server), + ok. + +marshal_l(doc) -> + ["Testing marshalling of IDL long"]; +marshal_l(suite) -> []; +marshal_l(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_l}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_l]), + ?line ok = m_i:stop(Server), + ok. + +marshal_ul(doc) -> + ["Testing marshalling of IDL unsigned long"]; +marshal_ul(suite) -> []; +marshal_ul(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_ul}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_ul]), + ?line ok = m_i:stop(Server), + ok. + +marshal_s(doc) -> + ["Testing marshalling of IDL short"]; +marshal_s(suite) -> []; +marshal_s(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_s}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_s]), + ?line ok = m_i:stop(Server), + ok. + +marshal_us(doc) -> + ["Testing marshalling of IDL unsigned short"]; +marshal_us(suite) -> []; +marshal_us(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_us}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_us]), + ?line ok = m_i:stop(Server), + ok. + +marshal_c(doc) -> + ["Testing marshalling of IDL char"]; +marshal_c(suite) -> []; +marshal_c(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_c}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_c]), + ?line ok = m_i:stop(Server), + ok. + +marshal_wc(doc) -> + ["Testing marshalling of IDL char"]; +marshal_wc(suite) -> []; +marshal_wc(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_wc}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_wc]), + ?line ok = m_i:stop(Server), + ok. + +marshal_str(doc) -> + ["Testing marshalling of IDL string"]; +marshal_str(suite) -> []; +marshal_str(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_str}), + ?line ok = java(?config(java, Config), DataDir, +%%% "-DOtpConnection.trace=4 " + "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_str]), + ?line ok = m_i:stop(Server), + ok. + +marshal_any_3(doc) -> + ["Testing marshalling of IDL any"]; +marshal_any_3(suite) -> []; +marshal_any_3(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_any_3}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_any_3]), + ?line ok = m_i:stop(Server), + ok. + +marshal_any_2(doc) -> + ["Testing marshalling of IDL any"]; +marshal_any_2(suite) -> []; +marshal_any_2(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_any_2}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_any_2]), + ?line ok = m_i:stop(Server), + ok. + +%%-------------------------------------------------------------------- +%% +%% Utilities + + +java(Java, Dir, ClassAndArgs) -> + cmd(Java++" -classpath "++classpath(Dir)++" "++ClassAndArgs). + +java(Java, Dir, Class, Args) -> + java(Java, Dir, Class++" "++to_string(Args)). + +to_string([H|T]) when is_integer(H) -> + integer_to_list(H)++" "++to_string(T); +to_string([H|T]) when is_atom(H) -> + atom_to_list(H)++" "++to_string(T); +to_string([H|T]) when is_list(H) -> + lists:flatten(H)++" "++to_string(T); +to_string([]) -> []. + +% javac(Dir, File) -> +% cmd("javac -d "++Dir++" -classpath "++classpath(Dir)++" "++ +% filename:join(Dir, File)). + +classpath(Dir) -> + PS = + case os:type() of + {win32, _} -> ";"; + _ -> ":" + end, + Dir++PS++ + filename:join([code:lib_dir(ic),"priv","ic.jar"])++PS++ + filename:join([code:lib_dir(jinterface),"priv","OtpErlang.jar"])++PS++ + case os:getenv("CLASSPATH") of + false -> ""; + Classpath -> Classpath + end. + + +cmd(Cmd) -> + PortOpts = [{line,80},eof,exit_status,stderr_to_stdout], + io:format("<cmd> ~s~n", [Cmd]), + case catch open_port({spawn,Cmd}, PortOpts) of + Port when is_port(Port) -> + Result = cmd_loop(Port, []), + io:format("<cmd=~w>~n", [Result]), + case Result of + 0 -> ok; + ExitCode when is_integer(ExitCode) -> {error,ExitCode}; + Error -> Error + end; + {'EXIT',Reason} -> + {error,Reason} + end. + +cmd_loop(Port, Line) -> + receive + {Port,eof} -> + receive + {Port,{exit_status,ExitStatus}} -> + ExitStatus + after 1 -> + undefined + end; + {Port,{exit_status,ExitStatus}} -> + receive + {Port,eof} -> + ok after 1 -> ok end, + ExitStatus; + {Port,{data,{Tag,Data}}} -> + case Tag of + eol -> + io:put_chars([Line|cr_to_nl(Data)]), + io:nl(), + cmd_loop(Port, []); + noeol -> + cmd_loop(Port, [Line|cr_to_nl(Data)]) + end; + {'EXIT',Port,Reason} -> + {error,Reason}; + Other -> + io:format("WARNING: Unexpected at ~s:~p: ~p~n", + [?MODULE_STRING,?LINE,Other]), + cmd_loop(Port, Line) + end. + +%% Convert lonely CR to NL, and CRLF to NL +%% +cr_to_nl([$\r,$\n|T]) -> + [$\n|cr_to_nl(T)]; +cr_to_nl([$\r|T]) -> + [$\n|cr_to_nl(T)]; +cr_to_nl([C|T]) -> + [C|cr_to_nl(T)]; +cr_to_nl([]) -> + []. diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java b/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java new file mode 100644 index 0000000000..1881279ac8 --- /dev/null +++ b/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java @@ -0,0 +1,759 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ +public class JavaClient { + + public static void main(String[] argv) + { + System.out.println("Hello World!"); + if (argv.length < 4) { + System.out.println("Too few arguments!"); + System.exit(1); + } + // for (int j = 0; j < argv.length; j++) + // System.out.println(argv[j]); + try { + if (argv[3].equals("marshal_ll")) { + System.out.println("marshal_ll"); + marshal_ll(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_ull")) { + marshal_ull(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_l")) { + marshal_l(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_ul")) { + marshal_ul(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_s")) { + marshal_s(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_us")) { + marshal_us(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_c")) { + marshal_c(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_wc")) { + marshal_wc(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_str")) { + marshal_str(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_any_3")) { + marshal_any_3(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_any_2")) { + marshal_any_2(argv[0], argv[1], argv[2], argv[3]); + } + else { + System.out.println("Unknown test: "+argv[3]); + System.exit(2); + } + } catch (java.lang.Exception e) { + System.out.println("Exception!: "+e); + System.exit(3); + } + System.exit(0); + } + + + + static void marshal_ll(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + System.out.println("Just warming up.."+i); + verify_ll(i, 3, 2, 1); + verify_ll(i, 5, 4, 3); + verify_ll(i, -128, 0, 1); + // The small integer border + verify_ll(i, 255, 0, 1); + verify_ll(i, 256, 0, 1); + // The integer border + verify_ll(i, (1L<<26)-1L, 0L, 1); + verify_ll(i, 1L<<26, 0L, 1); + verify_ll(i, -(1L<<26), 0L, 1); + verify_ll(i, (1L<<27)-1L, 0L, 1); + verify_ll(i, 1L<<27, 0L, 1); + verify_ll(i, -(1L<<27), 0L, 1); + // Bignum byte borders + verify_ll(i, (1L<<32)-1L, 0L, 1); + verify_ll(i, 1L<<32, 0L, 1); + verify_ll(i, -(1L<<32)+1L, 0L, 1); + verify_ll(i, -(1L<<32), 0L, 1); + verify_ll(i, (1L<<40)-1L, 0L, 1); + verify_ll(i, 1L<<40, 0L, 1); + verify_ll(i, -(1L<<40)+1L, 0L, 1); + verify_ll(i, -(1L<<40), 0L, 1); + verify_ll(i, (1L<<48)-1L, 0L, 1); + verify_ll(i, 1L<<48, 0L, 1); + verify_ll(i, -(1L<<48)+1L, 0L, 1); + verify_ll(i, -(1L<<48), 0L, 1); + // Java long border + verify_ll(i, java.lang.Long.MAX_VALUE, 0L, 1); + verify_ll(i, java.lang.Long.MIN_VALUE, 0L, 1); + verify_ll(i, -1L, 0L, 1); + // Impossible decodes + verify_ll_bad(i, java.lang.Long.MAX_VALUE, -1L, 1); + verify_ll_bad(i, java.lang.Long.MIN_VALUE, 1L, 1); + verify_ll_bad(i, java.lang.Long.MIN_VALUE, 0L, -1); + verify_ll_bad(i, java.lang.Long.MAX_VALUE, -1L, 2); + verify_ll_bad(i, java.lang.Long.MIN_VALUE, 0L, 2); + } + + static void marshal_ull(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_ull(i, 3, 2, 1); + verify_ull(i, 5, 4, 3); + // The small integer border + verify_ull(i, 255, 0, 1); + verify_ull(i, 256, 0, 1); + // The integer border + verify_ull(i, (1L<<26)-1L, 0L, 1); + verify_ull(i, 1L<<26, 0L, 1); + verify_ull(i, (1L<<27)-1L, 0L, 1); + verify_ull(i, 1L<<27, 0L, 1); + // Bignum byte borders + verify_ull(i, (1L<<32)-1L, 0L, 1); + verify_ull(i, 1L<<32, 0L, 1); + verify_ull(i, (1L<<40)-1L, 0L, 1); + verify_ull(i, 1L<<40, 0L, 1); + verify_ull(i, (1L<<48)-1L, 0L, 1); + verify_ull(i, 1L<<48, 0L, 1); + // Java long border + verify_ull(i, java.lang.Long.MAX_VALUE, 0L, 1); + verify_ull(i, java.lang.Long.MIN_VALUE, 0L, 1); + verify_ull(i, -1L, 0L, 1); + verify_ull(i, java.lang.Long.MAX_VALUE, + java.lang.Long.MIN_VALUE, 1); + // Impossible decodes + verify_ull_bad(i, -1L, -1L, 1); + verify_ull_bad(i, java.lang.Long.MAX_VALUE, -1L, 2); + } + + static void marshal_l(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_l(i, 3, 2, 1); + verify_l(i, 5, 4, 3); + verify_l(i, -128, 0, 1); + // The small integer border + verify_l(i, 255, 0, 1); + verify_l(i, 256, 0, 1); + // The integer border + verify_l(i, (1<<26)-1, 0, 1); + verify_l(i, 1<<26, 0, 1); + verify_l(i, -(1<<26), 0, 1); + verify_l(i, (1<<27)-1, 0, 1); + verify_l(i, 1<<27, 0, 1); + verify_l(i, -(1<<27), 0, 1); + // Java int border + verify_l(i, java.lang.Integer.MAX_VALUE, 0, 1); + verify_l(i, java.lang.Integer.MIN_VALUE, 0, 1); + // Impossible decodes + verify_l_bad(i, java.lang.Integer.MAX_VALUE, -1, 1); + verify_l_bad(i, java.lang.Integer.MIN_VALUE, 1, 1); + verify_l_bad(i, java.lang.Integer.MIN_VALUE, 0, -1); + } + + static void marshal_ul(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_ul(i, 3, 2, 1); + verify_ul(i, 5, 4, 3); + // The small integer border + verify_ul(i, 255, 0, 1); + verify_ul(i, 256, 0, 1); + // The integer border + verify_ul(i, (1<<26)-1, 0, 1); + verify_ul(i, 1<<26, 0, 1); + verify_ul(i, (1<<27)-1, 0, 1); + verify_ul(i, 1<<27, 0, 1); + // Java int border + verify_ul(i, java.lang.Integer.MAX_VALUE, 0, 1); + verify_ul(i, java.lang.Integer.MIN_VALUE, 0, 1); + verify_ul(i, -1, 0, 1); + verify_ul(i, java.lang.Integer.MAX_VALUE, + java.lang.Integer.MIN_VALUE, 1); + // Impossible decodes + verify_ul_bad(i, -1, -1, 1); + } + + static void marshal_s(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_s(i, 3, 2, 1); + verify_s(i, 5, 4, 3); + verify_s(i, -128, 0, 1); + // The small integer border + verify_s(i, 255, 0, 1); + verify_s(i, 256, 0, 1); + // Java short border + verify_s(i, java.lang.Short.MAX_VALUE, 0, 1); + verify_s(i, java.lang.Short.MIN_VALUE, 0, 1); + // Impossible decodes + verify_s_bad(i, java.lang.Short.MAX_VALUE, -1, 1); + verify_s_bad(i, java.lang.Short.MIN_VALUE, 1, 1); + verify_s_bad(i, java.lang.Short.MIN_VALUE, 0, -1); + } + + static void marshal_us(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_us(i, 3, 2, 1); + verify_us(i, 5, 4, 3); + // The small integer border + verify_us(i, 255, 0, 1); + verify_us(i, 256, 0, 1); + // Java short border + verify_us(i, java.lang.Short.MAX_VALUE, 0, 1); + verify_us(i, java.lang.Short.MIN_VALUE, 0, 1); + verify_us(i, -1, 0, 1); + verify_us(i, java.lang.Short.MAX_VALUE, + java.lang.Short.MIN_VALUE, 1); + // Impossible decodes + verify_us_bad(i, -1, -1, 1); + } + + static void marshal_c(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_c(i, '\3', '\2', 1); + verify_c(i, '\5', '\4', 3); + // The small integer border + verify_c(i, '\u00FF', '\0', 1); + verify_c(i, '\u0100', '\0', 1); + // Java char border + verify_c(i, java.lang.Character.MAX_VALUE, '\0', 1); + verify_c(i, java.lang.Character.MIN_VALUE, '\0', 1); + verify_c(i, java.lang.Character.MAX_VALUE, + java.lang.Character.MIN_VALUE, 1); + // Impossible decodes + verify_c_bad(i, '\u8000', '\0', 2); + } + + static void marshal_wc(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_wc(i, '\3', '\2', 1); + verify_wc(i, '\5', '\4', 3); + // The small integer border + verify_wc(i, '\u00FF', '\0', 1); + verify_wc(i, '\u0100', '\0', 1); + // Java char border + verify_wc(i, java.lang.Character.MAX_VALUE, '\0', 1); + verify_wc(i, java.lang.Character.MIN_VALUE, '\0', 1); + verify_wc(i, java.lang.Character.MAX_VALUE, + java.lang.Character.MIN_VALUE, 1); + // Impossible decodes + verify_c_bad(i, '\u8000', '\0', 2); + } + + static void marshal_str(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_str(i, 100, 100); + verify_str(i, 100, 1); + // Erlang string border + verify_str(i, 65535, 1); + verify_str(i, 2, 65535); + // Erlang string border out + verify_str(i, 65536, 1); + verify_str(i, 65536, 65536); + } + + static void marshal_any_3(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + com.ericsson.otp.ic.Any x = new com.ericsson.otp.ic.Any(); + com.ericsson.otp.ic.Any y = new com.ericsson.otp.ic.Any(); + com.ericsson.otp.ic.Any z = new com.ericsson.otp.ic.Any(); + + x.insert_longlong(java.lang.Long.MAX_VALUE); + y.insert_longlong(1L); + z.insert_longlong(java.lang.Long.MAX_VALUE-1L); + System.out.println("verify_any_3 longlong max"); + verify_any_3(i, x, y, 1, z); + + x.insert_longlong(java.lang.Long.MIN_VALUE); + y.insert_longlong(-1L); + z.insert_longlong(java.lang.Long.MIN_VALUE+1L); + System.out.println("verify_any_3 longlong min"); + verify_any_3(i, x, y, 1, z); + + x.insert_ulonglong(-1L); + y.insert_longlong(1L); + z.insert_ulonglong(-2L); + System.out.println("verify_any_3 ulonglong max"); + verify_any_3(i, x, y, 1, z); + + x.insert_ulonglong(0L); + y.insert_longlong(-1L); + z.insert_ulonglong(1L); + System.out.println("verify_any_3 ulonglong min"); + verify_any_3(i, x, y, 1, z); + + x.insert_long(java.lang.Integer.MAX_VALUE); + y.insert_long(1); + z.insert_long(java.lang.Integer.MAX_VALUE-1); + System.out.println("verify_any_3 long max"); + verify_any_3(i, x, y, 1, z); + + x.insert_long(java.lang.Integer.MIN_VALUE); + y.insert_long(-1); + z.insert_long(java.lang.Integer.MIN_VALUE+1); + System.out.println("verify_any_3 long min"); + verify_any_3(i, x, y, 1, z); + + x.insert_ulong(-1); + y.insert_long(1); + z.insert_ulong(-2); + System.out.println("verify_any_3 ulong max"); + verify_any_3(i, x, y, 1, z); + + x.insert_ulong(0); + y.insert_long(-1); + z.insert_ulong(1); + System.out.println("verify_any_3 ulong min"); + verify_any_3(i, x, y, 1, z); + + x.insert_short(java.lang.Short.MAX_VALUE); + y.insert_short((short)1); + z.insert_short((short)(java.lang.Short.MAX_VALUE-1)); + System.out.println("verify_any_3 short max"); + verify_any_3(i, x, y, 1, z); + + x.insert_short(java.lang.Short.MIN_VALUE); + y.insert_short((short)-1); + z.insert_short((short)(java.lang.Short.MIN_VALUE+1)); + System.out.println("verify_any_3 short min"); + verify_any_3(i, x, y, 1, z); + + x.insert_ushort((short)-1); + y.insert_short((short)1); + z.insert_ushort((short)-2); + System.out.println("verify_any_3 ushort max"); + verify_any_3(i, x, y, 1, z); + + x.insert_ushort((short)0); + y.insert_short((short)-1); + z.insert_ushort((short)1); + System.out.println("verify_any_3 ushort min"); + verify_any_3(i, x, y, 1, z); + + x.insert_char('\377'); + y.insert_char('\1'); + z.insert_char('\376'); + System.out.println("verify_any_3 char max"); + verify_any_3(i, x, y, 1, z); + + x.insert_wchar('\uFFFF'); + y.insert_wchar('\u0001'); + z.insert_wchar('\uFFFE'); + System.out.println("verify_any_3 char max"); + verify_any_3(i, x, y, 1, z); + } + + static void marshal_any_2(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + m.s s = new m.s(); + com.ericsson.otp.ic.Any a = new com.ericsson.otp.ic.Any(); + // + s.ull_x = -1L; + s.ll_x = java.lang.Long.MAX_VALUE; + s.ll_y = 1L; + s.ull_z = -2L; + s.ll_z = java.lang.Long.MAX_VALUE-1L; + // + s.ul_x = -1; + s.l_x = java.lang.Integer.MAX_VALUE; + s.l_y = 1; + s.ul_z = -2; + s.l_z = java.lang.Integer.MAX_VALUE-1; + // + s.us_x = (short)-1; + s.s_x = java.lang.Short.MAX_VALUE; + s.s_y = (short)1; + s.us_z = (short)-2; + s.s_z = (short)(java.lang.Short.MAX_VALUE-1); + // + s.c_x = '\377'; + s.c_y = '\1'; + s.c_z = '\376'; + s.wc_x = '\uFFFF'; + s.wc_y = '\u0001'; + s.wc_z = '\uFFFE'; + m.sHelper.insert(a, s); + verify_any_2(i, a, 1); + + s.ull_x = 0L; + s.ll_x = java.lang.Long.MIN_VALUE; + s.ll_y = -1L; + s.ull_z = 1L; + s.ll_z = java.lang.Long.MIN_VALUE+1L; + // + s.ul_x = 0; + s.l_x = java.lang.Integer.MIN_VALUE; + s.l_y = -1; + s.ul_z = 1; + s.l_z = java.lang.Integer.MIN_VALUE+1; + // + s.us_x = (short)0; + s.s_x = java.lang.Short.MIN_VALUE; + s.s_y = (short)-1; + s.us_z = (short)1; + s.s_z = (short)(java.lang.Short.MIN_VALUE+1); + // + s.c_x = '\0'; + s.c_y = '\0'; + s.c_z = '\0'; + s.wc_x = '\u0000'; + s.wc_y = '\u0000'; + s.wc_z = '\u0000'; + m.sHelper.insert(a, s); + verify_any_2(i, a, 1); + } + + + static void verify_ll(m._iStub i, long x, long y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + System.out.println("verify_ll "+a); + a.ll_x = x; + a.ll_y = y; + long expected = (x - y)*(short)b; + long result = i.marshal_ll(a, (short)b); + if (result == expected) { + System.out.println("verify_ll("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_ll("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_ull(m._iStub i, long x, long y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.ull_x = x; + a.ll_y = y; + long expected = (x - y)*(short)b; + long result = i.marshal_ull(a, (short)b); + if (result == expected) { + System.out.println("verify_ull("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_ull("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_l(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.l_x = x; + a.l_y = y; + int expected = (x - y)*(short)b; + int result = i.marshal_l(a, (short)b); + if (result == expected) { + System.out.println("verify_l("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_l("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_ul(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.ul_x = x; + a.l_y = y; + int expected = (x - y)*(short)b; + int result = i.marshal_ul(a, (short)b); + if (result == expected) { + System.out.println("verify_ul("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_ul("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_s(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.s_x = (short)x; + a.s_y = (short)y; + short expected = (short)((x - y)*(short)b); + short result = i.marshal_s(a, (short)b); + if (result == expected) { + System.out.println("verify_s("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_s("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_us(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.us_x = (short)x; + a.s_y = (short)y; + short expected = (short)((x - y)*(short)b); + short result = i.marshal_us(a, (short)b); + if (result == expected) { + System.out.println("verify_us("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_us("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_c(m._iStub i, char x, char y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.c_x = x; + a.c_y = y; + char expected = (char)(((int)x - (int)y)*(short)b); + char result = i.marshal_c(a, (short)b); + if (result == expected) { + System.out.println("verify_c("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_c("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_wc(m._iStub i, char x, char y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.wc_x = x; + a.wc_y = y; + char expected = (char)(((int)x - (int)y)*(short)b); + char result = i.marshal_wc(a, (short)b); + if (result == expected) { + System.out.println("verify_wc("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_wc("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_str(m._iStub i, int a_len, int b_len) + throws java.lang.Exception + { + String a = mk_str(a_len); + String b = mk_str(b_len); + String expected = a + b; + String result = i.strcat(a, b); + if (result.equals(expected)) { + System.out.println("verify_str(\""+a+"\", \""+b+"\") => \"" + +result+"\""); + } else { + System.out.println("verify_str(\""+a+"\", \""+b+"\") => \"" + +result+"\" != \""+expected.length()+"\""); + System.exit(4); + } + } + + static String mk_str(int len) + throws StringIndexOutOfBoundsException + { + StringBuffer s = new StringBuffer(); + // 17 characters is prime relative all bases of two - on purpose + do s.append("qwertyuiopasdfghj"); while (s.length() < len); + return s.substring(0, len); + } + + static void verify_any_3(m._iStub i, + com.ericsson.otp.ic.Any x, + com.ericsson.otp.ic.Any y, + int b, + com.ericsson.otp.ic.Any expected) + throws java.lang.Exception + { + com.ericsson.otp.ic.Any result = i.marshal_any_3(x, y, (short)b); + if (! expected.equal(result)) { + System.exit(4); + } + } + + static void verify_any_2(m._iStub i, com.ericsson.otp.ic.Any a, int b) + throws java.lang.Exception + { + com.ericsson.otp.ic.Any result = i.marshal_any_2(a, (short)b); + if (! a.equal(result)) { + System.exit(4); + } + } + + + + static void verify_ll_bad(m._iStub i, long x, long y, int b) + throws java.lang.Exception + { + try { + verify_ll(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_ull_bad(m._iStub i, long x, long y, int b) + throws java.lang.Exception + { + try { + verify_ull(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_l_bad(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + try { + verify_l(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_ul_bad(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + try { + verify_ul(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_s_bad(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + try { + verify_s(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_us_bad(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + try { + verify_us(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_c_bad(m._iStub i, char x, char y, int b) + throws java.lang.Exception + { + try { + verify_c(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_wc_bad(m._iStub i, char x, char y, int b) + throws java.lang.Exception + { + try { + verify_wc(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + +} diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src new file mode 100644 index 0000000000..de1503401c --- /dev/null +++ b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src @@ -0,0 +1,88 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2003-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +# Makefile.src for java_client_erl_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .erl .idl .@EMULATOR@ .java + + +JAVAC = @JAVAC@ +ERLC = erlc + +# ic variables available from ts: +# +# ic_libpath: @ic_libpath@ +# ic_include_path: @ic_include_path@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_CLASSPATH = @ic_classpath@ + +JINTERFACE_CLASSPATH = @jinterface_classpath@ + +CLASSPATH = .@PS@$(IC_CLASSPATH)@PS@$(JINTERFACE_CLASSPATH)@PS@ + +GEN_JAVA_FILES = \ + m@DS@_iImplBase.java \ + m@DS@_iStub.java \ + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_java_erl_test.hrl + +GEN_ERL_FILES = \ + m_i.erl \ + oe_java_erl_test.erl + +JAVA_FILES = $(GEN_JAVA_FILES) JavaClient.java +CLASS_FILES = $(JAVA_FILES:.java=.class) +ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(CLASS_FILES) $(EBINS) + +clean: + -rm -f $(GEN_JAVA_FILES) $(CLASS_FILES) \ + $(GEN_ERL_FILES) $(GEN_HRL_FILES) $(EBINS) + -del /F /Q $(GEN_JAVA_FILES) $(CLASS_FILES) \ + $(GEN_ERL_FILES) $(GEN_HRL_FILES) $(EBINS) + +$(GEN_JAVA_FILES) : java_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,java}" java_erl_test.idl + +$(CLASS_FILES) : $(JAVA_FILES) + $(JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES) + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): java_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" java_erl_test.idl + +.erl.@EMULATOR@: + $(ERLC) -I $(IC_INCLUDE_PATH) $< diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl b/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl new file mode 100644 index 0000000000..b72c972d3b --- /dev/null +++ b/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl @@ -0,0 +1,68 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2003-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +module m { + + struct s { + long long ll_x; + unsigned long long ull_x; + long long ll_y; + long long ll_z; + unsigned long long ull_z; + + long l_x; + unsigned long ul_x; + long l_y; + long l_z; + unsigned long ul_z; + + short s_x; + unsigned short us_x; + short s_y; + short s_z; + unsigned short us_z; + + char c_x; + char c_y; + char c_z; + + wchar wc_x; + wchar wc_y; + wchar wc_z; + }; + + interface i { + long long marshal_ll( in s a, in short b ); + unsigned long long marshal_ull( in s a, in short b ); + + long marshal_l( in s a, in short b ); + unsigned long marshal_ul( in s a, in short b ); + + short marshal_s( in s a, in short b ); + unsigned short marshal_us( in s a, in short b ); + + char marshal_c( in s a, in short b ); + wchar marshal_wc( in s a, in short b ); + + string strcat( in string a, in string b ); + + any marshal_any_3( in any x, in any y, in short b ); + any marshal_any_2( in any a, in short b ); + }; + +}; diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl b/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl new file mode 100644 index 0000000000..77e532288f --- /dev/null +++ b/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl @@ -0,0 +1,169 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%%-------------------------------------------------------------------- +-module(m_i_impl). + +-export([marshal_ll/3,marshal_ull/3, + marshal_l/3,marshal_ul/3, + marshal_s/3,marshal_us/3, + marshal_c/3,marshal_wc/3, + strcat/3, + marshal_any_3/4,marshal_any_2/3]). +-export([init/1,terminate/2,code_change/3]). + +-include("m.hrl"). + +-define(TK_M_S, {tk_struct, + "IDL:m/s:1.0", + "s", + [{"ll_x",tk_longlong}, + {"ull_x",tk_ulonglong}, + {"ll_y",tk_longlong}, + {"ll_z",tk_longlong}, + {"ull_z",tk_ulonglong}, + {"l_x",tk_long}, + {"ul_x",tk_ulong}, + {"l_y",tk_long}, + {"l_z",tk_long}, + {"ul_z",tk_ulong}, + {"s_x",tk_short}, + {"us_x",tk_ushort}, + {"s_y",tk_short}, + {"s_z",tk_short}, + {"us_z",tk_ushort}, + {"c_x",tk_char}, + {"c_y",tk_char}, + {"c_z",tk_char}, + {"wc_x",tk_wchar}, + {"wc_y",tk_wchar}, + {"wc_z",tk_wchar}|_]}). + + + +marshal_ll(State, #m_s{ll_x = X, ll_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +marshal_ull(State, #m_s{ull_x = X, ll_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + + +marshal_l(State, #m_s{l_x = X, l_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +marshal_ul(State, #m_s{ul_x = X, l_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + + +marshal_s(State, #m_s{s_x = X, s_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +marshal_us(State, #m_s{us_x = X, s_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + + +marshal_c(State, #m_s{c_x = X, c_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +marshal_wc(State, #m_s{wc_x = X, wc_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +strcat(State, A, B) when list(A), list(B) -> + R = A++B, + io:format("~p", [{?MODULE,?LINE,[length(A),length(B),A,B,R]}]), + {reply, R, State}; +strcat(State, A, B) -> + io:format("~p", [{?MODULE,?LINE,[A,B]}]), + {reply, [], State}. + +marshal_any_3(State, {any,TkX,_}=X, {any,_,_}=Y, B) when integer(B) -> + R = any(mul(sub(any(X), any(Y)), B), TkX), + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +marshal_any_2(State, + {any,TkA,#m_s{ll_x=LL_X, ull_x=ULL_X, ll_y=LL_Y, + l_x=L_X, ul_x=UL_X, l_y=L_Y, + s_x=S_X, us_x=US_X, s_y=S_Y, + c_x=C_X, c_y=C_Y, + wc_x=WC_X, wc_y=WC_Y} = A}, + B) when integer(B) -> + {check_type_code,?TK_M_S} = {check_type_code,TkA}, + ULL_Z = (ULL_X - LL_Y) * B, + LL_Z = (LL_X - LL_Y) * B, + UL_Z = (UL_X - L_Y) * B, + L_Z = (L_X - L_Y) * B, + US_Z = (US_X - S_Y) * B, + S_Z = (S_X - S_Y) * B, + C_Z = (C_X - C_Y) * B, + WC_Z = (WC_X - WC_Y) * B, + R = A#m_s{ll_z=LL_Z, ull_z=ULL_Z, + l_z=L_Z, ul_z=UL_Z, + s_z=S_Z, us_z=US_Z, + c_z=C_Z, wc_z=WC_Z}, + io:format("~p", [{?MODULE,?LINE,[A,B,R]}]), + {reply, {any,TkA,R}, State}. + + + +init(_Env) -> + {ok, []}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + + +any({any,tk_longlong,X}) -> X; +any({any,tk_long,X}) -> X; +any({any,tk_short,X}) -> X; +any({any,tk_ulonglong,X}) -> X; +any({any,tk_ulong,X}) -> X; +any({any,tk_ushort,X}) -> X; +any({any,tk_char,X}) -> X; +any({any,tk_wchar,X}) -> X. + +any(X, Tk) when integer(X) -> {any,Tk,X}. + +sub(X, Y) when integer(X), integer(Y) -> + X - Y. + +mul(X, Y) when integer(X), integer(Y) -> + X * Y. + +napp(0, L) -> L; +napp(N, L) when integer(N), N >= 1 -> napp(N-1, L)++L. diff --git a/lib/orber/test/Makefile b/lib/orber/test/Makefile new file mode 100644 index 0000000000..4601e84d2c --- /dev/null +++ b/lib/orber/test/Makefile @@ -0,0 +1,228 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1997-2010. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(ORBER_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/orber_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = orber.spec + + +IDL_FILES = \ + orber_test.idl \ + iiop_test.idl \ + orber_test_server.idl + +IDLOUTDIR = idl_output + +MODULES = \ + cdrcoding_11_SUITE \ + cdrcoding_10_SUITE \ + cdrcoding_12_SUITE \ + cdrlib_SUITE \ + corba_SUITE \ + iop_ior_11_SUITE \ + iop_ior_10_SUITE \ + iop_ior_12_SUITE \ + iiop_module_do_test_impl \ + iiop_module_test_impl \ + lname_SUITE \ + naming_context_SUITE \ + orber_SUITE \ + orber_test_server_impl \ + orber_test_timeout_server_impl \ + orber_test_lib \ + csiv2_SUITE \ + multi_ORB_SUITE \ + data_types_SUITE \ + tc_SUITE \ + generated_SUITE \ + orber_web_SUITE \ + interceptors_SUITE \ + orber_acl_SUITE \ + orber_firewall_ipv4_in_SUITE \ + orber_firewall_ipv6_in_SUITE \ + orber_firewall_ipv4_out_SUITE \ + orber_firewall_ipv6_out_SUITE \ + orber_nat_SUITE + +GEN_MOD_ORBER = \ + oe_orber_test \ + Module_Except1 \ + Module_Except2 \ + Module_Except3 \ + Module_Except4 \ + Module_HEADER \ + Module_I1 \ + Module_I2 \ + Module_Struct0 \ + Module_Struct1 \ + Module_Struct2 \ + Module_Union \ + Module_Union1 \ + Module_Union2 + +GEN_HRL_ORBER = \ + oe_orber_test.hrl \ + Module.hrl \ + Module_I1.hrl \ + Module_I2.hrl + +GEN_MOD_IIOP = \ + oe_iiop_test \ + iiop_module_Except1 \ + iiop_module_Struct1 \ + iiop_module_Union1 \ + iiop_module_do_test \ + iiop_module_test \ + iiop_module_test_retval + +GEN_HRL_IIOP = \ + oe_iiop_test.hrl \ + iiop_module.hrl \ + iiop_module_do_test.hrl \ + iiop_module_test.hrl + +GEN_MOD_TEST_SERVER = \ + oe_orber_test_server \ + orber_test_server \ + orber_test_server_ComplexUserDefinedException \ + orber_test_server_UserDefinedException \ + orber_test_server_struc \ + orber_test_server_uni \ + orber_test_server_uni_d \ + orber_test_timeout_server \ + orber_parent_inherrit + +GEN_HRL_TEST_SERVER = \ + oe_orber_test_server.hrl \ + orber_test_server.hrl \ + orber_test_timeout_server.hrl + +GEN_MODULES = $(GEN_MOD_ORBER) $(GEN_MOD_IIOP) \ + $(GEN_MOD_TEST_SERVER) + +ERL_FILES = $(MODULES:%=%.erl) + +HRL_FILES = + +GEN_HRL_FILES = $(GEN_HRL_ORBER) $(GEN_HRL_IIOP) \ + $(GEN_HRL_TEST_SERVER) + +GEN_FILES = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl) + +GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR)) + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(GEN_TARGET_FILES) \ + $(SUITE_TARGET_FILES) + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/orber/ebin -pa $(ERL_TOP)/lib/ic/ebin + +ERL_COMPILE_FLAGS += $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/test_server/ebin \ + -pa $(ERL_TOP)/lib/ic/ebin \ + -pa $(ERL_TOP)/lib/orber/ebin \ + -I$(ERL_TOP)/lib/orber \ + -I$(ERL_TOP)/lib/orber/test/$(IDLOUTDIR) \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +tests debug opt: $(TARGET_FILES) + +clean: + rm -f idl_output/* + rm -f $(TARGET_FILES) + rm -f errs core *~ + + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + +# +# Each IDL file produces many target files so no pattern +# rule can be used. +# +TGT_ORBER = \ + $(GEN_HRL_ORBER:%=$(IDLOUTDIR)/%) \ + $(GEN_MOD_ORBER:%=$(IDLOUTDIR)/%.erl) +TGT_IIOP = \ + $(GEN_HRL_IIOP:%=$(IDLOUTDIR)/%) \ + $(GEN_MOD_IIOP:%=$(IDLOUTDIR)/%.erl) + +TGT_TEST_SERVER = \ + $(GEN_HRL_TEST_SERVER:%=$(IDLOUTDIR)/%) \ + $(GEN_MOD_TEST_SERVER:%=$(IDLOUTDIR)/%.erl) + +$(TGT_ORBER): orber_test.idl + erlc $(ERL_IDL_FLAGS) -o$(IDLOUTDIR) orber_test.idl + +$(TGT_IIOP): iiop_test.idl + erlc $(ERL_IDL_FLAGS) -o$(IDLOUTDIR) \ + +'{preproc_flags,"-I../COSS/CosNaming"}' iiop_test.idl + +$(TGT_TEST_SERVER): orber_test_server.idl + erlc $(ERL_IDL_FLAGS) -o$(IDLOUTDIR) \ + +'{cfgfile,"orber_test_server.cfg"}' orber_test_server.idl + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +# We don't copy generated intermediate erlang and hrl files + +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ + $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + chmod -f -R u+w $(RELSYSDIR) + $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) + $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ + $(RELSYSDIR)/$(IDLOUTDIR) + diff --git a/lib/orber/test/cdrcoding_10_SUITE.erl b/lib/orber/test/cdrcoding_10_SUITE.erl new file mode 100644 index 0000000000..d5d030538f --- /dev/null +++ b/lib/orber/test/cdrcoding_10_SUITE.erl @@ -0,0 +1,616 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for the CDR encode/decode functions +%% +%%----------------------------------------------------------------- +-module(cdrcoding_10_SUITE). + + +-include("idl_output/Module.hrl"). +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-define(default_timeout, ?t:minutes(20)). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [types, reply, cancel_request, close_connection, message_error]. +%% request, locate_request, locate_reply]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + orber:jump_start(0), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) when is_list(Config) -> + orber:jump_stop(), + Config. + +%%----------------------------------------------------------------- +%% Test Case: type encoding tests +%% Description: Just testing the complex types, the others are +%% tested in the cdrlib SUITE. +%%----------------------------------------------------------------- +types(doc) -> ["Description", "more description"]; +types(suite) -> [do_register, null_type, void_type, principal_type, + objref_type, struct_type, union_type, string_type, + array_type, any_type, typecode_type, alias_type, + exception_type, do_unregister]. +%types(Config) when list(Config) -> +% 'oe_orber_test':'oe_register'(), +% null_type(), +% void_type(), +% principal_type(), +% objref_type(), +% struct_type(), +% union_type(), +% string_type(), +% array_type(), +% any_type(), +% typecode_type(), +% alias_type(), +% exception_type(), +% 'oe_orber_test':'oe_unregister'(), +% ok. + +do_register(doc) -> []; +do_register(suite) -> []; +do_register(Config) when is_list(Config) -> + io:format("Pwd: ~p, mod: ~p~n",[c:pwd(), c:m('oe_orber_test')]), + 'oe_orber_test':'oe_register'(), + ok. +do_unregister(doc) -> []; +do_unregister(suite) -> []; +do_unregister(Config) when is_list(Config) -> + 'oe_orber_test':'oe_unregister'(), + ok. +%%----------------------------------------------------------------- +%% Encode/decode test of type: null +%%----------------------------------------------------------------- +null_type(doc) -> []; +null_type(suite) -> []; +null_type(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, 'tk_null', 'null'), + ?line {'null', <<>>, _} = cdr_decode:dec_type('tk_null', {1, 0}, B, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: void +%%----------------------------------------------------------------- +void_type(doc) -> []; +void_type(suite) -> []; +void_type(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, 'tk_void', 'ok'), + ?line {'ok', <<>>, _} = cdr_decode:dec_type('tk_void', {1, 0}, B, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: principal +%%----------------------------------------------------------------- +principal_type(doc) -> []; +principal_type(suite) -> []; +principal_type(Config) when is_list(Config) -> + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, 'tk_Principal', "principal"), + ?line {"principal", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 0}, B0, 0, big), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, 'tk_Principal', ""), + ?line {"", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 0}, B1, 0, big), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, 'tk_Principal', "principal"), + ?line {"principal", <<>>, _} = + cdr_decode:dec_type('tk_Principal', {1, 0}, B2, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: object reference +%%----------------------------------------------------------------- +version() -> #'IIOP_Version'{major=1,minor=0}. + +objref(0) -> + PB = #'IIOP_ProfileBody_1_0'{iiop_version=version(), + host="my.hostname.org", + port=4040, + object_key="ExternalKey: which is an arbitary octet sequence"}, + TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB}, + #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}; +objref(1) -> + K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", key, + list_to_pid("<0.100.0>")), + PB = #'IIOP_ProfileBody_1_0'{iiop_version=version(), + host="my.hostname.org", + port=4040, + object_key=K}, + TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB}, + #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}; +objref(2) -> + K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", registered, + list_to_atom("orber_nameservice")), + PB = #'IIOP_ProfileBody_1_0'{iiop_version=version(), + host="my.hostname.org", + port=4040, + object_key=K}, + TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB}, + #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}. + +objref_type(doc) -> []; +objref_type(suite) -> []; +objref_type(Config) when is_list(Config) -> + T = {'tk_objref', "IDL:Module/Interface:1.0", "Interface"}, + Objref0 = objref(0), + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T, Objref0), + ?line {Objref0, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B0, 0, big), + Objref1 = objref(1), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T, Objref1), + ?line {Objref1, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B1, 0, big), + Objref2 = objref(2), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T, Objref2), + ?line {Objref2, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B2, 0, big), + ok. + + + +%%----------------------------------------------------------------- +%% Encode/decode test of type: struct +%%----------------------------------------------------------------- +struct_type(doc) -> []; +struct_type(suite) -> []; +struct_type(Config) when is_list(Config) -> + T0 = {'tk_struct',"IDL:Module/Struct0:1.0", "Module_Struct0", + [{"long", 'tk_long'}, {"short", 'tk_short'}, {"character", 'tk_char'}]}, + S0 = #'Module_Struct0'{l=-4711, s=17, c=$a}, + ?line B0 = cdr_encode:enc_type({1, 0}, T0, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 0}, B0, 0, big), + + T1 = {'tk_struct', "IDL:Module/Struct1:1.0", "Module_Struct1", + [{"string", {'tk_string', 0}}, {"ushort", 'tk_ushort'}, {"ulong", 'tk_ulong'}]}, + S1 = #'Module_Struct1'{s="Hi !!!!", us=17, ul=4711}, + ?line B1 = cdr_encode:enc_type({1, 0}, T1, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B1, 0, big), + + T2 = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2", + [{"long_sequence", {'tk_sequence', 'tk_long', 0}}, + {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}}, + {"octet", 'tk_octet'}]}, + S2 = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], e=cow, o=$X}, + ?line B2 = cdr_encode:enc_type({1, 0}, T2, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 0}, B2, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: union +%%----------------------------------------------------------------- +union_type(doc) -> []; +union_type(suite) -> []; +union_type(Config) when is_list(Config) -> + T0 = {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2, + [{0, "First", 'tk_short'}, + {1, "Second", {'tk_string', 0}}, + {2, "Third", 'tk_char'}]}, + S0 = #'Module_Union'{label=1, value="Foo Bar !"}, + ?line B0 = cdr_encode:enc_type({1, 0}, T0, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 0}, B0, 0, big), + S1 = #'Module_Union'{label=0, value=-17}, + ?line B1 = cdr_encode:enc_type({1, 0}, T0, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T0, {1, 0}, B1, 0, big), + S2 = #'Module_Union'{label=2, value=$X}, + ?line B2 = cdr_encode:enc_type({1, 0}, T0, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type(T0, {1, 0}, B2, 0, big), + T1 = {'tk_union', "IDL:Module/Union1:1.0", "Union1", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", "apple"]}}]}, + S3 = #'Module_Union1'{label=pig, value=["Foo", "Bar", "!"]}, + ?line B3 = cdr_encode:enc_type({1, 0}, T1, S3), + ?line {S3, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B3, 0, big), + S4 = #'Module_Union1'{label=cow, value=apple}, + ?line B4 = cdr_encode:enc_type({1, 0}, T1, S4), + ?line {S4, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B4, 0, big), + S5 = #'Module_Union1'{label=horse, value=17}, + ?line B5 = cdr_encode:enc_type({1, 0}, T1, S5), + ?line {S5, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B5, 0, big), + T2 = {'tk_union', "IDL:Module/Union2:1.0", "Union2", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", {'tk_array', 'tk_long', 3}}, + {"pig", "Second", + {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2, + [{0, "First", 'tk_short'}, + {1, "Second", {'tk_string', 0}}, + {2, "Third", 'tk_char'}]}}, + {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', + {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', + "IDL:Module/Enum1:1.0", + "Module_Enum1", + ["orange", "banana", + "apple"]}}]}}]}, + S6 = #'Module_Union2'{label=pig, value=#'Module_Union'{label=0, value=-17}}, + ?line B6 = cdr_encode:enc_type({1, 0}, T2, S6), + ?line {S6, <<>>, _} = cdr_decode:dec_type(T2, {1, 0}, B6, 0, big), + S7 = #'Module_Union2'{label=cow, value=#'Module_Union1'{label=pig, + value=["Foo", "Bar", "!"]}}, + ?line B7 = cdr_encode:enc_type({1, 0}, T2, S7), + ?line {S7, <<>>, _} = cdr_decode:dec_type(T2, {1, 0}, B7, 0, big), + S8 = #'Module_Union2'{label=horse, value={-17, 1234567890, -987654321}}, + ?line B8 = cdr_encode:enc_type({1, 0}, T2, S8), + ?line {S8, <<>>, _} = cdr_decode:dec_type(T2, {1, 0}, B8, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: string +%%----------------------------------------------------------------- +string_type(doc) -> []; +string_type(suite) -> []; +string_type(Config) when is_list(Config) -> + S0 = "Foo Bar ???", + ?line B0 = cdr_encode:enc_type({1, 0}, {'tk_string', 0}, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 0}, B0, 0, big), + S1 = "Yes, Foo Bar !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! more than 5000 characters", + ?line B1 = cdr_encode:enc_type({1, 0}, {'tk_string', 0}, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 0}, B1, 0, big), + S2 = "", + ?line B2 = cdr_encode:enc_type({1, 0}, {'tk_string', 0}, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 0}, B2, 0, big), + S3 = "\0", + ?line B3 = cdr_encode:enc_type({1, 0}, {'tk_string', 0}, S3), + ?line {S3, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 0}, B3, 0, big), + S4 = "~n", + ?line B4 = cdr_encode:enc_type({1, 0}, {'tk_string', 0}, S4), + ?line {S4, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 0}, B4, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: array +%%----------------------------------------------------------------- +array_type(doc) -> []; +array_type(suite) -> []; +array_type(Config) when is_list(Config) -> + T0 = {'tk_array', 'tk_long', 5}, + S0 = {-100, 0, 30000, -900100900, 123456789}, + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T0, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 0}, B0, 0, big), + T1 = {'tk_array', {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, 2}, + S1 = {pig, cow}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T1, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B1, 0, big), + T2 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", "apple"]}}]}, 2}, + S2 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}}, + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T2, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 0}, B2, 0, big), + T3 = {'tk_array', {'tk_objref', "IDL:Module/Interface:1.0", "Interface"}, 3}, + S3 = {objref(0), objref(1), objref(2)}, + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T3, S3), + ?line {S3, <<>>, _} = cdr_decode:dec_type(T3, {1, 0}, B3, 0, big), + ok. +%%----------------------------------------------------------------- +%% Encode/decode test of type: TypeCode +%%----------------------------------------------------------------- +any_type(doc) -> []; +any_type(suite) -> []; +any_type(Config) when is_list(Config) -> + T = 'tk_any', + TC = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2", + [{"long_sequence", {'tk_sequence', 'tk_long', 0}}, + {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}}, + {"octet", 'tk_octet'}]}, + S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], + e=cow, o=$X}, + Any = #any{typecode=TC,value=S}, + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T,Any), + ?line {Any, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B, 0, big), + TC1 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}, 1, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", + "apple"]}}]},2}, + S1 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}}, + Any1 = #any{typecode=TC1,value=S1}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T,Any1), + ?line {Any1, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B1, 0, big), + ok. + + +%%----------------------------------------------------------------- +%% Encode/decode test of type: TypeCode +%%----------------------------------------------------------------- +typecode_type(doc) -> []; +typecode_type(suite) -> []; +typecode_type(Config) when is_list(Config) -> + T = 'tk_TypeCode', + TC = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}, 1, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", + "apple"]}}]}, 10}, + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T,TC), + ?line {TC, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B, 0, big), + TC1 = {'tk_union', "IDL:Module/Union2:1.0", "Union2", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, 2, + [{"horse", "First", 'tk_long'}, + {"pig", "Second", + {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2, + [{0, "First", 'tk_short'}, + {1, "Second", {'tk_string', 0}}, + {2, "Third", 'tk_char'}]}}, + {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, 2, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', + {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', + "IDL:Module/Enum1:1.0", + "Module_Enum1", + ["orange", "banana", + "apple"]}}]}}]}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T, TC1), + ?line {TC1, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B1, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: TypeCode +%%----------------------------------------------------------------- +alias_type(doc) -> []; +alias_type(suite) -> []; +alias_type(Config) when is_list(Config) -> + T = {'tk_alias', "IDL:Module/Alias:1.0", "Alias", + {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2", + [{"long_sequence", {'tk_sequence', 'tk_long', 0}}, + {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}}, + {"octet", 'tk_octet'}]}}, + S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], + e=cow, o=$X}, + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T,S), + ?line {S, <<>>, _} = cdr_decode:dec_type(T, {1, 0}, B, 0, big), + T1 = {'tk_alias', "IDL:Module/Alias1:1.0", "Alias1", + {'tk_sequence', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}, 2, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", + "apple"]}}]},0}}, + S1 = [#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}], + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T1, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 0}, B1, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: exception +%%----------------------------------------------------------------- +exception_type(doc) -> []; +exception_type(suite) -> []; +exception_type(Config) when is_list(Config) -> + system_exceptions(), + user_exceptions(), + ok. + +system_exceptions() -> + E = #'UNKNOWN'{completion_status=?COMPLETED_YES}, + {system_exception, T, E} = orber_exceptions:get_def(E), + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T,E), + ?line {E, _} = cdr_decode:dec_system_exception({1, 0}, B, 0, big), + E1 = #'INV_OBJREF'{completion_status=?COMPLETED_NO}, + {system_exception, T1, E1} = orber_exceptions:get_def(E1), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T1,E1), + ?line {E1, _} = cdr_decode:dec_system_exception({1, 0}, B1, 0, big), + E2 = #'BAD_OPERATION'{completion_status=?COMPLETED_NO}, + {system_exception, T2, E2} = orber_exceptions:get_def(E2), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T2,E2), + ?line {E2, _} = cdr_decode:dec_system_exception({1, 0}, B2, 0, big), + E3 = #'INTF_REPOS'{completion_status=?COMPLETED_MAYBE}, + {system_exception, T3, E3} = orber_exceptions:get_def(E3), + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T3,E3), + ?line {E3, _} = cdr_decode:dec_system_exception({1, 0}, B3, 0, big), + ok. + +user_exceptions() -> + E = #'Module_Except1'{rest_of_name=["I","am","testing","exceptions"], why="Error"}, + {user_exception, T, E} = orber_exceptions:get_def(E), + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T, E), + ?line {E, _} = cdr_decode:dec_user_exception({1, 0}, B, 0, big), + E1 = #'Module_Except2'{e=banana, + s=#'Module_Struct2'{long_sequence=[12,-4040, + 1234567898], + e=horse, + o=$a}}, + {user_exception, T1, E1} = orber_exceptions:get_def(E1), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T1, E1), + ?line {E1, _} = cdr_decode:dec_user_exception({1, 0}, B1, 0, big), + E2 = #'Module_Except3'{u=#'Module_Union1'{label=pig,value=["high","and","low"]},s=1313, o=objref(0)}, + {user_exception, T2, E2} = orber_exceptions:get_def(E2), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T2, E2), + ?line {E2, _} = cdr_decode:dec_user_exception({1, 0}, B2, 0, big), + E3 = #'Module_Except4'{}, + {user_exception, T3, E3} = orber_exceptions:get_def(E3), + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 0}}, T3, E3), + ?line {E3, _} = cdr_decode:dec_user_exception({1, 0}, B3, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Test Case: request encoding test +%% Description: Precondition the stack must be started so the +%% objectkey is valid. +%%----------------------------------------------------------------- +%request(suite) -> []; +%request(_) -> +% exit(not_implemented). + +%%----------------------------------------------------------------- +%% Test Case: reply encoding test +%% Description: +%%----------------------------------------------------------------- +reply(doc) -> ["Description", "more description"]; +reply(suite) -> []; +reply(Config) when is_list(Config) -> + R = #reply_header{service_context=[], request_id=1, + reply_status='no_exception'}, + ?line B = cdr_encode:enc_reply( + #giop_env{version = {1, 0}, request_id = 1, + reply_status = 'no_exception', + tc = {'tk_long', [], [{'tk_sequence', + {'tk_string', 0}, 0}]}, + result = 1200, parameters = [["foo","Bar"]], + ctx = []}), + ?line {R, 1200, [["foo","Bar"]]} = + cdr_decode:dec_message({'tk_long', [], [{'tk_sequence', {'tk_string', 0},0}]}, + B), + ok. + +%%----------------------------------------------------------------- +%% Test Case: cancel_request encoding test +%% Description: +%%----------------------------------------------------------------- +cancel_request(doc) -> ["Description", "more description"]; +cancel_request(suite) -> []; +cancel_request(Config) when is_list(Config) -> + R = #cancel_request_header{request_id=1}, + ?line B = cdr_encode:enc_cancel_request(#giop_env{version = {1, 0}, + request_id = 1}), + ?line R = cdr_decode:dec_message([], B), + ok. + +%%----------------------------------------------------------------- +%% Test Case: locate_request encoding test +%% Description: +%%----------------------------------------------------------------- +locate_request(doc) -> ["Description", "more description"]; +locate_request(suite) -> []; +locate_request(Config) when is_list(Config) -> + io:format("Function not imlpemented yet"), + exit(not_implemented). + +%%----------------------------------------------------------------- +%% Test Case: locate_reply encoding test +%% Description: +%%----------------------------------------------------------------- +locate_reply(doc) -> ["Description", "more description"]; +locate_reply(suite) -> []; +locate_reply(Config) when is_list(Config) -> + io:format("Function not imlpemented yet"), + exit(not_implemented). + +%%----------------------------------------------------------------- +%% Test Case: close_connection encoding test +%% Description: +%%----------------------------------------------------------------- +close_connection(doc) -> ["Description", "more description"]; +close_connection(suite) -> []; +close_connection(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_close_connection(#giop_env{version = {1, 0}}), + ?line 'close_connection' = cdr_decode:dec_message([], B), + ok. + +%%----------------------------------------------------------------- +%% Test Case: message_error encoding test +%% Description: +%%----------------------------------------------------------------- +message_error(doc) -> ["Description", "more description"]; +message_error(suite) -> []; +message_error(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_message_error(#giop_env{version = {1, 0}}), + ?line 'message_error' = cdr_decode:dec_message([], B), + ok. + + + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- +corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) -> + Key = make_objkey(), + {list_to_binary(Id), 'key', Key, term_to_binary(undefined), + term_to_binary(undefined), term_to_binary(undefined)}; +corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) -> + Key = term_to_binary(RegName), + {list_to_binary(Id), 'key', Key, term_to_binary(undefined), + term_to_binary(undefined), term_to_binary(undefined)}; +corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) -> + {list_to_binary(Id), 'registered', RegName, term_to_binary(undefined), + term_to_binary(undefined), term_to_binary(undefined)}. + +make_objkey() -> + term_to_binary({now(), node()}). diff --git a/lib/orber/test/cdrcoding_11_SUITE.erl b/lib/orber/test/cdrcoding_11_SUITE.erl new file mode 100644 index 0000000000..d62fe6eb3a --- /dev/null +++ b/lib/orber/test/cdrcoding_11_SUITE.erl @@ -0,0 +1,615 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for the CDR encode/decode functions +%% +%%----------------------------------------------------------------- +-module(cdrcoding_11_SUITE). + + +-include("idl_output/Module.hrl"). +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-define(default_timeout, ?t:minutes(5)). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [types, reply, cancel_request, close_connection, message_error]. +%% request, locate_request, locate_reply]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + orber:jump_start(0), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) when is_list(Config) -> + orber:jump_stop(), + Config. + +%%----------------------------------------------------------------- +%% Test Case: type encoding tests +%% Description: Just testing the complex types, the others are +%% tested in the cdrlib SUITE. +%%----------------------------------------------------------------- +types(doc) -> ["Description", "more description"]; +types(suite) -> [do_register, null_type, void_type, principal_type, + objref_type, struct_type, union_type, string_type, + array_type, any_type, typecode_type, alias_type, + exception_type, do_unregister]. +%types(Config) when list(Config) -> +% 'oe_orber_test':'oe_register'(), +% null_type(), +% void_type(), +% principal_type(), +% objref_type(), +% struct_type(), +% union_type(), +% string_type(), +% array_type(), +% any_type(), +% typecode_type(), +% alias_type(), +% exception_type(), +% 'oe_orber_test':'oe_unregister'(), +% ok. + +do_register(doc) -> []; +do_register(suite) -> []; +do_register(Config) when is_list(Config) -> + 'oe_orber_test':'oe_register'(), + ok. +do_unregister(doc) -> []; +do_unregister(suite) -> []; +do_unregister(Config) when is_list(Config) -> + 'oe_orber_test':'oe_unregister'(), + ok. +%%----------------------------------------------------------------- +%% Encode/decode test of type: null +%%----------------------------------------------------------------- +null_type(doc) -> []; +null_type(suite) -> []; +null_type(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, 'tk_null', 'null'), + ?line {'null', <<>>, _} = cdr_decode:dec_type('tk_null', {1, 1}, B, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: void +%%----------------------------------------------------------------- +void_type(doc) -> []; +void_type(suite) -> []; +void_type(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, 'tk_void', 'ok'), + ?line {'ok', <<>>, _} = cdr_decode:dec_type('tk_void', {1, 1}, B, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: principal +%%----------------------------------------------------------------- +principal_type(doc) -> []; +principal_type(suite) -> []; +principal_type(Config) when is_list(Config) -> + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, 'tk_Principal', "principal"), + ?line {"principal", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 1}, B0, 0, big), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, 'tk_Principal', ""), + ?line {"", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 1}, B1, 0, big), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, 'tk_Principal', "principal"), + ?line {"principal", <<>>, _} = + cdr_decode:dec_type('tk_Principal', {1, 1}, B2, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: object reference +%%----------------------------------------------------------------- +version() -> #'IIOP_Version'{major=1,minor=1}. + +objref(0) -> + PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(), + host="my.hostname.org", + port=4040, + object_key="ExternalKey: which is an arbitary octet sequence", + components=[]}, + TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB}, + #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}; +objref(1) -> + K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", key, + list_to_pid("<0.100.0>")), + PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(), + host="my.hostname.org", + port=4040, + object_key=K, components=[]}, + TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB}, + #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}; +objref(2) -> + K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", registered, + list_to_atom("orber_nameservice")), + PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(), + host="my.hostname.org", + port=4040, + object_key=K, components=[]}, + TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB}, + #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}. + +objref_type(doc) -> []; +objref_type(suite) -> []; +objref_type(Config) when is_list(Config) -> + T = {'tk_objref', "IDL:Module/Interface:1.0", "Interface"}, + Objref0 = objref(0), + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T, Objref0), + ?line {Objref0, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B0, 0, big), + Objref1 = objref(1), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T, Objref1), + ?line {Objref1, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B1, 0, big), + Objref2 = objref(2), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T, Objref2), + ?line {Objref2, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B2, 0, big), + ok. + + + +%%----------------------------------------------------------------- +%% Encode/decode test of type: struct +%%----------------------------------------------------------------- +struct_type(doc) -> []; +struct_type(suite) -> []; +struct_type(Config) when is_list(Config) -> + T0 = {'tk_struct',"IDL:Module/Struct0:1.0", "Module_Struct0", + [{"long", 'tk_long'}, {"short", 'tk_short'}, {"character", 'tk_char'}]}, + S0 = #'Module_Struct0'{l=-4711, s=17, c=$a}, + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T0, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 1}, B0, 0, big), + + T1 = {'tk_struct', "IDL:Module/Struct1:1.0", "Module_Struct1", + [{"string", {'tk_string', 0}}, {"ushort", 'tk_ushort'}, {"ulong", 'tk_ulong'}]}, + S1 = #'Module_Struct1'{s="Hi !!!!", us=17, ul=4711}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B1, 0, big), + + T2 = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2", + [{"long_sequence", {'tk_sequence', 'tk_long', 0}}, + {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}}, + {"octet", 'tk_octet'}]}, + S2 = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], e=cow, o=$X}, + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 1}, B2, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: union +%%----------------------------------------------------------------- +union_type(doc) -> []; +union_type(suite) -> []; +union_type(Config) when is_list(Config) -> + T0 = {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2, + [{0, "First", 'tk_short'}, + {1, "Second", {'tk_string', 0}}, + {2, "Third", 'tk_char'}]}, + S0 = #'Module_Union'{label=1, value="Foo Bar !"}, + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T0, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 1}, B0, 0, big), + S1 = #'Module_Union'{label=0, value=-17}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T0, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T0, {1, 1}, B1, 0, big), + S2 = #'Module_Union'{label=2, value=$X}, + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T0, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type(T0, {1, 1}, B2, 0, big), + T1 = {'tk_union', "IDL:Module/Union1:1.0", "Union1", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", "apple"]}}]}, + S3 = #'Module_Union1'{label=pig, value=["Foo", "Bar", "!"]}, + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S3), + ?line {S3, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B3, 0, big), + S4 = #'Module_Union1'{label=cow, value=apple}, + ?line B4 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S4), + ?line {S4, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B4, 0, big), + S5 = #'Module_Union1'{label=horse, value=17}, + ?line B5 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S5), + ?line {S5, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B5, 0, big), + T2 = {'tk_union', "IDL:Module/Union2:1.0", "Union2", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", {'tk_array', 'tk_long', 3}}, + {"pig", "Second", + {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2, + [{0, "First", 'tk_short'}, + {1, "Second", {'tk_string', 0}}, + {2, "Third", 'tk_char'}]}}, + {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', + {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', + "IDL:Module/Enum1:1.0", + "Module_Enum1", + ["orange", "banana", + "apple"]}}]}}]}, + S6 = #'Module_Union2'{label=pig, value=#'Module_Union'{label=0, value=-17}}, + ?line B6 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, S6), + ?line {S6, <<>>, _} = cdr_decode:dec_type(T2, {1, 1}, B6, 0, big), + S7 = #'Module_Union2'{label=cow, value=#'Module_Union1'{label=pig, + value=["Foo", "Bar", "!"]}}, + ?line B7 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, S7), + ?line {S7, <<>>, _} = cdr_decode:dec_type(T2, {1, 1}, B7, 0, big), + S8 = #'Module_Union2'{label=horse, value={-17, 1234567890, -987654321}}, + ?line B8 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, S8), + ?line {S8, <<>>, _} = cdr_decode:dec_type(T2, {1, 1}, B8, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: string +%%----------------------------------------------------------------- +string_type(doc) -> []; +string_type(suite) -> []; +string_type(Config) when is_list(Config) -> + S0 = "Foo Bar ???", + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, {'tk_string', 0}, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 1}, B0, 0, big), + S1 = "Yes, Foo Bar !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! more than 5000 characters", + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, {'tk_string', 0}, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 1}, B1, 0, big), + S2 = "", + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, {'tk_string', 0}, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 1}, B2, 0, big), + S3 = "\0", + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, {'tk_string', 0}, S3), + ?line {S3, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 1}, B3, 0, big), + S4 = "~n", + ?line B4 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, {'tk_string', 0}, S4), + ?line {S4, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 1}, B4, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: array +%%----------------------------------------------------------------- +array_type(doc) -> []; +array_type(suite) -> []; +array_type(Config) when is_list(Config) -> + T0 = {'tk_array', 'tk_long', 5}, + S0 = {-100, 0, 30000, -900100900, 123456789}, + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T0, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 1}, B0, 0, big), + T1 = {'tk_array', {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, 2}, + S1 = {pig, cow}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B1, 0, big), + T2 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", "apple"]}}]}, 2}, + S2 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}}, + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 1}, B2, 0, big), + T3 = {'tk_array', {'tk_objref', "IDL:Module/Interface:1.0", "Interface"}, 3}, + S3 = {objref(0), objref(1), objref(2)}, + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T3, S3), + ?line {S3, <<>>, _} = cdr_decode:dec_type(T3, {1, 1}, B3, 0, big), + ok. +%%----------------------------------------------------------------- +%% Encode/decode test of type: TypeCode +%%----------------------------------------------------------------- +any_type(doc) -> []; +any_type(suite) -> []; +any_type(Config) when is_list(Config) -> + T = 'tk_any', + TC = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2", + [{"long_sequence", {'tk_sequence', 'tk_long', 0}}, + {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}}, + {"octet", 'tk_octet'}]}, + S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], + e=cow, o=$X}, + Any = #any{typecode=TC,value=S}, + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T,Any), + ?line {Any, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B, 0, big), + TC1 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}, 1, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", + "apple"]}}]},2}, + S1 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}}, + Any1 = #any{typecode=TC1,value=S1}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T,Any1), + ?line {Any1, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B1, 0, big), + ok. + + +%%----------------------------------------------------------------- +%% Encode/decode test of type: TypeCode +%%----------------------------------------------------------------- +typecode_type(doc) -> []; +typecode_type(suite) -> []; +typecode_type(Config) when is_list(Config) -> + T = 'tk_TypeCode', + TC = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}, 1, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", + "apple"]}}]}, 10}, + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T,TC), + ?line {TC, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B, 0, big), + TC1 = {'tk_union', "IDL:Module/Union2:1.0", "Union2", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, 2, + [{"horse", "First", 'tk_long'}, + {"pig", "Second", + {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2, + [{0, "First", 'tk_short'}, + {1, "Second", {'tk_string', 0}}, + {2, "Third", 'tk_char'}]}}, + {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, 2, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', + {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', + "IDL:Module/Enum1:1.0", + "Module_Enum1", + ["orange", "banana", + "apple"]}}]}}]}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T, TC1), + ?line {TC1, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B1, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: TypeCode +%%----------------------------------------------------------------- +alias_type(doc) -> []; +alias_type(suite) -> []; +alias_type(Config) when is_list(Config) -> + T = {'tk_alias', "IDL:Module/Alias:1.0", "Alias", + {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2", + [{"long_sequence", {'tk_sequence', 'tk_long', 0}}, + {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}}, + {"octet", 'tk_octet'}]}}, + S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], + e=cow, o=$X}, + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T,S), + ?line {S, <<>>, _} = cdr_decode:dec_type(T, {1, 1}, B, 0, big), + T1 = {'tk_alias', "IDL:Module/Alias1:1.0", "Alias1", + {'tk_sequence', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}, 2, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", + "apple"]}}]},0}}, + S1 = [#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}], + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 1}, B1, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: exception +%%----------------------------------------------------------------- +exception_type(doc) -> []; +exception_type(suite) -> []; +exception_type(Config) when is_list(Config) -> + system_exceptions(), + user_exceptions(), + ok. + +system_exceptions() -> + E = #'UNKNOWN'{completion_status=?COMPLETED_YES}, + {system_exception, T, E} = orber_exceptions:get_def(E), + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T,E), + ?line {E, _} = cdr_decode:dec_system_exception({1, 1}, B, 0, big), + E1 = #'INV_OBJREF'{completion_status=?COMPLETED_NO}, + {system_exception, T1, E1} = orber_exceptions:get_def(E1), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1,E1), + ?line {E1, _} = cdr_decode:dec_system_exception({1, 1}, B1, 0, big), + E2 = #'BAD_OPERATION'{completion_status=?COMPLETED_NO}, + {system_exception, T2, E2} = orber_exceptions:get_def(E2), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2,E2), + ?line {E2, _} = cdr_decode:dec_system_exception({1, 1}, B2, 0, big), + E3 = #'INTF_REPOS'{completion_status=?COMPLETED_MAYBE}, + {system_exception, T3, E3} = orber_exceptions:get_def(E3), + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T3,E3), + ?line {E3, _} = cdr_decode:dec_system_exception({1, 1}, B3, 0, big), + ok. + +user_exceptions() -> + E = #'Module_Except1'{rest_of_name=["I","am","testing","exceptions"], why="Error"}, + {user_exception, T, E} = orber_exceptions:get_def(E), + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T, E), + ?line {E, _} = cdr_decode:dec_user_exception({1, 1}, B, 0, big), + E1 = #'Module_Except2'{e=banana, + s=#'Module_Struct2'{long_sequence=[12,-4040, + 1234567898], + e=horse, + o=$a}}, + {user_exception, T1, E1} = orber_exceptions:get_def(E1), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T1, E1), + ?line {E1, _} = cdr_decode:dec_user_exception({1, 1}, B1, 0, big), + E2 = #'Module_Except3'{u=#'Module_Union1'{label=pig,value=["high","and","low"]},s=1313, o=objref(0)}, + {user_exception, T2, E2} = orber_exceptions:get_def(E2), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T2, E2), + ?line {E2, _} = cdr_decode:dec_user_exception({1, 1}, B2, 0, big), + E3 = #'Module_Except4'{}, + {user_exception, T3, E3} = orber_exceptions:get_def(E3), + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 1}}, T3, E3), + ?line {E3, _} = cdr_decode:dec_user_exception({1, 1}, B3, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Test Case: request encoding test +%% Description: Precondition the stack must be started so the +%% objectkey is valid. +%%----------------------------------------------------------------- +%request(suite) -> []; +%request(_) -> +% exit(not_implemented). + +%%----------------------------------------------------------------- +%% Test Case: reply encoding test +%% Description: +%%----------------------------------------------------------------- +reply(doc) -> ["Description", "more description"]; +reply(suite) -> []; +reply(Config) when is_list(Config) -> + R = #reply_header{service_context=[], request_id=1, + reply_status='no_exception'}, + ?line B = cdr_encode:enc_reply(#giop_env{version = {1, 1}, request_id = 1, + reply_status = 'no_exception', + tc = {'tk_long', [], [{'tk_sequence', + {'tk_string', 0}, 0}]}, + result = 1200, parameters = [["foo","Bar"]], + ctx = []}), + ?line {R, 1200, [["foo","Bar"]]} = + cdr_decode:dec_message({'tk_long', [], [{'tk_sequence', {'tk_string', 0},0}]}, + B), + ok. + +%%----------------------------------------------------------------- +%% Test Case: cancel_request encoding test +%% Description: +%%----------------------------------------------------------------- +cancel_request(doc) -> ["Description", "more description"]; +cancel_request(suite) -> []; +cancel_request(Config) when is_list(Config) -> + R = #cancel_request_header{request_id=1}, + ?line B = cdr_encode:enc_cancel_request(#giop_env{version = {1, 1}, + request_id = 1}), + ?line R = cdr_decode:dec_message([], B), + ok. + +%%----------------------------------------------------------------- +%% Test Case: locate_request encoding test +%% Description: +%%----------------------------------------------------------------- +locate_request(doc) -> ["Description", "more description"]; +locate_request(suite) -> []; +locate_request(Config) when is_list(Config) -> + io:format("Function not imlpemented yet"), + exit(not_implemented). + +%%----------------------------------------------------------------- +%% Test Case: locate_reply encoding test +%% Description: +%%----------------------------------------------------------------- +locate_reply(doc) -> ["Description", "more description"]; +locate_reply(suite) -> []; +locate_reply(Config) when is_list(Config) -> + io:format("Function not imlpemented yet"), + exit(not_implemented). + +%%----------------------------------------------------------------- +%% Test Case: close_connection encoding test +%% Description: +%%----------------------------------------------------------------- +close_connection(doc) -> ["Description", "more description"]; +close_connection(suite) -> []; +close_connection(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_close_connection(#giop_env{version = {1, 1}}), + ?line 'close_connection' = cdr_decode:dec_message([], B), + ok. + +%%----------------------------------------------------------------- +%% Test Case: message_error encoding test +%% Description: +%%----------------------------------------------------------------- +message_error(doc) -> ["Description", "more description"]; +message_error(suite) -> []; +message_error(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_message_error(#giop_env{version = {1, 1}}), + ?line 'message_error' = cdr_decode:dec_message([], B), + ok. + + + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- +corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) -> + Key = make_objkey(), + {list_to_binary(Id), 'key', Key, term_to_binary(undefined), + term_to_binary(undefined), term_to_binary(undefined)}; +corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) -> + Key = term_to_binary(RegName), + {list_to_binary(Id), 'key', Key, term_to_binary(undefined), + term_to_binary(undefined), term_to_binary(undefined)}; +corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) -> + {list_to_binary(Id), 'registered', RegName, term_to_binary(undefined), + term_to_binary(undefined), term_to_binary(undefined)}. + +make_objkey() -> + term_to_binary({now(), node()}). diff --git a/lib/orber/test/cdrcoding_12_SUITE.erl b/lib/orber/test/cdrcoding_12_SUITE.erl new file mode 100644 index 0000000000..18e8eaa08a --- /dev/null +++ b/lib/orber/test/cdrcoding_12_SUITE.erl @@ -0,0 +1,603 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for the CDR encode/decode functions +%% +%%----------------------------------------------------------------- + +-module(cdrcoding_12_SUITE). + +-include("idl_output/Module.hrl"). +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-define(default_timeout, ?t:minutes(5)). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [types, reply, cancel_request, close_connection, message_error]. +%% request, locate_request, locate_reply]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) when is_list(Config) -> + orber:jump_start(0), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) when is_list(Config) -> + orber:jump_stop(), + Config. + +%%----------------------------------------------------------------- +%% Test Case: type encoding tests +%% Description: Just testing the complex types, the others are +%% tested in the cdrlib SUITE. +%%----------------------------------------------------------------- +types(doc) -> ["Description", "more description"]; +types(suite) -> [do_register, null_type, void_type, principal_type, + objref_type, struct_type, union_type, string_type, + array_type, any_type, typecode_type, alias_type, + exception_type, do_unregister]. + +do_register(doc) -> []; +do_register(suite) -> []; +do_register(Config) when is_list(Config) -> + 'oe_orber_test':'oe_register'(), + ok. +do_unregister(doc) -> []; +do_unregister(suite) -> []; +do_unregister(Config) when is_list(Config) -> + 'oe_orber_test':'oe_unregister'(), + ok. +%%----------------------------------------------------------------- +%% Encode/decode test of type: null +%%----------------------------------------------------------------- +null_type(doc) -> []; +null_type(suite) -> []; +null_type(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, 'tk_null', 'null'), + ?line {'null', <<>>, _} = cdr_decode:dec_type('tk_null', {1, 2}, B, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: void +%%----------------------------------------------------------------- +void_type(doc) -> []; +void_type(suite) -> []; +void_type(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, 'tk_void', 'ok'), + ?line {'ok', <<>>, _} = cdr_decode:dec_type('tk_void', {1, 2}, B, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: principal +%%----------------------------------------------------------------- +principal_type(doc) -> []; +principal_type(suite) -> []; +principal_type(Config) when is_list(Config) -> + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, 'tk_Principal', "principal"), + ?line {"principal", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 2}, B0, 0, big), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, 'tk_Principal', ""), + ?line {"", <<>>, _} = cdr_decode:dec_type('tk_Principal', {1, 2}, B1, 0, big), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, 'tk_Principal', "principal"), + ?line {"principal", <<>>, _} = + cdr_decode:dec_type('tk_Principal', {1, 2}, B2, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: object reference +%%----------------------------------------------------------------- +version() -> #'IIOP_Version'{major=1,minor=2}. + +objref(0) -> + PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(), + host="my.hostname.org", + port=4040, + object_key="ExternalKey: which is an arbitary octet sequence", + components=[]}, + TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB}, + #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}; +objref(1) -> + K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", key, + list_to_pid("<0.100.0>")), + PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(), + host="my.hostname.org", + port=4040, + object_key=K, components=[]}, + TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB}, + #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}; +objref(2) -> + K = corba_fake_mk_objkey("IDL:Module/Interface:1.0", registered, + list_to_atom("orber_nameservice")), + PB = #'IIOP_ProfileBody_1_1'{iiop_version=version(), + host="my.hostname.org", + port=4040, + object_key=K, components=[]}, + TP = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB}, + #'IOP_IOR'{type_id="IDL:Module/Interface:1.0", profiles=[TP]}. + +objref_type(doc) -> []; +objref_type(suite) -> []; +objref_type(Config) when is_list(Config) -> + T = {'tk_objref', "IDL:Module/Interface:1.0", "Interface"}, + Objref0 = objref(0), + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T, Objref0), + ?line {Objref0, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B0, 0, big), + Objref1 = objref(1), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T, Objref1), + ?line {Objref1, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B1, 0, big), + Objref2 = objref(2), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T, Objref2), + ?line {Objref2, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B2, 0, big), + ok. + + + +%%----------------------------------------------------------------- +%% Encode/decode test of type: struct +%%----------------------------------------------------------------- +struct_type(doc) -> []; +struct_type(suite) -> []; +struct_type(Config) when is_list(Config) -> + T0 = {'tk_struct',"IDL:Module/Struct0:1.0", "Module_Struct0", + [{"long", 'tk_long'}, {"short", 'tk_short'}, {"character", 'tk_char'}]}, + S0 = #'Module_Struct0'{l=-4711, s=17, c=$a}, + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T0, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 2}, B0, 0, big), + + T1 = {'tk_struct', "IDL:Module/Struct1:1.0", "Module_Struct1", + [{"string", {'tk_string', 0}}, {"ushort", 'tk_ushort'}, {"ulong", 'tk_ulong'}]}, + S1 = #'Module_Struct1'{s="Hi !!!!", us=17, ul=4711}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B1, 0, big), + + T2 = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2", + [{"long_sequence", {'tk_sequence', 'tk_long', 0}}, + {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}}, + {"octet", 'tk_octet'}]}, + S2 = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], e=cow, o=$X}, + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 2}, B2, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: union +%%----------------------------------------------------------------- +union_type(doc) -> []; +union_type(suite) -> []; +union_type(Config) when is_list(Config) -> + T0 = {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2, + [{0, "First", 'tk_short'}, + {1, "Second", {'tk_string', 0}}, + {2, "Third", 'tk_char'}]}, + S0 = #'Module_Union'{label=1, value="Foo Bar !"}, + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T0, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 2}, B0, 0, big), + S1 = #'Module_Union'{label=0, value=-17}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T0, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T0, {1, 2}, B1, 0, big), + S2 = #'Module_Union'{label=2, value=$X}, + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T0, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type(T0, {1, 2}, B2, 0, big), + T1 = {'tk_union', "IDL:Module/Union1:1.0", "Union1", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", "apple"]}}]}, + S3 = #'Module_Union1'{label=pig, value=["Foo", "Bar", "!"]}, + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S3), + ?line {S3, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B3, 0, big), + S4 = #'Module_Union1'{label=cow, value=apple}, + ?line B4 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S4), + ?line {S4, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B4, 0, big), + S5 = #'Module_Union1'{label=horse, value=17}, + ?line B5 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S5), + ?line {S5, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B5, 0, big), + T2 = {'tk_union', "IDL:Module/Union2:1.0", "Union2", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", {'tk_array', 'tk_long', 3}}, + {"pig", "Second", + {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2, + [{0, "First", 'tk_short'}, + {1, "Second", {'tk_string', 0}}, + {2, "Third", 'tk_char'}]}}, + {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', + {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', + "IDL:Module/Enum1:1.0", + "Module_Enum1", + ["orange", "banana", + "apple"]}}]}}]}, + S6 = #'Module_Union2'{label=pig, value=#'Module_Union'{label=0, value=-17}}, + ?line B6 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, S6), + ?line {S6, <<>>, _} = cdr_decode:dec_type(T2, {1, 2}, B6, 0, big), + S7 = #'Module_Union2'{label=cow, value=#'Module_Union1'{label=pig, + value=["Foo", "Bar", "!"]}}, + ?line B7 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, S7), + ?line {S7, <<>>, _} = cdr_decode:dec_type(T2, {1, 2}, B7, 0, big), + S8 = #'Module_Union2'{label=horse, value={-17, 1234567890, -987654321}}, + ?line B8 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, S8), + ?line {S8, <<>>, _} = cdr_decode:dec_type(T2, {1, 2}, B8, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: string +%%----------------------------------------------------------------- +string_type(doc) -> []; +string_type(suite) -> []; +string_type(Config) when is_list(Config) -> + S0 = "Foo Bar ???", + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, {'tk_string', 0}, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 2}, B0, 0, big), + S1 = "Yes, Foo Bar !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! more than 5000 characters", + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, {'tk_string', 0}, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 2}, B1, 0, big), + S2 = "", + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, {'tk_string', 0}, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 2}, B2, 0, big), + S3 = "\0", + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, {'tk_string', 0}, S3), + ?line {S3, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 2}, B3, 0, big), + S4 = "~n", + ?line B4 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, {'tk_string', 0}, S4), + ?line {S4, <<>>, _} = cdr_decode:dec_type({'tk_string', 0}, {1, 2}, B4, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: array +%%----------------------------------------------------------------- +array_type(doc) -> []; +array_type(suite) -> []; +array_type(Config) when is_list(Config) -> + T0 = {'tk_array', 'tk_long', 5}, + S0 = {-100, 0, 30000, -900100900, 123456789}, + ?line B0 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T0, S0), + ?line {S0, <<>>, _} = cdr_decode:dec_type(T0, {1, 2}, B0, 0, big), + T1 = {'tk_array', {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, 2}, + S1 = {pig, cow}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B1, 0, big), + T2 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", ["horse", "pig", "cow"]}, "pig", + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", "apple"]}}]}, 2}, + S2 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}}, + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, S2), + ?line {S2, <<>>, _} = cdr_decode:dec_type(T2, {1, 2}, B2, 0, big), + T3 = {'tk_array', {'tk_objref', "IDL:Module/Interface:1.0", "Interface"}, 3}, + S3 = {objref(0), objref(1), objref(2)}, + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T3, S3), + ?line {S3, <<>>, _} = cdr_decode:dec_type(T3, {1, 2}, B3, 0, big), + ok. +%%----------------------------------------------------------------- +%% Encode/decode test of type: TypeCode +%%----------------------------------------------------------------- +any_type(doc) -> []; +any_type(suite) -> []; +any_type(Config) when is_list(Config) -> + T = 'tk_any', + TC = {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2", + [{"long_sequence", {'tk_sequence', 'tk_long', 0}}, + {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}}, + {"octet", 'tk_octet'}]}, + S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], + e=cow, o=$X}, + Any = #any{typecode=TC,value=S}, + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T,Any), + ?line {Any, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B, 0, big), + TC1 = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}, 1, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", + "apple"]}}]},2}, + S1 = {#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}}, + Any1 = #any{typecode=TC1,value=S1}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T,Any1), + ?line {Any1, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B1, 0, big), + ok. + + +%%----------------------------------------------------------------- +%% Encode/decode test of type: TypeCode +%%----------------------------------------------------------------- +typecode_type(doc) -> []; +typecode_type(suite) -> []; +typecode_type(Config) when is_list(Config) -> + T = 'tk_TypeCode', + TC = {'tk_array', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}, 1, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", + "apple"]}}]}, 10}, + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T,TC), + ?line {TC, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B, 0, big), + TC1 = {'tk_union', "IDL:Module/Union2:1.0", "Union2", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, 2, + [{"horse", "First", 'tk_long'}, + {"pig", "Second", + {'tk_union', "IDL:Module/Union:1.0", "Union", 'tk_short', 2, + [{0, "First", 'tk_short'}, + {1, "Second", {'tk_string', 0}}, + {2, "Third", 'tk_char'}]}}, + {"cow", "Third", {'tk_union', "IDL:Module/Union1:1.0", "Union1", + {'tk_enum', "IDL:Module/Enum:1.0", + "Module_Enum", ["horse", "pig", "cow"]}, 2, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', + {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', + "IDL:Module/Enum1:1.0", + "Module_Enum1", + ["orange", "banana", + "apple"]}}]}}]}, + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T, TC1), + ?line {TC1, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B1, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: TypeCode +%%----------------------------------------------------------------- +alias_type(doc) -> []; +alias_type(suite) -> []; +alias_type(Config) when is_list(Config) -> + T = {'tk_alias', "IDL:Module/Alias:1.0", "Alias", + {'tk_struct', "IDL:Module/Struct2:1.0", "Module_Struct2", + [{"long_sequence", {'tk_sequence', 'tk_long', 0}}, + {"enum", {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}}, + {"octet", 'tk_octet'}]}}, + S = #'Module_Struct2'{long_sequence=[4711, 350000, 0, -3030, -600000], + e=cow, o=$X}, + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T,S), + ?line {S, <<>>, _} = cdr_decode:dec_type(T, {1, 2}, B, 0, big), + T1 = {'tk_alias', "IDL:Module/Alias1:1.0", "Alias1", + {'tk_sequence', {'tk_union', "IDL:Module/Union:1.0", "Union", + {'tk_enum', "IDL:Module/Enum:1.0", "Module_Enum", + ["horse", "pig", "cow"]}, 2, + [{"horse", "First", 'tk_ushort'}, + {"pig", "Second", {'tk_sequence', {'tk_string', 0}, 0}}, + {"cow", "Third", {'tk_enum', "IDL:Module/Enum1:1.0", + "Module_Enum1", ["orange", "banana", + "apple"]}}]},0}}, + S1 = [#'Module_Union'{label=cow, value=banana}, #'Module_Union'{label=pig, value=["This", "is", "a", "test", ""]}], + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, S1), + ?line {S1, <<>>, _} = cdr_decode:dec_type(T1, {1, 2}, B1, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Encode/decode test of type: exception +%%----------------------------------------------------------------- +exception_type(doc) -> []; +exception_type(suite) -> []; +exception_type(Config) when is_list(Config) -> + system_exceptions(), + user_exceptions(), + ok. + +system_exceptions() -> + E = #'UNKNOWN'{completion_status=?COMPLETED_YES}, + {system_exception, T, E} = orber_exceptions:get_def(E), + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T,E), + ?line {E, _} = cdr_decode:dec_system_exception({1, 2}, B, 0, big), + E1 = #'INV_OBJREF'{completion_status=?COMPLETED_NO}, + {system_exception, T1, E1} = orber_exceptions:get_def(E1), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1,E1), + ?line {E1, _} = cdr_decode:dec_system_exception({1, 2}, B1, 0, big), + E2 = #'BAD_OPERATION'{completion_status=?COMPLETED_NO}, + {system_exception, T2, E2} = orber_exceptions:get_def(E2), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2,E2), + ?line {E2, _} = cdr_decode:dec_system_exception({1, 2}, B2, 0, big), + E3 = #'INTF_REPOS'{completion_status=?COMPLETED_MAYBE}, + {system_exception, T3, E3} = orber_exceptions:get_def(E3), + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T3,E3), + ?line {E3, _} = cdr_decode:dec_system_exception({1, 2}, B3, 0, big), + ok. + +user_exceptions() -> + E = #'Module_Except1'{rest_of_name=["I","am","testing","exceptions"], why="Error"}, + {user_exception, T, E} = orber_exceptions:get_def(E), + ?line B = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T, E), + ?line {E, _} = cdr_decode:dec_user_exception({1, 2}, B, 0, big), + E1 = #'Module_Except2'{e=banana, + s=#'Module_Struct2'{long_sequence=[12,-4040, + 1234567898], + e=horse, + o=$a}}, + {user_exception, T1, E1} = orber_exceptions:get_def(E1), + ?line B1 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T1, E1), + ?line {E1, _} = cdr_decode:dec_user_exception({1, 2}, B1, 0, big), + E2 = #'Module_Except3'{u=#'Module_Union1'{label=pig,value=["high","and","low"]},s=1313, o=objref(0)}, + {user_exception, T2, E2} = orber_exceptions:get_def(E2), + ?line B2 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T2, E2), + ?line {E2, _} = cdr_decode:dec_user_exception({1, 2}, B2, 0, big), + E3 = #'Module_Except4'{}, + {user_exception, T3, E3} = orber_exceptions:get_def(E3), + ?line B3 = cdr_encode:enc_type(#giop_env{version = {1, 2}}, T3, E3), + ?line {E3, _} = cdr_decode:dec_user_exception({1, 2}, B3, 0, big), + ok. + +%%----------------------------------------------------------------- +%% Test Case: request encoding test +%% Description: Precondition the stack must be started so the +%% objectkey is valid. +%%----------------------------------------------------------------- +%request(suite) -> []; +%request(_) -> +% exit(not_implemented). + +%%----------------------------------------------------------------- +%% Test Case: reply encoding test +%% Description: +%%----------------------------------------------------------------- +reply(doc) -> ["Description", "more description"]; +reply(suite) -> []; +reply(Config) when is_list(Config) -> + R = #reply_header{service_context=[], request_id=1, + reply_status='no_exception'}, + ?line B = cdr_encode:enc_reply(#giop_env{version = {1, 2}, request_id = 1, + reply_status = 'no_exception', + tc = {'tk_long', [], [{'tk_sequence', + {'tk_string', 0}, 0}]}, + result = 1200, + parameters = [["foo","Bar"]], + ctx = []}), + + ?line {R, 1200, [["foo","Bar"]]} = + cdr_decode:dec_message({'tk_long', [], [{'tk_sequence', {'tk_string', 0},0}]}, + B), + + ok. + +%%----------------------------------------------------------------- +%% Test Case: cancel_request encoding test +%% Description: +%%----------------------------------------------------------------- +cancel_request(doc) -> ["Description", "more description"]; +cancel_request(suite) -> []; +cancel_request(Config) when is_list(Config) -> + R = #cancel_request_header{request_id=1}, + ?line B = cdr_encode:enc_cancel_request(#giop_env{version = {1, 2}, + request_id = 1}), + ?line R = cdr_decode:dec_message([], B), + ok. + +%%----------------------------------------------------------------- +%% Test Case: locate_request encoding test +%% Description: +%%----------------------------------------------------------------- +locate_request(doc) -> ["Description", "more description"]; +locate_request(suite) -> []; +locate_request(Config) when is_list(Config) -> + io:format("Function not imlpemented yet"), + exit(not_implemented). + +%%----------------------------------------------------------------- +%% Test Case: locate_reply encoding test +%% Description: +%%----------------------------------------------------------------- +locate_reply(doc) -> ["Description", "more description"]; +locate_reply(suite) -> []; +locate_reply(Config) when is_list(Config) -> + io:format("Function not imlpemented yet"), + exit(not_implemented). + +%%----------------------------------------------------------------- +%% Test Case: close_connection encoding test +%% Description: +%%----------------------------------------------------------------- +close_connection(doc) -> ["Description", "more description"]; +close_connection(suite) -> []; +close_connection(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_close_connection(#giop_env{version = {1, 2}}), + ?line 'close_connection' = cdr_decode:dec_message([], B), + ok. + +%%----------------------------------------------------------------- +%% Test Case: message_error encoding test +%% Description: +%%----------------------------------------------------------------- +message_error(doc) -> ["Description", "more description"]; +message_error(suite) -> []; +message_error(Config) when is_list(Config) -> + ?line B = cdr_encode:enc_message_error(#giop_env{version = {1, 2}}), + ?line 'message_error' = cdr_decode:dec_message([], B), + ok. + + + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- +corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) -> + Key = make_objkey(), + {list_to_binary(Id), 'key', Key, term_to_binary(undefined), + term_to_binary(undefined), term_to_binary(undefined)}; +corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) -> + Key = term_to_binary(RegName), + {list_to_binary(Id), 'key', Key, term_to_binary(undefined), + term_to_binary(undefined), term_to_binary(undefined)}; +corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) -> + {list_to_binary(Id), 'registered', RegName, term_to_binary(undefined), + term_to_binary(undefined), term_to_binary(undefined)}. + +make_objkey() -> + term_to_binary({now(), node()}). diff --git a/lib/orber/test/cdrlib_SUITE.erl b/lib/orber/test/cdrlib_SUITE.erl new file mode 100644 index 0000000000..fa2d7f2a30 --- /dev/null +++ b/lib/orber/test/cdrlib_SUITE.erl @@ -0,0 +1,487 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for the CDR basic type encode/decode functions +%% +%%----------------------------------------------------------------- +-module(cdrlib_SUITE). + +-include("test_server.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> + [short, ushort, long, ulong, longlong, ulonglong, boolean, character, octet, + float, double, enum]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case: short integer test +%% Description: +%%----------------------------------------------------------------- +short(doc) -> ["Description", "more description"]; +short(suite) -> []; +short(_) -> + short_big_loop([-32768, -4040, -1, 0, 4040, 32767]), + short_little_loop([-32768, -4040, -1, 0, 4040, 32767]), + bad_short(). + +short_big_loop([]) -> + ok; +short_big_loop([X |List]) -> + ?line [CodedType] = cdrlib:enc_short(X, []), + ?line {X, <<>>} = cdrlib:dec_short(big, CodedType), + short_big_loop(List), + ok. + +short_little_loop([]) -> + ok; +short_little_loop([X |List]) -> + ?line CodedType = enc_short_little(X, []), + ?line {X, <<>>} = cdrlib:dec_short(little, CodedType), + short_little_loop(List), + ok. + +enc_short_little(X, Message) -> + list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff | Message]). + +bad_short() -> + ?line {'EXCEPTION', _} = (catch cdrlib:enc_short('atom', [])), + ?line [CodedType] = cdrlib:enc_char($a, []), + ?line {'EXIT', _} = (catch cdrlib:dec_short(big, CodedType)), + ok. +%%----------------------------------------------------------------- +%% Test Case: unsigned short integer test +%% Description: +%%----------------------------------------------------------------- +ushort(doc) -> ["Description", "more description"]; +ushort(suite) -> []; +ushort(_) -> + ushort_big_loop([0, 4040, 65535]), + ushort_little_loop([0, 4040, 65535]), + bad_ushort(). + +ushort_big_loop([]) -> + ok; +ushort_big_loop([X |List]) -> + ?line [CodedType] = cdrlib:enc_unsigned_short(X, []), + ?line {X, <<>>} = cdrlib:dec_unsigned_short(big, CodedType), + ushort_big_loop(List), + ok. + +ushort_little_loop([]) -> + ok; +ushort_little_loop([X |List]) -> + ?line CodedType = enc_ushort_little(X, []), + ?line {X, <<>>} = cdrlib:dec_unsigned_short(little, CodedType), + ushort_little_loop(List), + ok. + +enc_ushort_little(X, Message) -> + list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff | Message]). + +bad_ushort() -> + ok. +%%----------------------------------------------------------------- +%% Test Case: long integer test +%% Description: +%%----------------------------------------------------------------- +long(doc) -> ["Description", "more description"]; +long(suite) -> []; +long(_) -> + long_big_loop([-2147483648, -40404040, -32768, -4040, -1, + 0, 4040, 32767, 40404040, 2147483647]), + long_little_loop([-2147483648, -40404040, -32768, -4040, -1, + 0, 4040, 32767, 40404040, 2147483647]), + bad_long(). + + +long_big_loop([]) -> + ok; +long_big_loop([X |List]) -> + ?line [CodedType] = cdrlib:enc_long(X, []), + ?line {X, <<>>} = cdrlib:dec_long(big, CodedType), + long_big_loop(List), + ok. + +long_little_loop([]) -> + ok; +long_little_loop([X |List]) -> + ?line CodedType = enc_long_little(X, []), + ?line {X, <<>>} = cdrlib:dec_long(little, CodedType), + long_little_loop(List), + ok. + +enc_long_little(X, Message) -> + list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff, ((X) bsr 16) band 16#ff, + ((X) bsr 24) band 16#ff | Message]). + +bad_long() -> + ok. + +%%----------------------------------------------------------------- +%% Test Case: unsigned long integer test +%% Description: +%%----------------------------------------------------------------- +ulong(doc) -> ["Description", "more description"]; +ulong(suite) -> []; +ulong(_) -> + ulong_big_loop([0, 4040, 65535, 40404040, 2147483647, 4294967295]), + ulong_little_loop([0, 4040, 65535, 40404040, 2147483647, 4294967295]), + bad_ulong(). + + +ulong_big_loop([]) -> + ok; +ulong_big_loop([X |List]) -> + ?line [CodedType] = cdrlib:enc_unsigned_long(X, []), + ?line {X, <<>>} = cdrlib:dec_unsigned_long(big, CodedType), + ulong_big_loop(List), + ok. + +ulong_little_loop([]) -> + ok; +ulong_little_loop([X |List]) -> + ?line CodedType = enc_ulong_little(X, []), + ?line {X, <<>>} = cdrlib:dec_unsigned_long(little, CodedType), + ulong_little_loop(List), + ok. + +enc_ulong_little(X, Message) -> + list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff, ((X) bsr 16) band 16#ff, + ((X) bsr 24) band 16#ff | Message]). + + +bad_ulong() -> + ok. + +%%----------------------------------------------------------------- +%% Test Case: long integer test +%% Description: +%%----------------------------------------------------------------- +longlong(doc) -> ["Description", "more description"]; +longlong(suite) -> []; +longlong(_) -> + longlong_big_loop([-2147483648, -40404040, -32768, -4040, -1, + 0, 4040, 32767, 40404040, 2147483647]), + longlong_little_loop([-2147483648, -40404040, -32768, -4040, -1, + 0, 4040, 32767, 40404040, 2147483647]), + bad_longlong(). + + +longlong_big_loop([]) -> + ok; +longlong_big_loop([X |List]) -> + ?line [CodedType] = cdrlib:enc_longlong(X, []), + ?line {X, <<>>} = cdrlib:dec_longlong(big, CodedType), + longlong_big_loop(List), + ok. + +longlong_little_loop([]) -> + ok; +longlong_little_loop([X |List]) -> + ?line CodedType = enc_longlong_little(X, []), + ?line {X, <<>>} = cdrlib:dec_longlong(little, CodedType), + longlong_little_loop(List), + ok. + +enc_longlong_little(X, Message) -> + list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff, ((X) bsr 16) band 16#ff, + ((X) bsr 24) band 16#ff, ((X) bsr 32) band 16#ff, ((X) bsr 40) band 16#ff, + ((X) bsr 48) band 16#ff, ((X) bsr 56) band 16#ff | Message]). + +bad_longlong() -> + ok. + +%%----------------------------------------------------------------- +%% Test Case: unsigned long integer test +%% Description: +%%----------------------------------------------------------------- +ulonglong(doc) -> ["Description", "more description"]; +ulonglong(suite) -> []; +ulonglong(_) -> + ulonglong_big_loop([0, 4040, 65535, 40404040, 2147483647, 4294967295]), + ulonglong_little_loop([0, 4040, 65535, 40404040, 2147483647, 4294967295]), + bad_ulonglong(). + + +ulonglong_big_loop([]) -> + ok; +ulonglong_big_loop([X |List]) -> + ?line [CodedType] = cdrlib:enc_unsigned_longlong(X, []), + ?line {X, <<>>} = cdrlib:dec_unsigned_longlong(big, CodedType), + ulonglong_big_loop(List), + ok. + +ulonglong_little_loop([]) -> + ok; +ulonglong_little_loop([X |List]) -> + ?line CodedType = enc_ulonglong_little(X, []), + ?line {X, <<>>} = cdrlib:dec_unsigned_longlong(little, CodedType), + ulonglong_little_loop(List), + ok. + +enc_ulonglong_little(X, Message) -> + list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff, ((X) bsr 16) band 16#ff, + ((X) bsr 24) band 16#ff, ((X) bsr 32) band 16#ff, ((X) bsr 40) band 16#ff, + ((X) bsr 48) band 16#ff, ((X) bsr 56) band 16#ff | Message]). + +bad_ulonglong() -> + ok. + + + +%%----------------------------------------------------------------- +%% Test Case: boolean test +%% Description: +%%----------------------------------------------------------------- +boolean(doc) -> ["Description", "more description"]; +boolean(suite) -> []; +boolean(_) -> + ?line [CodedTrue] = cdrlib:enc_bool('true', []), + ?line {'true', <<>>} = cdrlib:dec_bool(CodedTrue), + ?line [CodedFalse] = cdrlib:enc_bool('false', []), + ?line {'false', <<>>} = cdrlib:dec_bool(CodedFalse), + ok. + +%%----------------------------------------------------------------- +%% Test Case: character test +%% Description: +%%----------------------------------------------------------------- +character(doc) -> ["Description", "more description"]; +character(suite) -> []; +character(_) -> + ?line [Coded_0] = cdrlib:enc_char($0, []), + ?line {$0, <<>>} = cdrlib:dec_char(Coded_0), + ?line [Coded_a] = cdrlib:enc_char($a, []), + ?line {$a, <<>>} = cdrlib:dec_char(Coded_a), + ?line [Coded_Z] = cdrlib:enc_char($Z, []), + ?line {$Z, <<>>} = cdrlib:dec_char(Coded_Z), + ?line [Coded_dollar] = cdrlib:enc_char($$, []), + ?line {$$, <<>>} = cdrlib:dec_char(Coded_dollar), + ok. + +%%----------------------------------------------------------------- +%% Test Case: octet test +%% Description: +%%----------------------------------------------------------------- +octet(doc) -> ["Description", "more description"]; +octet(suite) -> []; +octet(_) -> + ?line [Coded_ff] = cdrlib:enc_octet(16#ff, []), + ?line {16#ff, <<>>} = cdrlib:dec_octet(Coded_ff), + ?line [Coded_00] = cdrlib:enc_octet(16#00, []), + ?line {16#00, <<>>} = cdrlib:dec_octet(Coded_00), + ?line [Coded_5a] = cdrlib:enc_octet(16#5a, []), + ?line {16#5a, <<>>} = cdrlib:dec_octet(Coded_5a), + ?line [Coded_48] = cdrlib:enc_octet(16#48, []), + ?line {16#48, <<>>} = cdrlib:dec_octet(Coded_48), + ok. + + + +%%----------------------------------------------------------------- +%% Test Case: float test +%% Description: +%%----------------------------------------------------------------- +float(doc) -> ["Description", "more description"]; +float(suite) -> []; +float(_) -> + G = 16#7fffff / 16#800000 + 1.0, + H1 = math:pow(2, 127), + H2 = math:pow(2, -126), + float_big_loop([-H1 * G, -H1 * 1.0, -H2 * G, -H2 * 1.0, + -4040.313131, -3.141592, 0.0, 3.141592, 4040.313131, + H1 * G, H1 * 1.0, H2 * G, H2 * 1.0]), + float_little_loop([-H1 * G, -H1 * 1.0, -H2 * G, -H2 * 1.0, + -4040.313131, -3.141592, 0.0, 3.141592, 4040.313131, + H1 * G, H1 * 1.0, H2 * G, H2 * 1.0]), + ok. + +float_big_loop([]) -> + ok; +float_big_loop([X |List]) -> + ?line [CodedType] = cdrlib:enc_float(X, []), + ?line {Y, <<>>} = cdrlib:dec_float(big, CodedType), + ?line float_comp(X,Y), + float_big_loop(List), + ok. + +float_little_loop([]) -> + ok; +float_little_loop([X |List]) -> + ?line [CodedType] = enc_float_little(X, []), + ?line {Y, <<>>} = cdrlib:dec_float(little, CodedType), + ?line float_comp(X,Y), + float_little_loop(List), + ok. + +float_comp(X,Y) when X == 0.0, Y == 0.0 -> + ok; +float_comp(X,Y) -> + Div = abs(Y) / abs(X), + %% io:format("~p~n", [float_to_list(Div)]), + ?line true = (Div < 1.0000001), + ?line true = (Div > 0.9999999), + ok. + +enc_float_little(X, Message) -> + [ <<X:32/little-float>> | Message]. + +%%----------------------------------------------------------------- +%% Test Case: double test +%% Description: +%%----------------------------------------------------------------- +double(doc) -> ["Description", "more description"]; +double(suite) -> []; +double(_) -> + F = 16#0fffffffffffff / 16#10000000000000 + 1.0, + E1 = math:pow(2, 1023), + E2 = math:pow(2, -1022), + G = 16#7fffff / 16#800000 + 1.0, + H1 = math:pow(2, 128), + H2 = math:pow(2, -127), + double_big_loop([-E1 * F, -E1 * 1.0, -E2 * F, -E2 * 1.0, + -H1 * G, -H1 * 1.0, -H2 * G, -H2 * 1.0, + -4040.313131, -3.141592, 0.0, 3.141592, 4040.313131, + H1 * G, H1 * 1.0, H2 * G, H2 * 1.0, + E1 * F, E1 * 1.0, E2 * F, E2 * 1.0]), + double_little_loop([-E1 * F, -E1 * 1.0, -E2 * F, -E2 * 1.0, + -H1 * G, -H1 * 1.0, -H2 * G, -H2 * 1.0, + -4040.313131, -3.141592, 0.0, 3.141592, 4040.313131, + H1 * G, H1 * 1.0, H2 * G, H2 * 1.0, + E1 * F, E1 * 1.0, E2 * F, E2 * 1.0]), + ok. + +double_big_loop([]) -> + ok; +double_big_loop([X |List]) -> + ?line [CodedType] = cdrlib:enc_double(X, []), + ?line {Y, <<>>} = cdrlib:dec_double(big, CodedType), + ?line double_comp(X,Y), + double_big_loop(List), + ok. + +double_little_loop([]) -> + ok; +double_little_loop([X |List]) -> + ?line [CodedType] = enc_double_little(X, []), + ?line {Y, <<>>} = cdrlib:dec_double(little, CodedType), + ?line double_comp(X,Y), + double_little_loop(List), + ok. + +enc_double_little(X, Message) -> + [ <<X:64/little-float>> | Message]. + +double_comp(X,Y) when X == 0.0, Y == 0.0 -> + ok; +double_comp(X,Y) -> + Div = abs(Y) / abs(X), + %% io:format("~p~n", [float_to_list(Div)]), + ?line true = (Div < 1.00000000000001), + ?line true = (Div > 0.99999999999999), + ok. + +double_should_be_ok(doc) -> ["Description", "more description"]; +double_should_be_ok(suite) -> []; +double_should_be_ok(_) -> + F = 16#0fffffffffffff / 16#10000000000000 + 1.0, + E1 = math:pow(2, 1024), % erlang can't handle this. + E2 = math:pow(2, -1023), + double_big_loop([-E1 * F, -E1 * 1.0, -E2 * F, -E2 * 1.0, + E1 * F, E1 * 1.0, E2 * F, E2 * 1.0]), + double_little_loop([-E1 * F, -E1 * 1.0, -E2 * F, -E2 * 1.0, + E1 * F, E1 * 1.0, E2 * F, E2 * 1.0]), + ok. + +%%----------------------------------------------------------------- +%% Test Case: enum test +%% Description: +%%----------------------------------------------------------------- +enum(doc) -> ["Description", "more description"]; +enum(suite) -> []; +enum(_) -> + enum_big(), + enum_little(), + ok. + +enum_big() -> + ?line [Coded_a] = cdrlib:enc_enum(a,[a,b,c],[]), + ?line {a, <<>>} = cdrlib:dec_enum(big, ["a","b","c"], Coded_a), + ?line [Coded_b] = cdrlib:enc_enum(b,[a,b,c],[]), + ?line {b, <<>>} = cdrlib:dec_enum(big, ["a","b","c"], Coded_b), + ?line [Coded_c] = cdrlib:enc_enum(c,[a,b,c],[]), + ?line {c, <<>>} = cdrlib:dec_enum(big, ["a","b","c"], Coded_c), + ok. + +enum_little() -> + ?line Coded_a = enc_r_enum(a,[a,b,c],[]), + ?line {a, <<>>} = cdrlib:dec_enum(little, ["a","b","c"], Coded_a), + ?line Coded_b = enc_r_enum(b,[a,b,c],[]), + ?line {b, <<>>} = cdrlib:dec_enum(little, ["a","b","c"], Coded_b), + ?line Coded_c = enc_r_enum(c,[a,b,c],[]), + ?line {c, <<>>} = cdrlib:dec_enum(little, ["a","b","c"], Coded_c), + ok. + +enc_r_enum(Enum, ElemList, Message) -> + Val = getEnumValue(ElemList,Enum, 0), + enc_r_unsigned_long(Val, Message). + +getEnumValue([Enum |_List], Enum, N) -> + N; +getEnumValue([_ |List], Enum, N) -> + getEnumValue(List, Enum, N + 1). + +enc_r_unsigned_long(X, Message) -> + list_to_binary([(X) band 16#ff, ((X) bsr 8) band 16#ff, + ((X) bsr 16) band 16#ff, ((X) bsr 24) band 16#ff | Message]). diff --git a/lib/orber/test/corba_SUITE.erl b/lib/orber/test/corba_SUITE.erl new file mode 100644 index 0000000000..dae8fcbefc --- /dev/null +++ b/lib/orber/test/corba_SUITE.erl @@ -0,0 +1,909 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for corba/boa/object/orber API functions +%% +%%----------------------------------------------------------------- +-module(corba_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + + +-define(default_timeout, ?t:minutes(5)). + +-define(match(ExpectedRes,Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([pseudo_calls/2, pseudo_casts/2]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for the CORBA/BOA/Object/orber interfaces", ""]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [exception_info_api, corba_api, object_api, orber_api, + orber_objectkeys_api, orber_pseudo_objects, callback_ok_api, + callback_arity_api, callback_module_api, callback_function_api, + callback_precond_api, callback_postcond_api, callback_exit_api, + callback_badarith_api, callback_case_clause_api, + callback_function_clause_api]. + +%% boa_api, request, locate_request, locate_reply]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + corba:orb_init([{orber_debug_level, 10}, {giop_version, {1,2}}, + {iiop_port, 0}]), + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + orber:install([node()]), + application:start(mnesia), + application:start(orber), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + application:stop(orber), + application:stop(mnesia), + mnesia:delete_schema([node()]), + Config. + +%%----------------------------------------------------------------- +%% API tests for pseudo interface CORBA +%%----------------------------------------------------------------- +corba_api(doc) -> ["CORBA API tests", ""]; +corba_api(suite) -> []; +corba_api(_) -> + NIL = corba:create_nil_objref(), + ?line ok = corba:dispose(NIL), + ?line NS = corba:resolve_initial_references("NameService"), + ?line List = corba:list_initial_services(), + ?line ["NameService"] = List, + ?line NSstring = corba:object_to_string(NS), + ?line NS1 = corba:string_to_object(NSstring), + ?line NSstring = corba:object_to_string(NS1), + ?line true = corba:add_initial_service("MyData", NS), + ?line NS = corba:resolve_initial_references("MyData"), + ?line [_,_] = corba:list_initial_services(), + ?line false = corba:remove_initial_service("Wrong"), + ?line NIL = corba:resolve_initial_references("Wrong"), + ?line NS = corba:string_to_object("corbaloc:rir:/MyData"), + ?line true = corba:remove_initial_service("MyData"), + ?line ["NameService"] = corba:list_initial_services(), + + %% This is a collection of different stringified IOR:s (correct & incorrect) + %% which we use to test IOR encode/decode. + ?line IOR1 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000040000000000000100000102010000000a3132372e302e302e31009d610000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e2316570000000003030300000002000000210000007800010202000000010040020200000022000000080003030300000000004000400000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c00030303000100010000000400010020000101090001010005010001000101090000000200010100050100010000000000000184000102010000000a3132372e302e302e310000000000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e231657000000000303030000000300000021000000ec000102020000000200060202000000240000001c0001006600060202000000010000000a3132372e302e302e31009d600000000000000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f00460202000000240000001c0001006600060202000000010000000a3132372e302e302e31009d62004000400000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f00000014000000080001006600069d5e000000010000002c000303030001000100000004000100200001010900010100050100010001010900000002000101000501000100000000000000dc000102010000000a3132372e302e302e31009d5f0000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e23165700000000030303000000020000002100000054000102020000000100000202000000220000000800030303000000000000000000000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c00030303000100010000000400010020000101090001010005010001000101090000000200010100050100010000000000000080000102010000000a3132372e302e302e31009d5d0000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e2316570000000003030300000001000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")), + ?line IOR2 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e30000303030000000100000000000000e0000102010000000a3132372e302e302e31009d5f00000034abacab3131303432343836383731005f526f6f74504f410049494f505f43534976325f504f410000cafebabe3e23165700000000000000020000002100000054000102020000000100000202000000220000000800030303000000000000000000000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")), + ?line IOR3 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000108000102010000000a3132372e302e302e31009d6100000037abacab3131303432343836383731005f526f6f74504f410049494f505f43534976325f55505f504f410000cafebabe3e231657000000000100000002000000210000007800010202000000010040020200000022000000080003030300000000004000400000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")), + ?line IOR4 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000080000102010000000a3132372e302e302e31009d5d0000002eabacab3131303432343836383731005f526f6f74504f410049494f505f504f410000cafebabe3e23165700000000020200000001000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")), + ?line IOR5 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e30000303030000000100000000000000fc000102010000000a3132372e302e302e3100000000000033abacab3131303432343836383731005f526f6f74504f4100544c535f43534976325f504f410000cafebabe3e231657000000000100000002000000210000007000010202000000010006020200000024000000220001006600060202000000010000000f3132382e3233302e3230382e353500019d6000000000020200000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")), + ?line IOR6 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000124000102010000000a3132372e302e302e3100000000000036abacab3131303432343836383731005f526f6f74504f4100544c535f43534976325f55505f504f410000cafebabe3e23165700000000020200000002000000210000009400010202000000010046020200000024000000220001006600060202000000010000000f3132382e3233302e3230382e353500019d620040004002020000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")), + ?line IOR7 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000090000102010000000a3132372e302e302e310000000000002dabacab3131303432343836383731005f526f6f74504f4100544c535f504f410000cafebabe3e231657000000000303030000000200000014000000080001006600069d5e000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")), + ?line IOR1 = corba:string_to_object(corba:object_to_string(IOR1)), + ?line IOR2 = corba:string_to_object(corba:object_to_string(IOR2)), + ?line IOR3 = corba:string_to_object(corba:object_to_string(IOR3)), + ?line IOR4 = corba:string_to_object(corba:object_to_string(IOR4)), + ?line IOR5 = corba:string_to_object(corba:object_to_string(IOR5)), + ?line IOR6 = corba:string_to_object(corba:object_to_string(IOR6)), + ?line IOR7 = corba:string_to_object(corba:object_to_string(IOR7)), + ?line ?match(ok, corba:print_object(IOR1)), + ?line ?match(ok, corba:print_object(IOR2)), + ?line ?match(ok, corba:print_object(IOR3)), + ?line ?match(ok, corba:print_object(IOR4)), + ?line ?match(ok, corba:print_object(IOR5)), + ?line ?match(ok, corba:print_object(IOR6)), + ?line ?match(ok, corba:print_object(IOR7)), + ?line ?match(ok, corba:print_object("IOR:000303030000000d49444c3a746573743a312e300003030300000002000000000000003000010001000000136d792e686f73742e65726c616e672e6f72670001801a02020000000c424f410a00000a0000070a010000000100000024000303030000000100000001000000140003030300010001000000000001010900000000")), + [IP] = ?match([_], orber:host()), + ?match(#'IOP_IOR'{profiles=[#'IOP_TaggedProfile' + {tag=?TAG_INTERNET_IOP, + profile_data=#'IIOP_ProfileBody_1_1' + {host = IP}}]}, + corba:string_to_object(corba:object_to_string(NS))), + ?match(#'IOP_IOR'{profiles=[#'IOP_TaggedProfile' + {tag=?TAG_INTERNET_IOP, + profile_data=#'IIOP_ProfileBody_1_1' + {host = "127.0.0.1"}}]}, + corba:string_to_object(corba:object_to_string(NS, ["127.0.0.1"]))), + ?match(#'IOP_IOR'{profiles=[#'IOP_TaggedProfile' + {tag=?TAG_INTERNET_IOP, + profile_data=#'IIOP_ProfileBody_1_1' + {host = "127.0.0.1", port = 5468}}]}, + corba:string_to_object(corba:object_to_string(NS, ["127.0.0.1"], + 5468))), + ok. + +%%----------------------------------------------------------------- +%% API tests for interface BOA +%%----------------------------------------------------------------- +boa_api(doc) -> ["BOA API tests", ""]; +boa_api(suite) -> []; +boa_api(_) -> + ok. + +%%----------------------------------------------------------------- +%% API tests for interface OBJECT +%%----------------------------------------------------------------- +object_api(doc) -> ["Object API tests", ""]; +object_api(suite) -> []; +object_api(_) -> + ?line oe_orber_test_server:oe_register(), + ?line EC = orber_test_server:oe_create(), + ?line NS = corba:resolve_initial_references("NameService"), + %% testing corba_object:is_a(Obj, IFRID) locally. + ?line orber_test_lib:corba_object_tests(EC, NS), + + ?line ?match(false, corba_object:non_existent(NS)), + + ?line corba:dispose(EC), + ?line oe_orber_test_server:oe_unregister(), + ok. + +%%----------------------------------------------------------------- +%% API tests for orbers main module +%%----------------------------------------------------------------- +orber_api(doc) -> ["orber API tests", ""]; +orber_api(suite) -> []; +orber_api(_) -> + ?line ok = orber:uninstall(), + ?line orber:install([node()]), + ?line application:start(orber), + ?line NodeList = orber:orber_nodes(), + ?line NL = node(), + ?line [NL] = NodeList, + ok. + +%%----------------------------------------------------------------- +%% API tests for exception mapping +%%----------------------------------------------------------------- +exception_info_api(doc) -> ["orber API tests", ""]; +exception_info_api(suite) -> []; +exception_info_api(_) -> + ?line {ok, S1} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1163001858,'COMPLETED_NO'}}), + ?line {ok, S2} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1330446337,'COMPLETED_NO'}}), + ?line {ok, S3} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1398079490,'COMPLETED_NO'}}), + ?line {ok, S4} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1347813377,'COMPLETED_NO'}}), + ?line {ok, S5} = orber:exception_info({'EXCEPTION', {'CosNaming_NamingContext_InvalidName',"IDL:omg.org/CosNaming/NamingContext/InvalidName:1.0"}}), + ?line error_logger:info_msg("~s", [S1]), + ?line error_logger:info_msg("~s", [S2]), + ?line error_logger:info_msg("~s", [S3]), + ?line error_logger:info_msg("~s", [S4]), + ?line error_logger:info_msg("~s", [S5]), + ok. + +%%----------------------------------------------------------------- +%% API tests for orbers pseudo objects. +%%----------------------------------------------------------------- +orber_pseudo_objects(doc) -> ["orber_pseudo_objects API tests", ""]; +orber_pseudo_objects(suite) -> []; +orber_pseudo_objects(_) -> + ?line oe_orber_test_server:oe_register(), + Obj1=(catch orber_test_server:oe_create(state,[{pseudo,true}, + {local_typecheck, true}])), + ?line ?match({_,pseudo,orber_test_server_impl, _,_, _}, Obj1), + Obj2=(catch orber_test_server:oe_create([],[{pseudo, truce}])), + ?line ?match({'EXCEPTION',{'BAD_PARAM',[],_,'COMPLETED_NO'}}, Obj2), + spawn(?MODULE, pseudo_calls, [20, Obj1]), + ?line ?match({ok, 10000}, orber_test_server:pseudo_call_delay(Obj1, 10000)), + spawn(?MODULE, pseudo_casts, [20, Obj1]), + ?line ?match(ok, orber_test_server:pseudo_cast_delay(Obj1, 10000)), + + ?line ?match('object_here', corba:locate(Obj1)), + + ?line NS = corba:resolve_initial_references("NameService"), + + ?line orber_test_lib:corba_object_tests(Obj1, NS), + + ?line ?match("IDL:omg.org/orber_test/server:1.0",orber_test_server:typeID()), + + %% Test if exceptions are handled properly. + ?line ?match({'EXCEPTION',{'BAD_QOS',_,_,_}}, + orber_test_server:pseudo_call_raise_exc(Obj1, 1)), + ?line ?match({'EXCEPTION',{'BAD_QOS',_,_,_}}, + orber_test_server:pseudo_call_raise_exc(Obj1, 2)), + + %% Test if exit is handled properly. + ?line ?match({'EXCEPTION',{'TRANSIENT',_,_,_}}, + orber_test_server:stop_brutal(Obj1)), + + orber_test_lib:test_coding(Obj1, true), + + %% possible to use subobject key? + ?line ?match(state, binary_to_term(corba:get_subobject_key(Obj1))), + + ?line ?match({'EXCEPTION',{'INV_OBJREF',[],_,'COMPLETED_NO'}}, + corba:get_pid(Obj1)), + ?line ?match(false, corba_object:non_existent(Obj1)), + + ?line ?match(ok, corba:dispose(Obj1)), + + ?line ?match(false, corba_object:non_existent(Obj1)), + + %% Try if it's possible to stringify and recover the object reference. + IOR_string = (catch corba:object_to_string(Obj1)), + Obj3 =(catch corba:string_to_object(IOR_string)), + ?line ?match(IOR_string, corba:object_to_string(Obj3)), + + Obj4=(catch orber_test_server:oe_create(undefined,[{pseudo,true}])), + ?line ?match(ok, corba:dispose(Obj4)), + ?line oe_orber_test_server:oe_unregister(), + ok. + +%%----------------------------------------------------------------- +%% API tests for orbers objectkeys server. +%%----------------------------------------------------------------- +orber_objectkeys_api(doc) -> ["orber_objectkeys API tests", ""]; +orber_objectkeys_api(suite) -> []; +orber_objectkeys_api(_) -> + Obj0=(catch orber_test_server:oe_create([], [{sup_child, true}])), + Obj1=(catch orber_test_server:oe_create([], [{persistent, true}, + {regname, {local,obj1}}])), + Obj2=(catch orber_test_server:oe_create([], [{persistent, true}, + {regname, {global,{obj2, 12345}}}])), + + %% Obj0 is supposed to be a child started by a supervisor (r6) which + %% handles not only {ok, Pid} but also {ok,Pid, Returnvalue}. In our + %% case the Returnvalue is an ObjectRef. + ?line ?match({ok,_,{_,key,_, _,_, _}}, Obj0), + {ok,_,Obj0Ref} = Obj0, + corba:dispose(Obj0Ref), + + %% Only 'global' servers are at the moment allowed to be persistent. + ?line ?match({'EXCEPTION',{'BAD_PARAM',[],_,'COMPLETED_NO'}}, Obj1), + + %% We created a persistent object successfully. + ?line ?match({_,key,_,_,_, _}, Obj2), + + %% Get key and Pid + {_,_,Key,_,_, _} = Obj2, + PID=(catch orber_objectkeys:get_pid(Key)), + + %% Use the two different ways to look up if the server is persistent. + ?line ?match(true, orber_objectkeys:is_persistent(Key)), + ?line ?match(true, orber_objectkeys:is_persistent(PID)), + + %% Create servers using every possible way. + O1=(catch orber_test_server:oe_create()), + O2=(catch orber_test_server:oe_create_link()), + O3=(catch orber_test_server:oe_create([])), + O4=(catch orber_test_server:oe_create_link([])), + %% NOTE!!! Next four lines requires that we still support RegName instead of + %% only OptionList as the second argument to oe_create*/2. Remove these when that + %% is no longer the case. + O5=(catch orber_test_server:oe_create([], {'local', o5})), + O6=(catch orber_test_server:oe_create([], {'global', {o6, obj}})), + O7=(catch orber_test_server:oe_create_link([], {'local', o7})), + O8=(catch orber_test_server:oe_create_link([], {'global', {o8, obj}})), + + %% Test if all the object references are correct. + ?line ?match({_,key,_,_,_, _}, O1), + ?line ?match({_,key,_,_,_, _}, O2), + ?line ?match({_,key,_,_,_, _}, O3), + ?line ?match({_,key,_,_,_, _}, O4), + ?line ?match({_, registered, o5, _,_, _}, O5), + ?line ?match({_,key,_,_,_, _}, O6), + ?line ?match({_, registered, o7, _,_, _}, O7), + ?line ?match({_,key,_,_,_, _}, O8), + + %% Test if persistent. + {_,_,Key1,_,_, _} = O1, + PID1=(catch orber_objectkeys:get_pid(Key1)), + ?line ?match(false, orber_objectkeys:is_persistent(Key1)), + ?line ?match(false, orber_objectkeys:is_persistent(PID1)), + + %% all the servers are alive(?!). + ?line ?match(false, corba_object:non_existent(O1)), + ?line ?match(false, corba_object:non_existent(O2)), + ?line ?match(false, corba_object:non_existent(O3)), + ?line ?match(false, corba_object:non_existent(O4)), + ?line ?match(false, corba_object:non_existent(O5)), + ?line ?match(false, corba_object:non_existent(O6)), + ?line ?match(false, corba_object:non_existent(O7)), + ?line ?match(false, corba_object:non_existent(O8)), + ?line ?match(false, corba_object:non_existent(Obj2)), + + %% Does locate work? + ?line ?match('object_here', corba:locate(O1)), + ?line ?match('object_here', corba:locate(O2)), + ?line ?match('object_here', corba:locate(O3)), + ?line ?match('object_here', corba:locate(O4)), + ?line ?match('object_here', corba:locate(O5)), + ?line ?match('object_here', corba:locate(O6)), + ?line ?match('object_here', corba:locate(O7)), + ?line ?match('object_here', corba:locate(O8)), + ?line ?match('object_here', corba:locate(Obj2)), + + %% Terminate all servers with reason 'normal'. + catch corba:dispose(O1), + catch corba:dispose(O2), + catch corba:dispose(O3), + catch corba:dispose(O4), + catch corba:dispose(O5), + catch corba:dispose(O6), + catch corba:dispose(O7), + catch corba:dispose(O8), + catch corba:dispose(Obj2), + + + %% To make sure that orber_objectkeys-server is able to + %% clean up we wait. + timer:sleep(2000), + + %% all the servers are dead(?!). If one of these test-cases + %% fails the only error can be that we didn't sleep long enough, i.e., + %% try a longer timeout. If still fails something is wrong. + ?line ?match(true, corba_object:non_existent(O1)), + ?line ?match(true, corba_object:non_existent(O2)), + ?line ?match(true, corba_object:non_existent(O3)), + ?line ?match(true, corba_object:non_existent(O4)), + ?line ?match(true, corba_object:non_existent(O5)), + ?line ?match(true, corba_object:non_existent(O6)), + ?line ?match(true, corba_object:non_existent(O7)), + ?line ?match(true, corba_object:non_existent(O8)), + ?line ?match(true, corba_object:non_existent(Obj2)), + + %% Create a new persistent server. + Obj3=(catch orber_test_server:oe_create([], + [{persistent, true}, + {regname, {global,{obj2, 12345}}}])), + + %% OK?! + ?line ?match({_,key,_,_,_, _}, Obj3), + + %% Try to create a server with the same name (naturally it fails). + ?line ?match({'EXCEPTION',{'INTERNAL',[],_,'COMPLETED_NO'}}, + orber_test_server:oe_create([], + [{persistent, true}, + {regname, {global,{obj2, 12345}}}])), + %% Try to remove all 'dead' servers. No server should be removed. + orber_objectkeys:gc(0), + + %% Kill object brutal, i.e., not with reason 'normal' or 'shutdown'. + P3 = corba:get_pid(Obj3), + exit(P3, kill), + + {_,_,Key3,_,_, _} = Obj3, + + %% Give time to clean up. + timer:sleep(2000), + ?line ?match({'EXCEPTION',{'TRANSIENT',[],_,'COMPLETED_NO'}}, + gen_server:call(orber_objkeyserver, + {get_pid, Key3}, + infinity)), + + ?line ?match(false,corba_object:non_existent(Obj3)), + + %% Run gc wit a "huge" time-limit. Will not erase the dead object. + orber_objectkeys:gc(10000), + ?line ?match(false,corba_object:non_existent(Obj3)), + + %% Run gc with minimum time-limit. Will erase the dead object. + orber_objectkeys:gc(0), + ?line ?match(true,corba_object:non_existent(Obj3)), + + %% Create a new persistent server. + Obj4=(catch orber_test_server:oe_create([], + [{persistent, true}, + {regname, {global,{obj2, 12345}}}])), + + %% OK?! + ?match({_,key,_,_,_, _}, Obj4), + %% Kill object brutal, i.e., not with reason 'normal' or 'shutdown'. + P4 = corba:get_pid(Obj4), + exit(P4, kill), + + %% Give time to clean up. + timer:sleep(2000), +% ?line ?match({'EXCEPTION',{'COMM_FAILURE',[],0,'COMPLETED_NO'}}, + ?line ?match({error, _}, + corba:get_pid(Obj4)), + + ?line ?match(false,corba_object:non_existent(Obj4)), + + %% Restart the object. + Obj5=(catch orber_test_server:oe_create([], + [{persistent, true}, + {regname, {global,{obj2, 12345}}}])), + %% OK?! + ?line ?match({_,key,_,_,_, _}, Obj5), + + %% Run gc with minimum time-limit. + orber_objectkeys:gc(0), + ?line ?match(false,corba_object:non_existent(Obj5)), + corba:dispose(Obj5), + ok. + + +%%----------------------------------------------------------------- +%% API tests for callback functions +%%----------------------------------------------------------------- +-define(DO_EXIT_FLAG, 0). +-define(NO_EXIT_FLAG, 16#10). + +-define(DO_EXIT, {is, 0}). +-define(NO_EXIT, {is, 16#10}). + + + +callback_ok_api(doc) -> ["Successful callbak API tests", ""]; +callback_ok_api(suite) -> []; +callback_ok_api(_) -> + %% Init + ?line ?match({ok, {?DO_EXIT, state}}, corba:handle_init(?MODULE, {?DO_EXIT_FLAG, state})), + %% Terminate + ?line ?match(ok, corba:handle_terminate(?MODULE, "reason", {?DO_EXIT, state})), + %% Handle_call + ?line ?match({reply,ok,{?DO_EXIT,state}}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, state}, [], false, false)), + %% Handle_cast + ?line ?match({noreply, {?DO_EXIT,state}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, state}, [], false)), + %% Handle_call precond/postcond + ?line ?match({reply, ok, {?DO_EXIT, state}}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, state}, [], false, false, {?MODULE, precond}, + {?MODULE, postcond}, ?MODULE)), + %% Handle_cast precond/postcond + ?line ?match({noreply, {?DO_EXIT, state}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, state}, [], false, {?MODULE, precond}, + {?MODULE, postcond}, ?MODULE)), + %% Handle_info + ?line ?match({noreply, {?DO_EXIT, state}}, + corba:handle_info(?MODULE, "info", {?DO_EXIT, state})), + ok. + +callback_arity_api(doc) -> ["callbak arity API tests", ""]; +callback_arity_api(suite) -> []; +callback_arity_api(_) -> + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', {undef,_}}, + corba:handle_call(?MODULE, foo, [to, many, arguments], + {?DO_EXIT, state}, [], false, false)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _}, + corba:handle_call(?MODULE, foo, [to, many, arguments], + {?NO_EXIT, state}, [], false, false)), + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, arity}, [], false, false)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _}, + corba:handle_call(?MODULE, foo, [], + {?NO_EXIT, arity}, [], false, false)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', {undef,_}}, + corba:handle_cast(?MODULE, foo_1w, [to, many, arguments], + {?DO_EXIT, state}, [], false)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, state}}, + corba:handle_cast(?MODULE, foo_1w, [to, many, arguments], + {?NO_EXIT, state}, [], false)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, arity}, [], false)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, arity}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?NO_EXIT, arity}, [], false)), + %% Handle_info - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_info(?MODULE, "info", {?DO_EXIT, arity})), + + %% Handle_info - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, arity}}, + corba:handle_info(?MODULE, "info", {?NO_EXIT, arity})), + ok. + +callback_module_api(doc) -> ["Module callbak API tests", ""]; +callback_module_api(suite) -> []; +callback_module_api(_) -> + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', {undef,_}}, + corba:handle_call(wrong_mod, foo, [], + {?DO_EXIT, state}, [], false, false)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _}, + corba:handle_call(wrong_mod, foo, [], + {?NO_EXIT, state}, [], false, false)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', {undef,_}}, + corba:handle_cast(wrong_mod, foo_1w, [], + {?DO_EXIT, state}, [], false)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, state}}, + corba:handle_cast(wrong_mod, foo_1w, [], + {?NO_EXIT, state}, [], false)), + %% Handle_info - stay-alive == false. + ?line ?match({'EXIT', _}, + corba:handle_info(wrong_mod, "info", {?DO_EXIT, state})), + + %% Handle_info - stay-alive == true. + ?line ?match({noreply, {?NO_EXIT, state}}, + corba:handle_info(wrong_mod, "info", {?NO_EXIT, state})), + ok. + +callback_function_api(doc) -> ["Function callbak API tests", ""]; +callback_function_api(suite) -> []; +callback_function_api(_) -> + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', {undef,_}}, + corba:handle_call(?MODULE, bad_function, [], + {?DO_EXIT, state}, [], false, false)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _}, + corba:handle_call(?MODULE, bad_function, [], + {?NO_EXIT, state}, [], false, false)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', {undef,_}}, + corba:handle_cast(?MODULE, bad_function, [], + {?DO_EXIT, state}, [], false)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, state}}, + corba:handle_cast(?MODULE, bad_function, [], + {?NO_EXIT, state}, [], false)), + %% Handle_info - stay-alive == false. Note, we cannot use ?MODULE here. + ?line ?match({'EXIT', _}, + corba:handle_info(corba, "info", {?DO_EXIT, state})), + + %% Handle_info - stay-alive == true. Note, we cannot use ?MODULE here. + ?line ?match({noreply, {?NO_EXIT, state}}, + corba:handle_info(corba, "info", {?NO_EXIT, state})), + ok. + +callback_precond_api(doc) -> ["Precond callbak API tests", ""]; +callback_precond_api(suite) -> []; +callback_precond_api(_) -> + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, state}, [], false, false, {wrong_mod, precond}, + {?MODULE, postcond}, ?MODULE)), + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, state}, [], false, false, {?MODULE, bad_precond}, + {?MODULE, postcond}, ?MODULE)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_}, + corba:handle_call(?MODULE, foo, [], + {?NO_EXIT, state}, [], false, false, {wrong_mod, precond}, + {?MODULE, postcond}, ?MODULE)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_}, + corba:handle_call(?MODULE, foo, [], + {?NO_EXIT, state}, [], false, false, {?MODULE, bad_precond}, + {?MODULE, postcond}, ?MODULE)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, state}, [], false, {wrong_mod, precond}, + {?MODULE, postcond}, ?MODULE)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, state}, [], false, {?MODULE, bad_precond}, + {?MODULE, postcond}, ?MODULE)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, state}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?NO_EXIT, state}, [], false, {wrong_mod, precond}, + {?MODULE, postcond}, ?MODULE)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, state}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?NO_EXIT, state}, [], false, {?MODULE, bad_precond}, + {?MODULE, postcond}, ?MODULE)), + ok. + + +callback_postcond_api(doc) -> ["Postcond callbak API tests", ""]; +callback_postcond_api(suite) -> []; +callback_postcond_api(_) -> + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, state}, [], false, false, {?MODULE, precond}, + {wrong_mod, postcond}, ?MODULE)), + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, state}, [], false, false, {?MODULE, precond}, + {?MODULE, bad_postcond}, ?MODULE)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_}, + corba:handle_call(?MODULE, foo, [], + {?NO_EXIT, state}, [], false, false, {?MODULE, precond}, + {wrong_mod, postcond}, ?MODULE)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_}, + corba:handle_call(?MODULE, foo, [], + {?NO_EXIT, state}, [], false, false, {?MODULE, precond}, + {?MODULE, bad_postcond}, ?MODULE)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, state}, [], false, {?MODULE, precond}, + {wrong_mod, postcond}, ?MODULE)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, state}, [], false, {?MODULE, precond}, + {?MODULE, bad_postcond}, ?MODULE)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, state}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?NO_EXIT, state}, [], false, {?MODULE, precond}, + {wrong_mod, postcond}, ?MODULE)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, state}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?NO_EXIT, state}, [], false, {?MODULE, precond}, + {?MODULE, bad_postcond}, ?MODULE)), + ok. + + +callback_exit_api(doc) -> ["Callbak exit API tests", ""]; +callback_exit_api(suite) -> []; +callback_exit_api(_) -> + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, exit}, [], false, false)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _}, + corba:handle_call(?MODULE, foo, [], + {?NO_EXIT, exit}, [], false, false)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, exit}, [], false)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, exit}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?NO_EXIT, exit}, [], false)), + %% Handle_info - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_info(?MODULE, "info", {?DO_EXIT, exit})), + + %% Handle_info - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, exit}}, + corba:handle_info(?MODULE, "info", {?NO_EXIT, exit})), + ok. + + +callback_badarith_api(doc) -> ["callbak badarith API tests", ""]; +callback_badarith_api(suite) -> []; +callback_badarith_api(_) -> + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, badarith}, [], false, false)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_}, + corba:handle_call(?MODULE, foo, [], + {?NO_EXIT, badarith}, [], false, false)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, badarith}, [], false)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, badarith}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?NO_EXIT, badarith}, [], false)), + %% Handle_info - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_info(?MODULE, "info", {?DO_EXIT, badarith})), + + %% Handle_info - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, badarith}}, + corba:handle_info(?MODULE, "info", {?NO_EXIT, badarith})), + ok. + +callback_case_clause_api(doc) -> ["callbak case_clause API tests", ""]; +callback_case_clause_api(suite) -> []; +callback_case_clause_api(_) -> + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, case_clause}, [], false, false)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _}, + corba:handle_call(?MODULE, foo, [], + {?NO_EXIT, case_clause}, [], false, false)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, case_clause}, [], false)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, case_clause}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?NO_EXIT, case_clause}, [], false)), + %% Handle_info - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_info(?MODULE, "info", {?DO_EXIT, case_clause})), + + %% Handle_info - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, case_clause}}, + corba:handle_info(?MODULE, "info", {?NO_EXIT, case_clause})), + ok. + +callback_function_clause_api(doc) -> ["callbak function_clause API tests", ""]; +callback_function_clause_api(suite) -> []; +callback_function_clause_api(_) -> + %% Handle_call - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_call(?MODULE, foo, [], + {?DO_EXIT, function_clause}, [], false, false)), + %% Handle_call - stay-alive == true + ?line ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _}, + corba:handle_call(?MODULE, foo, [], + {?NO_EXIT, function_clause}, [], false, false)), + %% Handle_cast - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_cast(?MODULE, foo_1w, [], + {?DO_EXIT, function_clause}, [], false)), + %% Handle_cast - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, function_clause}}, + corba:handle_cast(?MODULE, foo_1w, [], + {?NO_EXIT, function_clause}, [], false)), + %% Handle_info - stay-alive == false + ?line ?match({'EXIT', _}, + corba:handle_info(?MODULE, "info", {?DO_EXIT, function_clause})), + %% Handle_info - stay-alive == true + ?line ?match({noreply, {?NO_EXIT, function_clause}}, + corba:handle_info(?MODULE, "info", {?NO_EXIT, function_clause})), + ok. + +%% Faked mandatory operations +init(State) -> + evaluate_state(State), + {ok, State}. +terminate(_Reason, State) -> + evaluate_state(State), + ok. + +code_change(_OldVsn, State, _Extra) -> + evaluate_state(State), + {ok, State}. +handle_call(_,_, State) -> + evaluate_state(State), + {noreply, State}. +handle_cast(_, State) -> + evaluate_state(State), + {noreply, State}. +handle_info(_Info, State) -> + evaluate_state(State), + {noreply, State}. + +foo(State) -> + evaluate_state(State), + {reply, ok, State}. +foo(State, _Arg) -> + evaluate_state(State), + {reply, ok, State}. + +foo_1w(State) -> + evaluate_state(State), + {noreply, State}. +foo_1w(State, _Arg) -> + evaluate_state(State), + {noreply, State}. + +precond(_Module, _Function, _Args) -> + ok. + +postcond(_Module, _Function, _Args, _Result) -> + ok. + +evaluate_state(exit) -> + exit("exit on purpose"); +evaluate_state(badarith) -> + 10 * atom; +evaluate_state(case_clause) -> + case 10 of + false -> + ok + end; +evaluate_state(module) -> + non_existing_module:bar(); +evaluate_state(function) -> + ?MODULE:non_existing_function(); +evaluate_state(arity) -> + ?MODULE:foo(to, many, arguments); +evaluate_state(function_clause) -> + evaluate_state(incorrect_state); +evaluate_state(state) -> + ok. + +%%----------------------------------------------------------------- +%% Local functions. +%%----------------------------------------------------------------- + +pseudo_calls(0, _) -> + ok; +pseudo_calls(Times, Obj) -> + orber_test_server:pseudo_call(Obj), + New = Times - 1, + pseudo_calls(New, Obj). +pseudo_casts(0, _) -> + ok; +pseudo_casts(Times, Obj) -> + orber_test_server:pseudo_cast(Obj), + New = Times - 1, + pseudo_casts(New, Obj). diff --git a/lib/orber/test/csiv2_SUITE.erl b/lib/orber/test/csiv2_SUITE.erl new file mode 100644 index 0000000000..8103fd81ac --- /dev/null +++ b/lib/orber/test/csiv2_SUITE.erl @@ -0,0 +1,940 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2005-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(csiv2_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include_lib("orber/src/ifr_objects.hrl"). +-include("idl_output/orber_test_server.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl"). +%%-include_lib("orber/src/OrberCSIv2.hrl"). + +-define(default_timeout, ?t:minutes(5)). + +-define(match(ExpectedRes,Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(REQUEST_ID, 0). + +-define(REPLY_FRAG_1, <<71,73,79,80,1,2,2,1,0,0,0,41,0,0,0,?REQUEST_ID,0,0,0,0,0,0,0,1,78,69,79,0,0,0,0,2,0,10,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,4,49>>). +%% The fragments are identical for requests and replies. +-define(FRAG_2, <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,?REQUEST_ID,50>>). +-define(FRAG_3, <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,?REQUEST_ID,51>>). +-define(FRAG_4, <<71,73,79,80,1,2,0,7,0,0,0,5,0,0,0,?REQUEST_ID,0>>). + +%% Should X509 DER generated by, for example, OpenSSL +-define(X509DER, + <<42>>). + +%% Should X509 PEM generated by, for example, OpenSSL +-define(X509PEM, + <<42>>). + +%% IOR exported by VB (CSIv2 activated). +-define(VB_IOR, + #'IOP_IOR' + {type_id = "IDL:omg.org/CosNotifyComm/SequencePushConsumer:1.0", + profiles = + [#'IOP_TaggedProfile' + {tag = ?TAG_INTERNET_IOP, + profile_data = + #'IIOP_ProfileBody_1_1'{ + iiop_version = #'IIOP_Version'{major = 1, + minor = 2}, + host = "127.0.0.1", + port = 0, + object_key = [0,86,66,1,0,0,0,24,47,70,77,65,95,67,73,82,80,77,65,78,95,80,79,65,95,83,69,67,85,82,69,0,0,0,0,4,0,0,4,186,0,0,2,10,81,218,65,185], + components = + [#'IOP_TaggedComponent'{tag = ?TAG_SSL_SEC_TRANS, + component_data = #'SSLIOP_SSL'{ + target_supports = 102, + target_requires = 66, + port = 49934}}, + #'IOP_TaggedComponent'{tag = ?TAG_CSI_SEC_MECH_LIST, + component_data = + #'CSIIOP_CompoundSecMechList'{stateful = true, + mechanism_list = + [#'CSIIOP_CompoundSecMech' + {target_requires = 66, + transport_mech = #'IOP_TaggedComponent'{ + tag = ?TAG_TLS_SEC_TRANS, + component_data = + #'CSIIOP_TLS_SEC_TRANS'{ + target_supports = 102, + target_requires = 66, + addresses = + [#'CSIIOP_TransportAddress' + {host_name = "127.0.0.1", + port = 49934}]}}, + as_context_mech = + #'CSIIOP_AS_ContextSec'{ + target_supports = 0, + target_requires = 0, + client_authentication_mech = [], + target_name = []}, + sas_context_mech = + #'CSIIOP_SAS_ContextSec'{ + target_supports = 1024, + target_requires = 0, + privilege_authorities = + [#'CSIIOP_ServiceConfiguration' + {syntax = 1447174401, + name = "Borland"}], + supported_naming_mechanisms = [[6, + 6, + 103, + 129, + 2, + 1, + 1, + 1]], + supported_identity_types = 15}}]}}, + #'IOP_TaggedComponent' + {tag = ?TAG_CODE_SETS, + component_data = + #'CONV_FRAME_CodeSetComponentInfo'{'ForCharData' = + #'CONV_FRAME_CodeSetComponent'{ + native_code_set = 65537, + conversion_code_sets = [83951617]}, + 'ForWcharData' = + #'CONV_FRAME_CodeSetComponent'{ + native_code_set = 65801, + conversion_code_sets = []}}}, + #'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE, + component_data = 1447645952}, + #'IOP_TaggedComponent'{tag = 1447645955, + component_data = [0,5,7,1,127]}]}}]}). + +%% Common basic types +-define(OID, {2,23,130,1,1,1}). + +-define(OCTET_STR, [1,2,3,4]). + +-define(BIT_STR, [0,1,0,1,1]). + +-define(BOOLEAN, false). + +-define(ANY, [19,5,111,116,112,67,65]). + +-ifdef(false). +%% PKIX1Explicit88 +-define(AlgorithmIdentifier, + #'AlgorithmIdentifier'{algorithm = ?OID, + parameters = ?ANY}). + +-define(Validity, #'Validity'{notBefore = {utcTime, "19820102070533.8"}, + notAfter = {generalTime, "19820102070533.8"}}). + +-define(SubjectPublicKeyInfo, + #'SubjectPublicKeyInfo'{algorithm = ?AlgorithmIdentifier, + subjectPublicKey = ?BIT_STR}). + +-define(AttributeTypeAndValue, + #'AttributeTypeAndValue'{type = ?OID, + value = <<19,11,69,114,105,99,115,115,111,110,32,65,66>>}). + +-define(RelativeDistinguishedName, [?AttributeTypeAndValue]). + +-define(RDNSequence, [?RelativeDistinguishedName]). + +-define(Name, {rdnSequence, ?RDNSequence}). + +-define(Version, v3). + +-define(CertificateSerialNumber, 1). + +-define(UniqueIdentifier, ?BIT_STR). + +-define(Extension, #'Extension'{extnID = ?OID, + critical = ?BOOLEAN, + extnValue = ?OCTET_STR}). + +-define(Extensions, [?Extension]). + +-define(TBSCertificate, + #'TBSCertificate'{version = ?Version, + serialNumber = ?CertificateSerialNumber, + signature = ?AlgorithmIdentifier, + issuer = ?Name, + validity = ?Validity, + subject = ?Name, + subjectPublicKeyInfo = ?SubjectPublicKeyInfo, + issuerUniqueID = ?UniqueIdentifier, + subjectUniqueID = ?UniqueIdentifier, + extensions = ?Extensions}). + +-define(Certificate, #'Certificate'{tbsCertificate = ?TBSCertificate, + signatureAlgorithm = ?AlgorithmIdentifier, + signature = ?BIT_STR}). + +%% PKIX1Implicit88 + +-define(GeneralName, {registeredID, ?OID}). + +-define(GeneralNames, [?GeneralName]). + +%% PKIXAttributeCertificate +-define(AttCertValidityPeriod, + #'AttCertValidityPeriod'{notBeforeTime = "19820102070533.8", + notAfterTime = "19820102070533.8"}). + + +-define(Attribute, #'Attribute'{type = ?OID, + values = []}). + +-define(Attributes, [?Attribute]). + +-define(IssuerSerial, #'IssuerSerial'{issuer = ?GeneralNames, + serial = ?CertificateSerialNumber, + issuerUID = ?UniqueIdentifier}). + +-define(DigestedObjectType, publicKey). %% Enum + +-define(ObjectDigestInfo, + #'ObjectDigestInfo'{digestedObjectType = ?DigestedObjectType, + otherObjectTypeID = ?OID, + digestAlgorithm = ?AlgorithmIdentifier, + objectDigest = ?BIT_STR}). + +-define(V2Form, #'V2Form'{issuerName = ?GeneralNames, + baseCertificateID = ?IssuerSerial, + objectDigestInfo = ?ObjectDigestInfo}). + +-define(AttCertVersion, v2). + +-define(Holder, #'Holder'{baseCertificateID = ?IssuerSerial, + entityName = ?GeneralNames, + objectDigestInfo = ?ObjectDigestInfo}). + +-define(AttCertIssuer, {v2Form, ?V2Form}). + +-define(AttributeCertificateInfo, + #'AttributeCertificateInfo'{version = ?AttCertVersion, + holder = ?Holder, + issuer = ?AttCertIssuer, + signature = ?AlgorithmIdentifier, + serialNumber = ?CertificateSerialNumber, + attrCertValidityPeriod = ?AttCertValidityPeriod, + attributes = ?Attributes, + issuerUniqueID = ?UniqueIdentifier, + extensions = ?Extensions}). + +-define(AttributeCertificate, + #'AttributeCertificate'{acinfo = ?AttributeCertificateInfo, + signatureAlgorithm = ?AlgorithmIdentifier, + signatureValue = ?BIT_STR}). + + +%% OrberCSIv2 +-define(AttributeCertChain, + #'AttributeCertChain'{attributeCert = ?AttributeCertificate, + certificateChain = ?CertificateChain}). + +-define(CertificateChain, [?Certificate]). + +-define(VerifyingCertChain, [?Certificate]). + +-endif. + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, + init_per_testcase/2, fin_per_testcase/2, +% code_CertificateChain_api/1, +% code_AttributeCertChain_api/1, +% code_VerifyingCertChain_api/1, +% code_AttributeCertificate_api/1, +% code_Certificate_api/1, +% code_TBSCertificate_api/1, +% code_CertificateSerialNumber_api/1, +% code_Version_api/1, +% code_AlgorithmIdentifier_api/1, +% code_Name_api/1, +% code_RDNSequence_api/1, +% code_RelativeDistinguishedName_api/1, +% code_AttributeTypeAndValue_api/1, +% code_Attribute_api/1, +% code_Validity_api/1, +% code_SubjectPublicKeyInfo_api/1, +% code_UniqueIdentifier_api/1, +% code_Extensions_api/1, +% code_Extension_api/1, +% code_AttributeCertificateInfo_api/1, +% code_AttCertVersion_api/1, +% code_Holder_api/1, +% code_AttCertIssuer_api/1, +% code_AttCertValidityPeriod_api/1, +% code_V2Form_api/1, +% code_IssuerSerial_api/1, +% code_ObjectDigestInfo_api/1, +% code_OpenSSL509_api/1, + ssl_server_peercert_api/1, + ssl_client_peercert_api/1]). + + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([fake_server_ORB/5]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for multi orber interfaces using CSIv2"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +%% NOTE - the fragment test cases must bu first since we explicitly set a request +%% id. Otherwise, the request-id counter would be increased and we cannot know +%% what it is. +cases() -> + [ +% code_CertificateChain_api, +% code_AttributeCertChain_api, +% code_VerifyingCertChain_api, +% code_AttributeCertificate_api, +% code_Certificate_api, +% code_TBSCertificate_api, +% code_CertificateSerialNumber_api, +% code_Version_api, +% code_AlgorithmIdentifier_api, +% code_Name_api, +% code_RDNSequence_api, +% code_RelativeDistinguishedName_api, +% code_AttributeTypeAndValue_api, +% code_Attribute_api, +% code_Validity_api, +% code_SubjectPublicKeyInfo_api, +% code_UniqueIdentifier_api, +% code_Extensions_api, +% code_Extension_api, +% code_AttributeCertificateInfo_api, +% code_AttCertVersion_api, +% code_Holder_api, +% code_AttCertIssuer_api, +% code_AttCertValidityPeriod_api, +% code_V2Form_api, +% code_IssuerSerial_api, +% code_ObjectDigestInfo_api, +% code_OpenSSL509_api, + ssl_server_peercert_api, + ssl_client_peercert_api]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + Dog=test_server:timetrap(?default_timeout), + orber:jump_start(0), + oe_orber_test_server:oe_register(), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + oe_orber_test_server:oe_unregister(), + orber:jump_stop(), + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + Config. + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, no security +%%----------------------------------------------------------------- + + +%%----------------------------------------------------------------- +%% Encode and decode ASN.1 X509 +%%----------------------------------------------------------------- + +-ifdef(false). +%% OrberCSIv2 +code_CertificateChain_api(doc) -> ["Code CertificateChain"]; +code_CertificateChain_api(suite) -> []; +code_CertificateChain_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('CertificateChain', ?CertificateChain)), + ?match({ok, [#'Certificate'{}]}, + 'OrberCSIv2':decode('CertificateChain', list_to_binary(Enc))), + ok. + +code_AttributeCertChain_api(doc) -> ["Code AttributeCertChain"]; +code_AttributeCertChain_api(suite) -> []; +code_AttributeCertChain_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('AttributeCertChain', ?AttributeCertChain)), + ?match({ok, #'AttributeCertChain'{}}, + 'OrberCSIv2':decode('AttributeCertChain', list_to_binary(Enc))), + ok. + +code_VerifyingCertChain_api(doc) -> ["Code VerifyingCertChain"]; +code_VerifyingCertChain_api(suite) -> []; +code_VerifyingCertChain_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('VerifyingCertChain', ?VerifyingCertChain)), + ?match({ok, [#'Certificate'{}]}, + 'OrberCSIv2':decode('VerifyingCertChain', list_to_binary(Enc))), + ok. + +%% PKIXAttributeCertificate +code_AttributeCertificate_api(doc) -> ["Code AttributeCertificate"]; +code_AttributeCertificate_api(suite) -> []; +code_AttributeCertificate_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('AttributeCertificate', ?AttributeCertificate)), + ?match({ok, #'AttributeCertificate'{}}, + 'OrberCSIv2':decode('AttributeCertificate', list_to_binary(Enc))), + ok. + +code_AttributeCertificateInfo_api(doc) -> ["Code AttributeCertificateInfo"]; +code_AttributeCertificateInfo_api(suite) -> []; +code_AttributeCertificateInfo_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('AttributeCertificateInfo', ?AttributeCertificateInfo)), + ?match({ok, #'AttributeCertificateInfo'{}}, + 'OrberCSIv2':decode('AttributeCertificateInfo', list_to_binary(Enc))), + ok. + +code_AttCertVersion_api(doc) -> ["Code AttCertVersion"]; +code_AttCertVersion_api(suite) -> []; +code_AttCertVersion_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('AttCertVersion', ?AttCertVersion)), + ?match({ok, ?AttCertVersion}, + 'OrberCSIv2':decode('AttCertVersion', list_to_binary(Enc))), + ok. + +code_Holder_api(doc) -> ["Code Holder"]; +code_Holder_api(suite) -> []; +code_Holder_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('Holder', ?Holder)), + ?match({ok, #'Holder'{}}, + 'OrberCSIv2':decode('Holder', list_to_binary(Enc))), + ok. + +code_AttCertIssuer_api(doc) -> ["Code AttCertIssuer"]; +code_AttCertIssuer_api(suite) -> []; +code_AttCertIssuer_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('AttCertIssuer', ?AttCertIssuer)), + ?match({ok, {v2Form, _}}, + 'OrberCSIv2':decode('AttCertIssuer', list_to_binary(Enc))), + ok. + +code_AttCertValidityPeriod_api(doc) -> ["Code AttCertValidityPeriod"]; +code_AttCertValidityPeriod_api(suite) -> []; +code_AttCertValidityPeriod_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('AttCertValidityPeriod', ?AttCertValidityPeriod)), + ?match({ok, #'AttCertValidityPeriod'{}}, + 'OrberCSIv2':decode('AttCertValidityPeriod', list_to_binary(Enc))), + ok. + +code_V2Form_api(doc) -> ["Code V2Form"]; +code_V2Form_api(suite) -> []; +code_V2Form_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('V2Form', ?V2Form)), + ?match({ok, #'V2Form'{}}, + 'OrberCSIv2':decode('V2Form', list_to_binary(Enc))), + ok. + +code_IssuerSerial_api(doc) -> ["Code IssuerSerial"]; +code_IssuerSerial_api(suite) -> []; +code_IssuerSerial_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('IssuerSerial', ?IssuerSerial)), + ?match({ok, #'IssuerSerial'{}}, + 'OrberCSIv2':decode('IssuerSerial', list_to_binary(Enc))), + ok. + +code_ObjectDigestInfo_api(doc) -> ["Code ObjectDigestInfo"]; +code_ObjectDigestInfo_api(suite) -> []; +code_ObjectDigestInfo_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('ObjectDigestInfo', ?ObjectDigestInfo)), + ?match({ok, #'ObjectDigestInfo'{}}, + 'OrberCSIv2':decode('ObjectDigestInfo', list_to_binary(Enc))), + ok. + +%% PKIX1Explicit88 +code_Certificate_api(doc) -> ["Code Certificate"]; +code_Certificate_api(suite) -> []; +code_Certificate_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('Certificate', ?Certificate)), + ?match({ok, #'Certificate'{}}, + 'OrberCSIv2':decode('Certificate', list_to_binary(Enc))), + ok. + +code_TBSCertificate_api(doc) -> ["Code TBSCertificate"]; +code_TBSCertificate_api(suite) -> []; +code_TBSCertificate_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('TBSCertificate', ?TBSCertificate)), + ?match({ok, #'TBSCertificate'{}}, + 'OrberCSIv2':decode('TBSCertificate', list_to_binary(Enc))), + ok. + +code_CertificateSerialNumber_api(doc) -> ["Code CertificateSerialNumber"]; +code_CertificateSerialNumber_api(suite) -> []; +code_CertificateSerialNumber_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, + 'OrberCSIv2':encode('CertificateSerialNumber', ?CertificateSerialNumber)), + ?match({ok, ?CertificateSerialNumber}, + 'OrberCSIv2':decode('CertificateSerialNumber', list_to_binary(Enc))), + ok. + +code_Version_api(doc) -> ["Code Version"]; +code_Version_api(suite) -> []; +code_Version_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('Version', ?Version)), + ?match({ok, ?Version}, 'OrberCSIv2':decode('Version', list_to_binary(Enc))), + ok. + +code_AlgorithmIdentifier_api(doc) -> ["Code AlgorithmIdentifier"]; +code_AlgorithmIdentifier_api(suite) -> []; +code_AlgorithmIdentifier_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('AlgorithmIdentifier', ?AlgorithmIdentifier)), + ?match({ok, #'AlgorithmIdentifier'{}}, + 'OrberCSIv2':decode('AlgorithmIdentifier', list_to_binary(Enc))), + ok. + +code_Name_api(doc) -> ["Code Name"]; +code_Name_api(suite) -> []; +code_Name_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('Name', ?Name)), + ?match({ok, {rdnSequence,_}}, + 'OrberCSIv2':decode('Name', list_to_binary(Enc))), + ok. + +code_RDNSequence_api(doc) -> ["Code RDNSequence"]; +code_RDNSequence_api(suite) -> []; +code_RDNSequence_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('RDNSequence', ?RDNSequence)), + ?match({ok, [[#'AttributeTypeAndValue'{}]]}, + 'OrberCSIv2':decode('RDNSequence', list_to_binary(Enc))), + ok. + +code_RelativeDistinguishedName_api(doc) -> ["Code RelativeDistinguishedName"]; +code_RelativeDistinguishedName_api(suite) -> []; +code_RelativeDistinguishedName_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('RelativeDistinguishedName', ?RelativeDistinguishedName)), + ?match({ok, [#'AttributeTypeAndValue'{}]}, + 'OrberCSIv2':decode('RelativeDistinguishedName', list_to_binary(Enc))), + ok. + +code_AttributeTypeAndValue_api(doc) -> ["Code AttributeTypeAndValue"]; +code_AttributeTypeAndValue_api(suite) -> []; +code_AttributeTypeAndValue_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('AttributeTypeAndValue', ?AttributeTypeAndValue)), + ?match({ok, #'AttributeTypeAndValue'{}}, + 'OrberCSIv2':decode('AttributeTypeAndValue', list_to_binary(Enc))), + ok. + +code_Attribute_api(doc) -> ["Code Attribute"]; +code_Attribute_api(suite) -> []; +code_Attribute_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('Attribute', ?Attribute)), + ?match({ok, #'Attribute'{}}, + 'OrberCSIv2':decode('Attribute', list_to_binary(Enc))), + ok. + +code_Validity_api(doc) -> ["Code Validity"]; +code_Validity_api(suite) -> []; +code_Validity_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('Validity', ?Validity)), + ?match({ok, #'Validity'{}}, + 'OrberCSIv2':decode('Validity', list_to_binary(Enc))), + ok. + +code_SubjectPublicKeyInfo_api(doc) -> ["Code SubjectPublicKeyInfo"]; +code_SubjectPublicKeyInfo_api(suite) -> []; +code_SubjectPublicKeyInfo_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('SubjectPublicKeyInfo', ?SubjectPublicKeyInfo)), + ?match({ok, #'SubjectPublicKeyInfo'{}}, + 'OrberCSIv2':decode('SubjectPublicKeyInfo', list_to_binary(Enc))), + ok. + +code_UniqueIdentifier_api(doc) -> ["Code UniqueIdentifier"]; +code_UniqueIdentifier_api(suite) -> []; +code_UniqueIdentifier_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('UniqueIdentifier', ?UniqueIdentifier)), + ?match({ok, _}, 'OrberCSIv2':decode('UniqueIdentifier', list_to_binary(Enc))), + ok. + +code_Extensions_api(doc) -> ["Code Extensions"]; +code_Extensions_api(suite) -> []; +code_Extensions_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('Extensions', ?Extensions)), + ?match({ok, [#'Extension'{}]}, + 'OrberCSIv2':decode('Extensions', list_to_binary(Enc))), + ok. + +code_Extension_api(doc) -> ["Code Extension"]; +code_Extension_api(suite) -> []; +code_Extension_api(_Config) -> + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('Extension', ?Extension)), + ?match({ok, #'Extension'{}}, + 'OrberCSIv2':decode('Extension', list_to_binary(Enc))), + ok. + +%% OpenSSL generated x509 Certificate +code_OpenSSL509_api(doc) -> ["Code OpenSSL generated x509 Certificate"]; +code_OpenSSL509_api(suite) -> []; +code_OpenSSL509_api(_Config) -> + {ok, Cert} = + ?match({ok, #'Certificate'{}}, + 'OrberCSIv2':decode('Certificate', ?X509DER)), + AttrCertChain = #'AttributeCertChain'{attributeCert = ?AttributeCertificate, + certificateChain = [Cert]}, + {ok, EAttrCertChain} = + ?match({ok, _}, 'OrberCSIv2':encode('AttributeCertChain', AttrCertChain)), + ?match({ok, #'AttributeCertChain'{}}, + 'OrberCSIv2':decode('AttributeCertChain', list_to_binary(EAttrCertChain))), + ok. + +-endif. + +%%----------------------------------------------------------------- +%% Test ssl:peercert +%%----------------------------------------------------------------- +ssl_server_peercert_api(doc) -> ["Test ssl:peercert (server side)"]; +ssl_server_peercert_api(suite) -> []; +ssl_server_peercert_api(_Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + Options = orber_test_lib:get_options(iiop_ssl, server, + 2, [{iiop_ssl_port, 0}]), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node(Options)), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), + SSLOptions = orber_test_lib:get_options(ssl, client), + {ok, Socket} = + ?match({ok, _}, fake_client_ORB(ssl, ServerHost, ServerPort, SSLOptions)), + {ok, _PeerCert} = ?match({ok, _}, orber_socket:peercert(ssl, Socket)), + ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])), + ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])), +% ?match({ok, #'Certificate'{}}, +% 'OrberCSIv2':decode('Certificate', PeerCert)), + destroy_fake_ORB(ssl, Socket), + ok + end. + +ssl_client_peercert_api(doc) -> ["Test ssl:peercert (client side)"]; +ssl_client_peercert_api(suite) -> []; +ssl_client_peercert_api(_Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + Options = orber_test_lib:get_options(iiop_ssl, client, + 2, [{iiop_ssl_port, 0}]), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node(Options)), + crypto:start(), + ssl:start(), + ssl:seed("testing"), + SSLOptions = orber_test_lib:get_options(ssl, server), + {ok, LSock} = ?match({ok, _}, ssl:listen(0, SSLOptions)), + {ok, {_Address, LPort}} = ?match({ok, {_, _}}, ssl:sockname(LSock)), + IOR = ?match({'IOP_IOR',_,_}, + iop_ior:create_external({1, 2}, "IDL:FAKE:1.0", + "localhost", 6004, "FAKE", + [#'IOP_TaggedComponent' + {tag=?TAG_SSL_SEC_TRANS, + component_data=#'SSLIOP_SSL' + {target_supports = 2, + target_requires = 2, + port = LPort}}])), + spawn(orber_test_lib, remote_apply, + [ClientNode, corba_object, non_existent, [IOR]]), + {ok, Socket} = ?match({ok, _}, ssl:transport_accept(LSock)), + ?match(ok, ssl:ssl_accept(Socket)), + + {ok, _PeerCert} = ?match({ok, _}, orber_socket:peercert(ssl, Socket)), + ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])), + ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])), +% ?match({ok, #'Certificate'{}}, +% 'OrberCSIv2':decode('Certificate', PeerCert)), + ssl:close(Socket), + ssl:close(LSock), + ssl:stop(), + ok + end. + +%%----------------------------------------------------------------- +%% Local functions. +%%----------------------------------------------------------------- +-ifdef(false). +%% Not used yet. +context_test(Obj) -> + IDToken1 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAbsent, + value = true}, + IDToken2 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAnonymous, + value = false}, + IDToken3 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTPrincipalName, + value = [0,255]}, + IDToken4 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTX509CertChain, + value = [1,255]}, + IDToken5 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTDistinguishedName, + value = [2,255]}, + IDToken6 = #'CSI_IdentityToken'{label = ?ULONGMAX, + value = [3,255]}, + + MTEstablishContext1 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken1, + client_authentication_token = [1, 255]}}, + MTEstablishContext2 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken2, + client_authentication_token = [1, 255]}}, + MTEstablishContext3 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken3, + client_authentication_token = [1, 255]}}, + MTEstablishContext4 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken4, + client_authentication_token = [1, 255]}}, + MTEstablishContext5 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken5, + client_authentication_token = [1, 255]}}, + MTEstablishContext6 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken6, + client_authentication_token = [1, 255]}}, + MTCompleteEstablishContext = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTCompleteEstablishContext, + value = #'CSI_CompleteEstablishContext'{client_context_id = ?ULONGLONGMAX, + context_stateful = false, + final_context_token = [1, 255]}}, + MTContextError = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTContextError, + value = #'CSI_ContextError'{client_context_id = ?ULONGLONGMAX, + major_status = 1, + minor_status = 2, + error_token = [2,255]}}, + MTMessageInContext = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTMessageInContext, + value = #'CSI_MessageInContext'{client_context_id = ?ULONGLONGMAX, + discard_context = true}}, + Ctx = [#'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext1}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext2}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext3}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext4}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext5}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext6}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTCompleteEstablishContext}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTContextError}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTMessageInContext}], + ?line ?match(ok, orber_test_server:testing_iiop_context(Obj, [{context, Ctx}])). + + +fake_server_ORB(Type, Port, Options) -> + start_ssl(Type), + {ok, ListenSocket, NewPort} = + orber_socket:listen(Type, Port, + [{active, false}|Options]), + Socket = orber_socket:accept(Type, ListenSocket), + orber_socket:post_accept(Type, Socket), + {ok, Socket, NewPort}. + +-endif. + +fake_server_ORB(Type, Port, Options, Action, Data) -> + start_ssl(Type), + {ok, ListenSocket, _NewPort} = + orber_socket:listen(Type, Port, [{active, false}|Options]), + Socket = orber_socket:accept(Type, ListenSocket), + orber_socket:post_accept(Type, Socket), + do_server_action(Type, Socket, Action, Data), + orber_socket:close(Type, Socket), + ok. + +start_ssl(ssl) -> + crypto:start(), + ssl:start(), + ssl:seed("testing"); +start_ssl(_) -> + ok. + + +destroy_fake_ORB(ssl, Socket) -> + orber_socket:close(ssl, Socket), + ssl:stop(); +destroy_fake_ORB(Type, Socket) -> + orber_socket:close(Type, Socket). + +fake_client_ORB(Type, Host, Port, Options) -> + start_ssl(Type), + Socket = orber_socket:connect(Type, Host, Port, [{active, false}|Options]), + {ok, Socket}. + +-ifdef(false). +%% Not used yet. + +fake_client_ORB(Type, Host, Port, Options, Action, Data) -> + start_ssl(Type), + Socket = orber_socket:connect(Type, Host, Port, [{active, false}|Options]), + Result = do_client_action(Type, Socket, Action, Data), + orber_socket:close(Type, Socket), + Result. + +do_client_action(Type, Socket, fragments, FragList) -> + ok = send_data(Type, Socket, FragList), + {ok, Bytes} = gen_tcp:recv(Socket, 0), + {#reply_header{request_id = ?REQUEST_ID, reply_status = no_exception}, ok, [Par]} = + cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes), + Par; +do_client_action(Type, Socket, fragments_max, FragList) -> + ok = send_data(Type, Socket, FragList), + {ok, Bytes} = gen_tcp:recv(Socket, 0), + {#reply_header{request_id = ?REQUEST_ID, reply_status = system_exception}, Exc, []} = + cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes), + Exc; +do_client_action(Type, Socket, message_error, Data) -> + ok = send_data(Type, Socket, Data), + {ok,Bytes} = gen_tcp:recv(Socket, 0), + 'message_error' = cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes), + ok; +do_client_action(_Type, _Socket, _Action, _Data) -> + ok. + +-endif. + +do_server_action(Type, Socket, fragments, FragList) -> + {ok, _B} = gen_tcp:recv(Socket, 0), + ok = send_data(Type, Socket, FragList); +do_server_action(_Type, _Socket, _Action, _Data) -> + ok. + + +send_data(_Type, _Socket, []) -> + ok; +send_data(Type, Socket, [H|T]) -> + orber_socket:write(Type, Socket, H), + send_data(Type, Socket, T). + diff --git a/lib/orber/test/data_types_SUITE.erl b/lib/orber/test/data_types_SUITE.erl new file mode 100644 index 0000000000..1feb0b3b58 --- /dev/null +++ b/lib/orber/test/data_types_SUITE.erl @@ -0,0 +1,173 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2002-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : data_types_SUITE.erl +%% Purpose : +%%----------------------------------------------------------------- + +-module(data_types_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["This suite is for testing more or less complex data types"]; +all(suite) -> + [fixed_type, any_type]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: name component handling tests +%% Description: +%%----------------------------------------------------------------- +fixed_type(doc) -> ["Test the Fixed Point Datatype."]; +fixed_type(suite) -> []; +fixed_type(_) -> + Val1 = ?match({fixed,3,2,314}, orber_test_server:val1()), + _Val2 = ?match({fixed,3,2,314}, orber_test_server:val2()), + _Val3 = ?match({fixed,3,2,314}, orber_test_server:val3()), + Val4 = ?match({fixed,3,2,314}, orber_test_server:val4()), + Val5 = ?match({fixed,2,2,14}, orber_test_server:val5()), + _Val6 = ?match({fixed,1,0,3}, orber_test_server:val6()), + Val7 = ?match({fixed,2,2,-14}, orber_test_server:val7()), + _Val8 = ?match({fixed,1,0,-3}, orber_test_server:val8()), + Val9 = ?match({fixed,3,2,328}, orber_test_server:val9()), + Val10 = ?match({fixed,4,4,4396}, orber_test_server:val10()), + Val11 = ?match({fixed,31,29,2242857142857142857142857142857}, orber_test_server:val11()), + Val12 = ?match({fixed,9,6,123140001}, orber_test_server:val12()), + Val13 = ?match({fixed,9,1,123140001}, orber_test_server:val13()), + Val14 = ?match({fixed,14,6,-12313876959999}, orber_test_server:val14()), + Val15 = ?match({fixed,14,6,12314123240001}, orber_test_server:val15()), + Val16 = ?match({fixed,17,7,15163459846280001}, orber_test_server:val16()), + _Val17 = ?match({fixed,3,2,402}, orber_test_server:val17()), + _Val18 = ?match({fixed,5,4,40401}, orber_test_server:val18()), + _Val19 = ?match({fixed,3,0,200}, orber_test_server:val19()), + Val20 = ?match({fixed,31,0,1999999999999999999999999999999}, orber_test_server:val20()), + Val21 = ?match({fixed,1,0,0}, orber_test_server:val21()), + Val22 = ?match({fixed,31,0,9999999999999999999999999999998}, orber_test_server:val22()), + Val23 = ?match({fixed,1,0,1}, orber_test_server:val23()), + _Val24 = ?match({fixed,5,0,19998}, orber_test_server:val24()), + _Val25 = ?match({fixed,2,0,40}, orber_test_server:val25()), + Val26 = ?match({fixed,31,0,9999999999999999999999999999999}, orber_test_server:val26()), + + ?match(Val1, fixed:create(3,2,314)), + Val27 = ?match({fixed,6,2,314}, fixed:create(6,2,314)), + + ?match({tk_fixed,3,2}, fixed:get_typecode(Val1)), + ?match({tk_fixed,6,2}, fixed:get_typecode(Val27)), + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, fixed:create(3,2,3140)), + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, fixed:create(5,6,314)), + ?match({'EXCEPTION',{'BAD_PARAM',_,_,_}}, fixed:create(32,2,314)), + ?match(Val10, fixed:multiply(Val4, Val5)), + ?match(Val16, fixed:multiply(Val12, Val13)), + ?match(Val22, fixed:multiply(Val26, Val26)), + + ?match(Val9, fixed:add(Val4, Val5)), + ?match(Val15, fixed:add(Val12, Val13)), + ?match(Val20, fixed:add(Val26, Val26)), + + ?match(Val11, fixed:divide(Val4, Val5)), + ?match(Val23, fixed:divide(Val26, Val26)), + + ?match(Val14, fixed:subtract(Val12, Val13)), + ?match(Val21, fixed:subtract(Val26, Val26)), + + ?match(Val7, fixed:unary_minus(Val5)), + ?match(Val5, fixed:unary_minus(Val7)), + + + + ok. + +%%----------------------------------------------------------------- +%% Test Case: any type +%% Description: +%%----------------------------------------------------------------- +any_type(doc) -> ["Test the Any Datatype."]; +any_type(suite) -> []; +any_type(_) -> + ?match(#any{typecode=undefined, value=undefined}, + any:create()), + ?match(#any{typecode=tk_short, value=undefined}, + any:set_typecode(any:create(), tk_short)), + ?match({'EXCEPTION', #'BAD_TYPECODE'{}}, + any:set_typecode(any:create(), "wrong")), + ?match({'EXCEPTION', #'BAD_TYPECODE'{}}, + any:create("wrong", 1)), + ?match(#any{typecode=tk_short, value = 1}, + any:create(tk_short, 1)), + ?match(tk_short, + any:get_typecode(any:create(tk_short, 1))), + ?match(1, + any:get_value(any:create(tk_short, 1))), + ?match(#any{typecode=tk_short, value=2}, + any:set_value(any:create(tk_short, 1), 2)), + + ok. diff --git a/lib/orber/test/generated_SUITE.erl b/lib/orber/test/generated_SUITE.erl new file mode 100644 index 0000000000..1cd1674fc4 --- /dev/null +++ b/lib/orber/test/generated_SUITE.erl @@ -0,0 +1,385 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : generated_SUITE.erl +%% Purpose : +%%----------------------------------------------------------------- + +-module(generated_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(nomatch(Not, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + Not -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS); + _ -> + AcTuAlReS + end + end()). + + +-define(checktc(_Op), + fun(TC) -> + case orber_tc:check_tc(TC) of + false -> + io:format("###### ERROR ERROR ######~n~p - ~p~n", [Op, TC]), + ?line exit(TC); + true -> + true + end + end). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["This suite is for testing IC generated files"]; +all(suite) -> + ['OrberApp_IFR', + erlang_binary, erlang_pid, erlang_port, erlang_ref, + 'CosNaming_Binding', 'CosNaming_BindingList', 'CosNaming_Name', + 'CosNaming_NameComponent', 'CosNaming_NamingContextExt_InvalidAddress', + 'CosNaming_NamingContext_AlreadyBound', 'CosNaming_NamingContext_CannotProceed', + 'CosNaming_NamingContext_InvalidName', 'CosNaming_NamingContext_NotEmpty', + 'CosNaming_NamingContext_NotFound', 'CosNaming_BindingIterator', + 'CosNaming_NamingContext', 'CosNaming_NamingContextExt']. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case:'OrberApp_IFR' +%% Description: +%%----------------------------------------------------------------- +'OrberApp_IFR'(doc) -> [""]; +'OrberApp_IFR'(suite) -> []; +'OrberApp_IFR'(_) -> + ?nomatch(undefined, 'OrberApp_IFR':oe_tc(get_absolute_name)), + ?nomatch(undefined, 'OrberApp_IFR':oe_tc(get_user_exception_type)), + ?match(undefined, 'OrberApp_IFR':oe_tc(undefined)), + ?match([_|_], 'OrberApp_IFR':oe_get_interface()), + ?match("IDL:OrberApp/IFR:1.0", 'OrberApp_IFR':typeID()), + check_tc('OrberApp_IFR':oe_get_interface()), + ?match(true, 'OrberApp_IFR':oe_is_a('OrberApp_IFR':typeID())), + ?match(false, 'OrberApp_IFR':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: erlang_binary +%% Description: +%%----------------------------------------------------------------- +erlang_binary(doc) -> [""]; +erlang_binary(suite) -> []; +erlang_binary(_) -> + ?match(true, orber_tc:check_tc(erlang_binary:tc())), + ?match("IDL:erlang/binary:1.0", erlang_binary:id()), + ?match("erlang_binary", erlang_binary:name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: erlang_pid +%% Description: +%%----------------------------------------------------------------- +erlang_pid(doc) -> [""]; +erlang_pid(suite) -> []; +erlang_pid(_) -> + ?match(true, orber_tc:check_tc(erlang_pid:tc())), + ?match("IDL:erlang/pid:1.0", erlang_pid:id()), + ?match("erlang_pid", erlang_pid:name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: erlang_port +%% Description: +%%----------------------------------------------------------------- +erlang_port(doc) -> [""]; +erlang_port(suite) -> []; +erlang_port(_) -> + ?match(true, orber_tc:check_tc(erlang_port:tc())), + ?match("IDL:erlang/port:1.0", erlang_port:id()), + ?match("erlang_port", erlang_port:name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: erlang_ref +%% Description: +%%----------------------------------------------------------------- +erlang_ref(doc) -> [""]; +erlang_ref(suite) -> []; +erlang_ref(_) -> + ?match(true, orber_tc:check_tc(erlang_ref:tc())), + ?match("IDL:erlang/ref:1.0", erlang_ref:id()), + ?match("erlang_ref", erlang_ref:name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_Binding' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_Binding'(doc) -> [""]; +'CosNaming_Binding'(suite) -> []; +'CosNaming_Binding'(_) -> + ?match(true, orber_tc:check_tc('CosNaming_Binding':tc())), + ?match("IDL:omg.org/CosNaming/Binding:1.0", 'CosNaming_Binding':id()), + ?match("CosNaming_Binding", 'CosNaming_Binding':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_BindingList' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_BindingList'(doc) -> [""]; +'CosNaming_BindingList'(suite) -> []; +'CosNaming_BindingList'(_) -> + ?match(true, orber_tc:check_tc('CosNaming_BindingList':tc())), + ?match("IDL:omg.org/CosNaming/BindingList:1.0", 'CosNaming_BindingList':id()), + ?match("CosNaming_BindingList", 'CosNaming_BindingList':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_Name' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_Name'(doc) -> [""]; +'CosNaming_Name'(suite) -> []; +'CosNaming_Name'(_) -> + ?match(true, orber_tc:check_tc('CosNaming_Name':tc())), + ?match("IDL:omg.org/CosNaming/Name:1.0", 'CosNaming_Name':id()), + ?match("CosNaming_Name", 'CosNaming_Name':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_NameComponent' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_NameComponent'(doc) -> [""]; +'CosNaming_NameComponent'(suite) -> []; +'CosNaming_NameComponent'(_) -> + ?match(true, orber_tc:check_tc('CosNaming_NameComponent':tc())), + ?match("IDL:omg.org/CosNaming/NameComponent:1.0", 'CosNaming_NameComponent':id()), + ?match("CosNaming_NameComponent", 'CosNaming_NameComponent':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_NamingContextExt_InvalidAddress' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_NamingContextExt_InvalidAddress'(doc) -> [""]; +'CosNaming_NamingContextExt_InvalidAddress'(suite) -> []; +'CosNaming_NamingContextExt_InvalidAddress'(_) -> + ?match(true, orber_tc:check_tc('CosNaming_NamingContextExt_InvalidAddress':tc())), + ?match("IDL:omg.org/CosNaming/NamingContextExt/InvalidAddress:1.0", 'CosNaming_NamingContextExt_InvalidAddress':id()), + ?match("CosNaming_NamingContextExt_InvalidAddress", 'CosNaming_NamingContextExt_InvalidAddress':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_NamingContext_AlreadyBound' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_NamingContext_AlreadyBound'(doc) -> [""]; +'CosNaming_NamingContext_AlreadyBound'(suite) -> []; +'CosNaming_NamingContext_AlreadyBound'(_) -> + ?match(true, orber_tc:check_tc('CosNaming_NamingContext_AlreadyBound':tc())), + ?match("IDL:omg.org/CosNaming/NamingContext/AlreadyBound:1.0", 'CosNaming_NamingContext_AlreadyBound':id()), + ?match("CosNaming_NamingContext_AlreadyBound", 'CosNaming_NamingContext_AlreadyBound':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_NamingContext_CannotProceed' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_NamingContext_CannotProceed'(doc) -> [""]; +'CosNaming_NamingContext_CannotProceed'(suite) -> []; +'CosNaming_NamingContext_CannotProceed'(_) -> + ?match(true, orber_tc:check_tc('CosNaming_NamingContext_CannotProceed':tc())), + ?match("IDL:omg.org/CosNaming/NamingContext/CannotProceed:1.0", 'CosNaming_NamingContext_CannotProceed':id()), + ?match("CosNaming_NamingContext_CannotProceed", 'CosNaming_NamingContext_CannotProceed':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_NamingContext_InvalidName' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_NamingContext_InvalidName'(doc) -> [""]; +'CosNaming_NamingContext_InvalidName'(suite) -> []; +'CosNaming_NamingContext_InvalidName'(_) -> + ?match(true, orber_tc:check_tc('CosNaming_NamingContext_InvalidName':tc())), + ?match("IDL:omg.org/CosNaming/NamingContext/InvalidName:1.0", 'CosNaming_NamingContext_InvalidName':id()), + ?match("CosNaming_NamingContext_InvalidName", 'CosNaming_NamingContext_InvalidName':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_NamingContext_NotEmpty' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_NamingContext_NotEmpty'(doc) -> [""]; +'CosNaming_NamingContext_NotEmpty'(suite) -> []; +'CosNaming_NamingContext_NotEmpty'(_) -> + ?match(true, orber_tc:check_tc('CosNaming_NamingContext_NotEmpty':tc())), + ?match("IDL:omg.org/CosNaming/NamingContext/NotEmpty:1.0", 'CosNaming_NamingContext_NotEmpty':id()), + ?match("CosNaming_NamingContext_NotEmpty", 'CosNaming_NamingContext_NotEmpty':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_NamingContext_NotFound' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_NamingContext_NotFound'(doc) -> [""]; +'CosNaming_NamingContext_NotFound'(suite) -> []; +'CosNaming_NamingContext_NotFound'(_) -> + ?match(true, orber_tc:check_tc('CosNaming_NamingContext_NotFound':tc())), + ?match("IDL:omg.org/CosNaming/NamingContext/NotFound:1.0", 'CosNaming_NamingContext_NotFound':id()), + ?match("CosNaming_NamingContext_NotFound", 'CosNaming_NamingContext_NotFound':name()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_BindingIterator' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_BindingIterator'(doc) -> [""]; +'CosNaming_BindingIterator'(suite) -> []; +'CosNaming_BindingIterator'(_) -> + ?nomatch(undefined, 'CosNaming_BindingIterator':oe_tc(next_one)), + ?nomatch(undefined, 'CosNaming_BindingIterator':oe_tc(next_n)), + ?nomatch(undefined, 'CosNaming_BindingIterator':oe_tc(destroy)), + ?match(undefined, 'CosNaming_BindingIterator':oe_tc(undefined)), + ?match([_|_], 'CosNaming_BindingIterator':oe_get_interface()), + ?match("IDL:omg.org/CosNaming/BindingIterator:1.0", + 'CosNaming_BindingIterator':typeID()), + check_tc('CosNaming_BindingIterator':oe_get_interface()), + ?match(true, 'CosNaming_BindingIterator':oe_is_a('CosNaming_BindingIterator':typeID())), + ?match(false, 'CosNaming_BindingIterator':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_NamingContext' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_NamingContext'(doc) -> [""]; +'CosNaming_NamingContext'(suite) -> []; +'CosNaming_NamingContext'(_) -> + ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(bind)), + ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(rebind)), + ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(bind_context)), + ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(rebind_context)), + ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(resolve)), + ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(unbind)), + ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(new_context)), + ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(bind_new_context)), + ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(destroy)), + ?nomatch(undefined, 'CosNaming_NamingContext':oe_tc(list)), + ?match(undefined, 'CosNaming_NamingContext':oe_tc(undefined)), + ?match([_|_], 'CosNaming_NamingContext':oe_get_interface()), + ?match("IDL:omg.org/CosNaming/NamingContext:1.0", + 'CosNaming_NamingContext':typeID()), + check_tc('CosNaming_NamingContext':oe_get_interface()), + ?match(true, 'CosNaming_NamingContext':oe_is_a('CosNaming_NamingContext':typeID())), + ?match(false, 'CosNaming_NamingContext':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: 'CosNaming_NamingContexExt' +%% Description: +%%----------------------------------------------------------------- +'CosNaming_NamingContextExt'(doc) -> [""]; +'CosNaming_NamingContextExt'(suite) -> []; +'CosNaming_NamingContextExt'(_) -> + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(to_string)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(to_name)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(to_url)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(resolve_str)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(bind)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(rebind)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(bind_context)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(rebind_context)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(new_context)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(bind_new_context)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(destroy)), + ?nomatch(undefined, 'CosNaming_NamingContextExt':oe_tc(list)), + ?match(undefined, 'CosNaming_NamingContextExt':oe_tc(undefined)), + ?match([_|_], 'CosNaming_NamingContextExt':oe_get_interface()), + ?match("IDL:omg.org/CosNaming/NamingContextExt:1.0", + 'CosNaming_NamingContextExt':typeID()), + check_tc('CosNaming_NamingContextExt':oe_get_interface()), + ?match(true, 'CosNaming_NamingContextExt':oe_is_a('CosNaming_NamingContextExt':typeID())), + ?match(true, 'CosNaming_NamingContextExt':oe_is_a('CosNaming_NamingContext':typeID())), + ?match(false, 'CosNaming_NamingContextExt':oe_is_a("wrong")), + ok. + + +%%----------------------------------------------------------------- +%% MISC functions +%%----------------------------------------------------------------- +check_tc([]) -> + ok; +check_tc([{Op, {RetType, InParameters, OutParameters}}|T]) -> + io:format("checked - ~s~n", [Op]), + lists:all(?checktc(Op), [RetType|InParameters]), + lists:all(?checktc(Op), OutParameters), + check_tc(T). + + diff --git a/lib/orber/test/idl_output/.gitignore b/lib/orber/test/idl_output/.gitignore new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/orber/test/idl_output/.gitignore diff --git a/lib/orber/test/iiop_module_do_test_impl.erl b/lib/orber/test/iiop_module_do_test_impl.erl new file mode 100644 index 0000000000..bf171a3097 --- /dev/null +++ b/lib/orber/test/iiop_module_do_test_impl.erl @@ -0,0 +1,112 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(iiop_module_do_test_impl). + + +-export([run_all/3, run_userexception/2, run_systemexception/2]). +-export([createTestContext/0]). + +-export([start/0, stop/0]). +-export([init/1, terminate/2]). + + +init(_) -> + {ok, []}. + +terminate(Reason, _State) -> + io:format("~p terminating with reason ~p~n", [?MODULE, Reason]), + ok. + +createTestContext() -> + NS = corba:resolve_initial_references("NameService"), + NC = lname_component:set_id(lname_component:create(), "iiop_test"), + N = lname:insert_component(lname:create(), 1, NC), + 'CosNaming_NamingContext':bind_new_context(NS, N). + +start() -> + SFok = corba:create('iiop_module_do_test', "IDL:iiop_module/do_test:1.0"), + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "iiop_test"), + NC2 = lname_component:set_id(lname_component:create(), "erl_dotest"), + N = lname:insert_component(lname:create(), 1, NC1), + N1 = lname:insert_component(N, 2, NC2), + 'CosNaming_NamingContext':bind(NS, N1, SFok), + SFok. + +stop() -> + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "iiop_test"), + NC2 = lname_component:set_id(lname_component:create(), "erl_dotest"), + N = lname:insert_component(lname:create(), 1, NC1), + N1 = lname:insert_component(N, 2, NC2), + 'CosNaming_NamingContext':unbind(NS, N1). + +run_all(S, X, TL) -> + ok = iiop_module_test:send_void(X), + {tk_short, P1} = lists:nth(1, TL), + {R1, IO1, O1} = iiop_module_test:send_short(X, P1, P1), + RL1= [{tk_short, R1}], + IOL1= [{tk_short, IO1}], + OL1= [{tk_short, O1}], + {tk_ushort, P2} = lists:nth(2, TL), + {R2, IO2, O2} = iiop_module_test:send_ushort(X, P2, P2), + RL2= [{tk_ushort, R2}|RL1], + IOL2= [{tk_ushort, IO2}|IOL1], + OL2= [{tk_ushort, O2}|OL1], + {tk_long, P3} = lists:nth(3, TL), + {R3, IO3, O3} = iiop_module_test:send_long(X, P3, P3), + RL3= [{tk_long, R3}|RL2], + IOL3= [{tk_long, IO3}|IOL2], + OL3= [{tk_long, O3}|OL2], + {tk_ulong, P4} = lists:nth(4, TL), + {R4, IO4, O4} = iiop_module_test:send_ulong(X, P4, P4), + RL4= [{tk_ulong, R4}|RL3], + IOL4= [{tk_ulong, IO4}|IOL3], + OL4= [{tk_ulong, O4}|OL3], + {tk_float, P5} = lists:nth(5, TL), + {R5, IO5, O5} = iiop_module_test:send_float(X, P5, P5), + RL5= [{tk_float, R5}|RL4], + IOL5= [{tk_float, IO5}|IOL4], + OL5= [{tk_float, O5}|OL4], + {tk_double, P6} = lists:nth(6, TL), + {R6, IO6, O6} = iiop_module_test:send_double(X, P6, P6), + RL6= [{tk_double, R6}|RL5], + IOL6= [{tk_double, IO6}|IOL5], + OL6= [{tk_double, O6}|OL5], + {tk_boolean, P7} = lists:nth(7, TL), + {R7, IO7, O7} = iiop_module_test:send_boolean(X, P7, P7), + RL7= [{tk_boolean, R7}|RL6], + IOL7= [{tk_boolean, IO7}|IOL6], + OL7= [{tk_boolean, O7}|OL6], + {tk_char, P8} = lists:nth(8, TL), + {R8, IO8, O8} = iiop_module_test:send_char(X, P8, P8), + RL= [{tk_char, R8} |RL7], + IOL= [{tk_char, IO8} |IOL7], + OL= [{tk_char, O8} |OL7], + {{lists:reverse(RL),lists:reverse(IOL),lists:reverse(OL)}, S}. + +run_systemexception(S, X) -> + iiop_module_test:ret_systemexception(X), + {ok, S}. + +run_userexception(S, X) -> + iiop_module_test:ret_userexception(X), + {ok, S}. diff --git a/lib/orber/test/iiop_module_test_impl.erl b/lib/orber/test/iiop_module_test_impl.erl new file mode 100644 index 0000000000..fe334e1b26 --- /dev/null +++ b/lib/orber/test/iiop_module_test_impl.erl @@ -0,0 +1,128 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(iiop_module_test_impl). +-include_lib("orber/include/corba.hrl"). +-include("idl_output/iiop_module.hrl"). + + +-export([send_void/1, send_short/3, send_ushort/3]). +-export([send_long/3, send_ulong/3, send_float/3]). +-export([send_double/3, send_boolean/3, send_char/3]). +-export([send_octet/3, send_any/3, send_object/3]). +-export([send_struct1/3, send_union1/3, send_enum1/3]). +-export([send_string/3, send_sequence1/3, send_array1/3]). +-export([ret_systemexception/1, ret_userexception/1]). + + + +-export([start/0, stop/0]). +-export([init/1, terminate/2]). + + +init(_) -> + {ok, []}. + +terminate(Reason, _State) -> + io:format("~p terminating with reason ~p~n", [?MODULE, Reason]), + ok. + + +start() -> + SFok = corba:create('iiop_module_test', "IDL:iiop_module/test:1.0"), + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "iiop_test"), + NC2 = lname_component:set_id(lname_component:create(), "erl_test"), + N = lname:insert_component(lname:create(), 1, NC1), + N1 = lname:insert_component(N, 2, NC2), + 'CosNaming_NamingContext':bind(NS, N1, SFok), + SFok. + +stop() -> + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "iiop_test"), + NC2 = lname_component:set_id(lname_component:create(), "erl_test"), + N = lname:insert_component(lname:create(), 1, NC1), + N1 = lname:insert_component(N, 2, NC2), + 'CosNaming_NamingContext':unbind(NS, N1). + + + +send_void(S) -> + {ok, S}. + +send_short(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_ushort(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_long(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_ulong(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_float(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_double(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_boolean(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_char(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_octet(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_any(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_object(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_struct1(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_union1(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_enum1(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_string(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_sequence1(S, P1, P2) -> + {{P1, P1, P2}, S}. + +send_array1(S, P1, P2) -> + {{P1, P1, P2}, S}. + +ret_systemexception(S) -> + throw(#'BAD_PARAM'{}), + {ok, S}. + +ret_userexception(S) -> + throw(#iiop_module_Except1{why="not readable",rest_of_name=["foo", "bar"]}), + {ok, S}. diff --git a/lib/orber/test/iiop_test.idl b/lib/orber/test/iiop_test.idl new file mode 100644 index 0000000000..339678106e --- /dev/null +++ b/lib/orber/test/iiop_test.idl @@ -0,0 +1,111 @@ +// +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// +#include "cos_naming.idl" + +module iiop_module +{ + + typedef long Array1[10]; + + enum Enum1 {horse, pig, cow}; + + typedef sequence<long> Sequence1; + + typedef Sequence1 Sequence2; + + struct Struct1 { + string s; + unsigned short us; + unsigned long ul; + }; + + union Union1 switch (short) { + case 0: short First; + case 1: string Second; + case 2: char Third; + }; + + exception Except1 { + string why; + sequence <string> rest_of_name; + }; + + typedef sequence<any> test_values; + struct test_retval { + test_values R; + test_values InOut; + test_values Out; + }; + + interface test; + + interface do_test { + void run_systemexception(in test x) + raises(CosNaming::NamingContext::NotFound, + CosNaming::NamingContext::CannotProceed, + CosNaming::NamingContext::InvalidName); + void run_userexception(in test x) + raises(iiop_module::Except1, + CosNaming::NamingContext::NotFound, + CosNaming::NamingContext::CannotProceed, + CosNaming::NamingContext::InvalidName); + test_retval run_all(in test x, in test_values tlist) + raises(iiop_module::Except1, + CosNaming::NamingContext::NotFound, + CosNaming::NamingContext::CannotProceed, + CosNaming::NamingContext::InvalidName); + }; + + interface test { + // Function to run all tests from java to erlang + // and return the answers + // Primitive types + void send_void(); + short send_short(in short p1, inout short p2, out short p3); + unsigned short send_ushort(in unsigned short p1, inout unsigned short p2, + out unsigned short p3); + long send_long(in long p1, inout long p2, out long p3); + unsigned long send_ulong(in unsigned long p1, inout unsigned long p2, + out unsigned long p3); + float send_float(in float p1, inout float p2, out float p3); + double send_double(in double p1, inout double p2, out double p3); + boolean send_boolean(in boolean p1, inout boolean p2, out boolean p3); + char send_char(in char p1, inout char p2, out char p3); + octet send_octet(in octet p1, inout octet p2, out octet p3); + any send_any(in any p1, inout any p2, out any p3); + Object send_object(in Object p1, inout Object p2, out Object p3); + // TypeCode send_typecode(in TypeCode p1, inout TypeCode p2, out TypeCode p3); + // Principal send_principal(in Principal p); //tested in every request + + // Complex types + Struct1 send_struct1(in Struct1 p1, inout Struct1 p2, out Struct1 p3); + Union1 send_union1(in Union1 p1, inout Union1 p2, out Union1 p3); + Enum1 send_enum1(in Enum1 p1, inout Enum1 p2, out Enum1 p3); + string send_string(in string p1, inout string p2, out string p3); + Sequence1 send_sequence1(in Sequence1 p1, inout Sequence1 p2, + out Sequence1 p3); + Array1 send_array1(in Array1 p1, inout Array1 p2, out Array1 p3); + + void ret_systemexception(); + void ret_userexception() raises(iiop_module::Except1); + + + }; + +}; diff --git a/lib/orber/test/iiop_test_impl.erl b/lib/orber/test/iiop_test_impl.erl new file mode 100644 index 0000000000..fd92109c09 --- /dev/null +++ b/lib/orber/test/iiop_test_impl.erl @@ -0,0 +1,34 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(iiop_test_impl). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/test/iiop_test.hrl"). +-export([]). + + +init(Env) -> + {ok, []}. + +terminate(From, Reason) -> + ok. + +send_void(State) -> + {ok, State}. + diff --git a/lib/orber/test/interceptors_SUITE.erl b/lib/orber/test/interceptors_SUITE.erl new file mode 100644 index 0000000000..27e23a9433 --- /dev/null +++ b/lib/orber/test/interceptors_SUITE.erl @@ -0,0 +1,338 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : interceptors_SUITE.erl +%% Purpose : +%%----------------------------------------------------------------- + +-module(interceptors_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(nomatch(Not, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + Not -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS); + _ -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS + end + end()). + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([in_reply/6, out_request/6]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["This suite is for testing Orber Interceptors"]; +all(suite) -> + [local_pseudo, local_default, local_local, local_global]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + corba:orb_init([{flags, (?ORB_ENV_USE_PI bor ?ORB_ENV_LOCAL_TYPECHECKING)}, + {local_interceptors, {native, [?MODULE]}}]), + orber:jump_start(2945), + oe_orber_test_server:oe_register(), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + oe_orber_test_server:oe_unregister(), + orber:jump_stop(), + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case: local_pseudo +%% Description: +%%----------------------------------------------------------------- +local_pseudo(doc) -> [""]; +local_pseudo(suite) -> []; +local_pseudo(_) -> + ?match({native, [?MODULE]}, orber:get_local_interceptors()), + %% Global settings + Obj1 = orber_test_server:oe_create(state,[{pseudo,true}]), + Result11 = orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX), + ?match([?USHORTMAX], put(out_request, undefined)), + ?match(Result11, put(in_reply, undefined)), + + Result12 = ?match({'EXCEPTION',_}, + orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX+1)), + ?match([(?USHORTMAX+1)], put(out_request, undefined)), + ?nomatch(Result12, put(in_reply, undefined)), + + Result13 = orber_test_server:testing_iiop_oneway_delay(Obj1, 0), + ?match([0], put(out_request, undefined)), + ?nomatch(Result13, put(in_reply, undefined)), + + Result14 = ?match({'EXCEPTION', _}, + orber_test_server:raise_local_exception(Obj1)), + ?match([], put(out_request, undefined)), + ?match(Result14, put(in_reply, undefined)), + + Result15 = ?match({'EXCEPTION',_}, orber_test_server:stop_brutal(Obj1)), + ?match([], put(out_request, undefined)), + ?match(Result15, put(in_reply, undefined)), + + %% Per-object + Obj2 = orber_test_server:oe_create(state,[{pseudo,true}, + {local_interceptors, false}]), + + Result21 = orber_test_server:testing_iiop_ushort(Obj2, ?USHORTMAX), + ?nomatch([?USHORTMAX], put(out_request, undefined)), + ?nomatch(Result21, put(in_reply, undefined)), + + Obj3 = orber_test_server:oe_create(state,[{pseudo,true}, + {local_interceptors, true}]), + + Result31 = orber_test_server:testing_iiop_ushort(Obj3, ?USHORTMAX), + ?match([?USHORTMAX], put(out_request, undefined)), + ?match(Result31, put(in_reply, undefined)), + + ok. + +%%----------------------------------------------------------------- +%% Test Case: local_default +%% Description: +%%----------------------------------------------------------------- +local_default(doc) -> [""]; +local_default(suite) -> []; +local_default(_) -> + ?match({native, [?MODULE]}, orber:get_local_interceptors()), + %% Global settings + Obj1 = orber_test_server:oe_create(state, []), + Result11 = orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX), + ?match([?USHORTMAX], put(out_request, undefined)), + ?match(Result11, put(in_reply, undefined)), + + Result12 = ?match({'EXCEPTION',_}, + orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX+1)), + ?match([(?USHORTMAX+1)], put(out_request, undefined)), + ?nomatch(Result12, put(in_reply, undefined)), + + Result13 = orber_test_server:testing_iiop_oneway_delay(Obj1, 0), + ?match([0], put(out_request, undefined)), + ?nomatch(Result13, put(in_reply, undefined)), + + Result14 = ?match({'EXCEPTION', _}, + orber_test_server:raise_local_exception(Obj1)), + ?match([], put(out_request, undefined)), + ?match(Result14, put(in_reply, undefined)), + + Result15 = ?match({'EXCEPTION',_}, orber_test_server:stop_brutal(Obj1)), + ?match([], put(out_request, undefined)), + ?match(Result15, put(in_reply, undefined)), + + + %% Per-object + Obj2 = orber_test_server:oe_create(state,[{local_interceptors, false}]), + + Result21 = orber_test_server:testing_iiop_ushort(Obj2, ?USHORTMAX), + ?nomatch([?USHORTMAX], put(out_request, undefined)), + ?nomatch(Result21, put(in_reply, undefined)), + corba:dispose(Obj2), + + Obj3 = orber_test_server:oe_create(state,[{local_interceptors, true}]), + + Result31 = orber_test_server:testing_iiop_ushort(Obj3, ?USHORTMAX), + ?match([?USHORTMAX], put(out_request, undefined)), + ?match(Result31, put(in_reply, undefined)), + corba:dispose(Obj3), + ok. + +%%----------------------------------------------------------------- +%% Test Case: local_local +%% Description: +%%----------------------------------------------------------------- +local_local(doc) -> [""]; +local_local(suite) -> []; +local_local(_) -> + ?match({native, [?MODULE]}, orber:get_local_interceptors()), + %% Global settings + Obj1 = orber_test_server:oe_create(state, [{regname, {local, regname}}]), + Result11 = orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX), + ?match([?USHORTMAX], put(out_request, undefined)), + ?match(Result11, put(in_reply, undefined)), + + Result12 = ?match({'EXCEPTION',_}, + orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX+1)), + ?match([(?USHORTMAX+1)], put(out_request, undefined)), + ?nomatch(Result12, put(in_reply, undefined)), + + Result13 = orber_test_server:testing_iiop_oneway_delay(Obj1, 0), + ?match([0], put(out_request, undefined)), + ?nomatch(Result13, put(in_reply, undefined)), + + Result14 = ?match({'EXCEPTION', _}, + orber_test_server:raise_local_exception(Obj1)), + ?match([], put(out_request, undefined)), + ?match(Result14, put(in_reply, undefined)), + + Result15 = ?match({'EXCEPTION',_}, orber_test_server:stop_brutal(Obj1)), + ?match([], put(out_request, undefined)), + ?match(Result15, put(in_reply, undefined)), + + %% Per-object + Obj2 = orber_test_server:oe_create(state,[{regname, {local, regname}}, + {local_interceptors, false}]), + + Result21 = orber_test_server:testing_iiop_ushort(Obj2, ?USHORTMAX), + ?nomatch([?USHORTMAX], put(out_request, undefined)), + ?nomatch(Result21, put(in_reply, undefined)), + corba:dispose(Obj2), + + Obj3 = orber_test_server:oe_create(state,[{regname, {local, regname}}, + {local_interceptors, true}]), + + Result31 = orber_test_server:testing_iiop_ushort(Obj3, ?USHORTMAX), + ?match([?USHORTMAX], put(out_request, undefined)), + ?match(Result31, put(in_reply, undefined)), + corba:dispose(Obj3), + ok. + +%%----------------------------------------------------------------- +%% Test Case: local_global +%% Description: +%%----------------------------------------------------------------- +local_global(doc) -> [""]; +local_global(suite) -> []; +local_global(_) -> + ?match({native, [?MODULE]}, orber:get_local_interceptors()), + %% Global settings + Obj1 = orber_test_server:oe_create(state, [{regname, {global, regname}}]), + Result11 = orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX), + ?match([?USHORTMAX], put(out_request, undefined)), + ?match(Result11, put(in_reply, undefined)), + + Result12 = ?match({'EXCEPTION',_}, + orber_test_server:testing_iiop_ushort(Obj1, ?USHORTMAX+1)), + ?match([(?USHORTMAX+1)], put(out_request, undefined)), + ?nomatch(Result12, put(in_reply, undefined)), + + Result13 = orber_test_server:testing_iiop_oneway_delay(Obj1, 0), + ?match([0], put(out_request, undefined)), + ?nomatch(Result13, put(in_reply, undefined)), + + Result14 = ?match({'EXCEPTION', _}, + orber_test_server:raise_local_exception(Obj1)), + ?match([], put(out_request, undefined)), + ?match(Result14, put(in_reply, undefined)), + + Result15 = ?match({'EXCEPTION',_}, orber_test_server:stop_brutal(Obj1)), + ?match([], put(out_request, undefined)), + ?match(Result15, put(in_reply, undefined)), + + %% Per-object + Obj2 = orber_test_server:oe_create(state,[{regname, {global, regname}}, + {local_interceptors, false}]), + + Result21 = orber_test_server:testing_iiop_ushort(Obj2, ?USHORTMAX), + ?nomatch([?USHORTMAX], put(out_request, undefined)), + ?nomatch(Result21, put(in_reply, undefined)), + corba:dispose(Obj2), + + Obj3 = orber_test_server:oe_create(state,[{regname, {global, regname}}, + {local_interceptors, true}]), + + Result31 = orber_test_server:testing_iiop_ushort(Obj3, ?USHORTMAX), + ?match([?USHORTMAX], put(out_request, undefined)), + ?match(Result31, put(in_reply, undefined)), + corba:dispose(Obj3), + ok. + + + + +%%----------------------------------------------------------------- +%% Local functions +%%----------------------------------------------------------------- +%%----------------------------------------------------------------- +%% function : in_reply +%%----------------------------------------------------------------- +in_reply(Ref, _ObjKey, Ctx, Op, Reply, _Args) -> + error_logger:info_msg("=============== in_reply ================= +Connection: ~p +Operation : ~p +Reply : ~p +Context : ~p +==========================================~n", + [Ref, Op, Reply, Ctx]), + put(in_reply, Reply), + {Reply, "NewArgs"}. + +%%----------------------------------------------------------------- +%% function : out_request +%%----------------------------------------------------------------- +out_request(Ref, _ObjKey, Ctx, Op, Params, _Args) -> + error_logger:info_msg("=============== out_request ============== +Connection: ~p +Operation : ~p +Parameters: ~p +Context : ~p +==========================================~n", + [Ref, Op, Params, Ctx]), + put(out_request, Params), + {Params, "NewArgs"}. diff --git a/lib/orber/test/iop_ior_10_SUITE.erl b/lib/orber/test/iop_ior_10_SUITE.erl new file mode 100644 index 0000000000..1000c7f113 --- /dev/null +++ b/lib/orber/test/iop_ior_10_SUITE.erl @@ -0,0 +1,167 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for the IOR functions +%% +%%----------------------------------------------------------------- +-module(iop_ior_10_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> + [encoding, create_and_get_ops]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case: IOR encoding test +%% Description: Just testing the string_encoding function because the +%% other encodings is called from them. +%%----------------------------------------------------------------- +encoding(doc) -> ["Description", "more description"]; +encoding(suite) -> []; +encoding(_) -> + V = #'IIOP_Version'{major=1,minor=0}, + M0 = 'Module_Interface', + T0 = "IDL:Module/Interface:1.0", + H0 = "my.hostname.org", + P0 = 4040, + N0 = 'name', + ?line O0 = corba_fake_mk_objkey(M0, registered, N0), + PB0 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O0}, + TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0}, + S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]}, + N1 = list_to_pid("<0.100.0>"), + ?line O1 = corba_fake_mk_objkey(M0, key, N1), + PB1 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O1}, + TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1}, + S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]}, + O2 = "This is an external objectkey", + PB2 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O2}, + TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2}, + S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]}, + ?line C0 = iop_ior:string_code(S0), + ?line {S0, <<>>, _} = iop_ior:string_decode(C0), + ?line C1 = iop_ior:string_code(S1), + ?line {S1, <<>>, _} = iop_ior:string_decode(C1), + ?line C2 = iop_ior:string_code(S2), + ?line {S2, <<>>, _} = iop_ior:string_decode(C2), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: IOR creation test +%% Description: +%%----------------------------------------------------------------- +create_and_get_ops(doc) -> ["Description", "more description"]; +create_and_get_ops(suite) -> []; +create_and_get_ops(_) -> + V = #'IIOP_Version'{major=1,minor=0}, + M0 = 'Module_Interface', + T0 = "IDL:Module/Interface:1.0", + H0 = "my.hostname.org", + P0 = 4040, + N0 = 'name', + ?line O0 = corba_fake_mk_objkey(M0, registered, N0), + PB0 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O0}, + TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0}, + S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]}, + ?line S0 = iop_ior:create({1, 0}, T0, [H0], P0, -1, O0, [], 0, 0), + N1 = list_to_pid("<0.100.0>"), + ?line O1 = corba_fake_mk_objkey(M0, key, N1), + {_,_,K1,_,_,_} = O1, + PB1 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O1}, + TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1}, + S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]}, + ?line S1 = iop_ior:create({1, 0}, T0, [H0], P0, -1, O1, [], 0, 0), + O2 = "This is an external objectkey", + PB2 = #'IIOP_ProfileBody_1_0'{iiop_version=V, host=H0, port=P0, object_key=O2}, + TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2}, + S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]}, + ?line {'internal_registered', N0, _, _, M0} = iop_ior:get_key(S0), + ?line {'internal', K1, _, _, M0} = iop_ior:get_key(S1), + ?line {'external', {H0, P0, O2, _,_, + #host_data{protocol = normal, + ssl_data = undefined, + version = {1,0}, + csiv2_mech = undefined, + csiv2_statefull = false, + charset = 65537, + wcharset = 65801, + ft_heartbeat = false, + ft_primary = false, + ft_group = undefined, + csiv2_addresses = []}}} + = iop_ior:get_key(S2), + ?line T0 = iop_ior:get_typeID(S0), + ?line O0 = iop_ior:get_objkey(S0), + ?line O1 = iop_ior:get_objkey(S1), + ?line O2 = iop_ior:get_objkey(S2), + ok. + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- +corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) -> + Key = make_objkey(), + {Id, 'key', Key, term_to_binary(undefined), 0, 0}; +corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) -> + Key = term_to_binary(RegName), + {Id, 'key', Key, term_to_binary(undefined), 0, 0}; +corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) -> + {Id, 'registered', RegName, term_to_binary(undefined), 0, 0}. + + +make_objkey() -> + term_to_binary({now(), node()}). diff --git a/lib/orber/test/iop_ior_11_SUITE.erl b/lib/orber/test/iop_ior_11_SUITE.erl new file mode 100644 index 0000000000..35d01789ee --- /dev/null +++ b/lib/orber/test/iop_ior_11_SUITE.erl @@ -0,0 +1,186 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for the IOR functions +%% +%%----------------------------------------------------------------- +-module(iop_ior_11_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> + [encoding, create_and_get_ops]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case: IOR encoding test +%% Description: Just testing the string_encoding function because the +%% other encodings is called from them. +%%----------------------------------------------------------------- +encoding(doc) -> ["Description", "more description"]; +encoding(suite) -> []; +encoding(_) -> + V = #'IIOP_Version'{major=1,minor=1}, + M0 = 'Module_Interface', + T0 = "IDL:Module/Interface:1.0", + H0 = "my.hostname.org", + P0 = 4040, + N0 = 'name', + Components = case orber:iiop_ssl_port() of + -1 -> + []; + SSLPort -> + [#'IOP_TaggedComponent'{tag=?TAG_SSL_SEC_TRANS, + component_data=[0 | + cdrlib:enc_unsigned_short(2, + cdrlib:enc_unsigned_short(2, + cdrlib:enc_unsigned_short(SSLPort, [])))]}] + end, + ?line O0 = corba_fake_mk_objkey(M0, registered, N0), + PB0 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O0, + components=Components}, + TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0}, + S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]}, + N1 = list_to_pid("<0.100.0>"), + ?line O1 = corba_fake_mk_objkey(M0, key, N1), + PB1 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O1, + components=[]}, + TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1}, + S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]}, + O2 = "This is an external objectkey", + PB2 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O2, + components=[]}, + TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2}, + S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]}, + ?line C0 = iop_ior:string_code(S0), + ?line {S0, <<>>, _} = iop_ior:string_decode(C0), + ?line C1 = iop_ior:string_code(S1), + ?line {S1, <<>>, _} = iop_ior:string_decode(C1), + ?line C2 = iop_ior:string_code(S2), + ?line {S2, <<>>, _} = iop_ior:string_decode(C2), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: IOR creation test +%% Description: +%%----------------------------------------------------------------- +create_and_get_ops(doc) -> ["Description", "more description"]; +create_and_get_ops(suite) -> []; +create_and_get_ops(_) -> + V = #'IIOP_Version'{major=1,minor=1}, + CSC = #'IOP_TaggedComponent'{tag=?TAG_CODE_SETS, + component_data=?DEFAULT_CODESETS}, + M0 = 'Module_Interface', + T0 = "IDL:Module/Interface:1.0", + H0 = "my.hostname.org", + P0 = 4040, + N0 = 'name', + ?line O0 = corba_fake_mk_objkey(M0, registered, N0), + PB0 = #'IIOP_ProfileBody_1_1' + {iiop_version=V, host=H0, port=P0, object_key=O0, + components=[CSC]}, + TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0}, + S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]}, + ?line S0 = iop_ior:create({1, 1}, T0, [H0], P0, -1, O0, [CSC], 0, 0), + N1 = list_to_pid("<0.100.0>"), + ?line O1 = corba_fake_mk_objkey(M0, key, N1), + {_,_,K1,_,_,_} = O1, + PB1 = #'IIOP_ProfileBody_1_1' + {iiop_version=V, host=H0, port=P0, object_key=O1, + components=[CSC]}, + TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1}, + S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]}, + ?line S1 = iop_ior:create({1, 1}, T0, [H0], P0, -1, O1, [CSC], 0, 0), + O2 = "This is an external objectkey", + PB2 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O2, + components=[]}, + TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2}, + S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]}, + ?line {'internal_registered', N0, _, _, M0} = iop_ior:get_key(S0), + ?line {'internal', K1, _, _, M0} = iop_ior:get_key(S1), + ?line {'external', {H0, P0, O2, _,_, + #host_data{protocol = normal, + ssl_data = undefined, + version = {1,1}, + csiv2_mech = undefined, + csiv2_statefull = false, + charset = 65537, + wcharset = 65801, + ft_heartbeat = false, + ft_primary = false, + ft_group = undefined, + csiv2_addresses = []}}} = + iop_ior:get_key(S2), + ?line T0 = iop_ior:get_typeID(S0), + ?line O0 = iop_ior:get_objkey(S0), + ?line O1 = iop_ior:get_objkey(S1), + ?line O2 = iop_ior:get_objkey(S2), + ok. + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- +corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) -> + Key = make_objkey(), + {Id, 'key', Key, term_to_binary(undefined), 0, 0}; +corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) -> + Key = term_to_binary(RegName), + {Id, 'key', Key, term_to_binary(undefined), 0, 0}; +corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) -> + {Id, 'registered', RegName, term_to_binary(undefined), 0, 0}. + +make_objkey() -> + term_to_binary({now(), node()}). diff --git a/lib/orber/test/iop_ior_12_SUITE.erl b/lib/orber/test/iop_ior_12_SUITE.erl new file mode 100644 index 0000000000..42db130e54 --- /dev/null +++ b/lib/orber/test/iop_ior_12_SUITE.erl @@ -0,0 +1,187 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : iop_ior_12_SUITE.erl +%% Description : Test suite for the IOR functions +%% +%%---------------------------------------------------------------------- +-module(iop_ior_12_SUITE). + + +-include("test_server.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> + [encoding, create_and_get_ops]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case: IOR encoding test +%% Description: Just testing the string_encoding function because the +%% other encodings is called from them. +%%----------------------------------------------------------------- +encoding(doc) -> ["Description", "more description"]; +encoding(suite) -> []; +encoding(_) -> + V = #'IIOP_Version'{major=1,minor=2}, + M0 = 'Module_Interface', + T0 = "IDL:Module/Interface:1.0", + H0 = "my.hostname.org", + P0 = 4040, + N0 = 'name', + Components = case orber:iiop_ssl_port() of + -1 -> + []; + SSLPort -> + [#'IOP_TaggedComponent'{tag=?TAG_SSL_SEC_TRANS, + component_data=[0 | + cdrlib:enc_unsigned_short(2, + cdrlib:enc_unsigned_short(2, + cdrlib:enc_unsigned_short(SSLPort, [])))]}] + end, + ?line O0 = corba_fake_mk_objkey(M0, registered, N0), + PB0 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O0, + components=Components}, + TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0}, + S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]}, + N1 = list_to_pid("<0.100.0>"), + ?line O1 = corba_fake_mk_objkey(M0, key, N1), + PB1 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O1, + components=[]}, + TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1}, + S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]}, + O2 = "This is an external objectkey", + PB2 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O2, + components=[]}, + TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2}, + S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]}, + ?line C0 = iop_ior:string_code(S0), + ?line {S0, <<>>, _} = iop_ior:string_decode(C0), + ?line C1 = iop_ior:string_code(S1), + ?line {S1, <<>>, _} = iop_ior:string_decode(C1), + ?line C2 = iop_ior:string_code(S2), + ?line {S2, <<>>, _} = iop_ior:string_decode(C2), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: IOR creation test +%% Description: +%%----------------------------------------------------------------- +create_and_get_ops(doc) -> ["Description", "more description"]; +create_and_get_ops(suite) -> []; +create_and_get_ops(_) -> + V = #'IIOP_Version'{major=1,minor=2}, + CSC = #'IOP_TaggedComponent'{tag=?TAG_CODE_SETS, + component_data=?DEFAULT_CODESETS}, + M0 = 'Module_Interface', + T0 = "IDL:Module/Interface:1.0", + H0 = "my.hostname.org", + P0 = 4040, + N0 = 'name', + ?line O0 = corba_fake_mk_objkey(M0, registered, N0), + PB0 = #'IIOP_ProfileBody_1_1' + {iiop_version=V, host=H0, port=P0, object_key=O0, + components=[CSC]}, + TP0 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB0}, + S0 = #'IOP_IOR'{type_id=T0, profiles=[TP0]}, + ?line S0 = iop_ior:create({1, 2}, T0, [H0], P0, -1, O0, [CSC], 0, 0), + N1 = list_to_pid("<0.100.0>"), + ?line O1 = corba_fake_mk_objkey(M0, key, N1), + {_,_,K1,_,_,_} = O1, + PB1 = #'IIOP_ProfileBody_1_1' + {iiop_version=V, host=H0, port=P0, object_key=O1, + components=[CSC]}, + TP1 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB1}, + S1 = #'IOP_IOR'{type_id=T0, profiles=[TP1]}, + ?line S1 = iop_ior:create({1, 2}, T0, [H0], P0, -1, O1, [CSC], 0, 0), + O2 = "This is an external objectkey", + PB2 = #'IIOP_ProfileBody_1_1'{iiop_version=V, host=H0, port=P0, object_key=O2, + components=[]}, + TP2 = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, profile_data=PB2}, + S2 = #'IOP_IOR'{type_id=T0, profiles=[TP2]}, + ?line {'internal_registered', N0, _, _, M0} = iop_ior:get_key(S0), + ?line {'internal', K1, _, _, M0} = iop_ior:get_key(S1), + ?line {'external', {H0, P0, O2,_,_, + #host_data{protocol = normal, + ssl_data = undefined, + version = {1,2}, + csiv2_mech = undefined, + csiv2_statefull = false, + charset = 65537, + wcharset = 65801, + ft_heartbeat = false, + ft_primary = false, + ft_group = undefined, + csiv2_addresses = []}}} + = iop_ior:get_key(S2), + ?line T0 = iop_ior:get_typeID(S0), + ?line O0 = iop_ior:get_objkey(S0), + ?line O1 = iop_ior:get_objkey(S1), + ?line O2 = iop_ior:get_objkey(S2), + ok. + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- +corba_fake_mk_objkey(Id, 'key', Pid) when is_pid(Pid) -> + Key = make_objkey(), + {Id, 'key', Key, term_to_binary(undefined), 0, 0}; +corba_fake_mk_objkey(Id, 'key', RegName) when is_atom(RegName) -> + Key = term_to_binary(RegName), + {Id, 'key', Key, term_to_binary(undefined), 0, 0}; +corba_fake_mk_objkey(Id, 'registered', RegName) when is_atom(RegName) -> + {Id, 'registered', RegName, term_to_binary(undefined), 0, 0}. + +make_objkey() -> + term_to_binary({now(), node()}). diff --git a/lib/orber/test/lname_SUITE.erl b/lib/orber/test/lname_SUITE.erl new file mode 100644 index 0000000000..d1f0e7cf0e --- /dev/null +++ b/lib/orber/test/lname_SUITE.erl @@ -0,0 +1,198 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for the Names Library module +%% +%%----------------------------------------------------------------- +-module(lname_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/COSS/CosNaming/lname.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> + [lname_component, lname]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: name component handling tests +%% Description: +%%----------------------------------------------------------------- +lname_component(doc) -> ["Description", "more description"]; +lname_component(suite) -> []; +lname_component(_) -> + create_test(), + get_tests(), + set_tests(). + +create_test() -> + ?line #'CosNaming_NameComponent'{} = lname_component:create(), + ok. + +get_tests() -> + NC = #'CosNaming_NameComponent'{id="first", kind="apple"}, + NC1 = #'CosNaming_NameComponent'{id="", kind="apple"}, + NC2 = #'CosNaming_NameComponent'{id="first", kind=""}, + ?line "first" = lname_component:get_id(NC), + ?line "apple" = lname_component:get_kind(NC), + ?line {'EXCEPTION', #'LNameComponent_NotSet'{}} = + (catch lname_component:get_id(NC1)), + ?line {'EXCEPTION', #'LNameComponent_NotSet'{}} = + (catch lname_component:get_kind(NC2)), + ok. + +set_tests() -> + NC = #'CosNaming_NameComponent'{id="first", kind="apple"}, + ?line #'CosNaming_NameComponent'{id="second", kind="apple"} = + lname_component:set_id(NC, "second"), + ?line #'CosNaming_NameComponent'{id="first", kind="pear"} = + lname_component:set_kind(NC, "pear"), + ok. + +%%----------------------------------------------------------------- +%% Test Case: name handling tests +%% Description: +%%----------------------------------------------------------------- +lname(doc) -> ["Description", "more description"]; +lname(suite) -> []; +lname(_) -> + Name = [#'CosNaming_NameComponent'{id="first", kind="apple"}, + #'CosNaming_NameComponent'{id="last", kind="peach"}, + #'CosNaming_NameComponent'{id="and", kind="plum"}, + #'CosNaming_NameComponent'{id="always", kind="orange"}], + insert_tests(Name), + get_tests(Name), + delete_tests(Name), + comparision_tests(Name), + convertion_tests(Name). + +insert_tests(Name) -> + NC = #'CosNaming_NameComponent'{id="new", kind="pear"}, + ?line [NC, #'CosNaming_NameComponent'{id="first", kind="apple"}, + #'CosNaming_NameComponent'{id="last", kind="peach"}, + #'CosNaming_NameComponent'{id="and", kind="plum"}, + #'CosNaming_NameComponent'{id="always", kind="orange"}] = + lname:insert_component(Name, 1, NC), + ?line [#'CosNaming_NameComponent'{id="first", kind="apple"}, + #'CosNaming_NameComponent'{id="last", kind="peach"}, + #'CosNaming_NameComponent'{id="and", kind="plum"}, + #'CosNaming_NameComponent'{id="always", kind="orange"}, NC] = + lname:insert_component(Name, 5, NC), + ?line [#'CosNaming_NameComponent'{id="first", kind="apple"}, + #'CosNaming_NameComponent'{id="last", kind="peach"}, + #'CosNaming_NameComponent'{id="and", kind="plum"}, NC, + #'CosNaming_NameComponent'{id="always", kind="orange"}] = + lname:insert_component(Name, 4, NC), + ?line [#'CosNaming_NameComponent'{id="first", kind="apple"}, + #'CosNaming_NameComponent'{id="last", kind="peach"}, NC, + #'CosNaming_NameComponent'{id="and", kind="plum"}, + #'CosNaming_NameComponent'{id="always", kind="orange"}] = + lname:insert_component(Name, 3, NC), + ?line {'EXCEPTION', #'LName_NoComponent'{}} = + (catch lname:insert_component(Name, 6, NC)), + ?line {'EXCEPTION', #'LName_NoComponent'{}} = + (catch lname:insert_component(Name, 0, NC)), + ?line {'EXCEPTION', #'LName_NoComponent'{}} = + (catch lname:insert_component(Name, -2, NC)), + ok. + +get_tests(Name) -> + ?line #'CosNaming_NameComponent'{id="first", kind="apple"} = + lname:get_component(Name, 1), + ?line #'CosNaming_NameComponent'{id="always", kind="orange"} = + lname:get_component(Name, 4), + ?line #'CosNaming_NameComponent'{id="and", kind="plum"} = + lname:get_component(Name, 3), + ?line {'EXCEPTION', #'LName_NoComponent'{}} = + (catch lname:get_component(Name, 5)), + ?line {'EXCEPTION', #'LName_NoComponent'{}} = + (catch lname:get_component(Name, 0)), + ?line {'EXCEPTION', #'LName_NoComponent'{}} = + (catch lname:get_component(Name, -2)), + ok. + +delete_tests(Name) -> + ?line [#'CosNaming_NameComponent'{id="last", kind="peach"}, + #'CosNaming_NameComponent'{id="and", kind="plum"}, + #'CosNaming_NameComponent'{id="always", kind="orange"}] = + lname:delete_component(Name, 1), + ?line [#'CosNaming_NameComponent'{id="first", kind="apple"}, + #'CosNaming_NameComponent'{id="last", kind="peach"}, + #'CosNaming_NameComponent'{id="and", kind="plum"}] = + lname:delete_component(Name, 4), + ?line [#'CosNaming_NameComponent'{id="first", kind="apple"}, + #'CosNaming_NameComponent'{id="last", kind="peach"}, + #'CosNaming_NameComponent'{id="always", kind="orange"}] = + lname:delete_component(Name, 3), + ?line {'EXCEPTION', #'LName_NoComponent'{}} = + (catch lname:delete_component(Name, 6)), + ?line {'EXCEPTION', #'LName_NoComponent'{}} = + (catch lname:delete_component(Name, 0)), + ?line {'EXCEPTION', #'LName_NoComponent'{}} = + (catch lname:delete_component(Name, -2)), + ok. + +comparision_tests(Name) -> + ?line true = lname:equal(Name, Name), + ?line false = lname:equal(Name, lname:delete_component(Name, 2)), + ?line true = lname:less_than(lname:delete_component(Name, 2), Name), + ?line false = lname:less_than(Name, Name), + ?line false = lname:less_than(Name, lname:delete_component(Name, 2)), + ok. + +convertion_tests(Name) -> + ?line Name = lname:from_idl_form(Name), + ?line Name = lname:to_idl_form(Name), + ok. diff --git a/lib/orber/test/multi_ORB_SUITE.erl b/lib/orber/test/multi_ORB_SUITE.erl new file mode 100644 index 0000000000..d1931f5393 --- /dev/null +++ b/lib/orber/test/multi_ORB_SUITE.erl @@ -0,0 +1,2352 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(multi_ORB_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include_lib("orber/src/ifr_objects.hrl"). +-include("idl_output/orber_test_server.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl"). + + +-define(default_timeout, ?t:minutes(15)). + +-define(match(ExpectedRes,Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, basic_PI_api/1, multi_orber_api/1, + init_per_testcase/2, fin_per_testcase/2, multi_pseudo_orber_api/1, + light_orber_api/1, light_orber2_api/1, + ssl_1_multi_orber_api/1, ssl_2_multi_orber_api/1, ssl_reconfigure_api/1, + iiop_timeout_api/1, iiop_timeout_added_api/1, setup_connection_timeout_api/1, + setup_multi_connection_timeout_api/1, setup_multi_connection_timeout_random_api/1, + setup_multi_connection_timeout_attempts_api/1, + fragments_server_api/1, fragments_max_server_api/1, + fragments_max_server_added_api/1, fragments_client_api/1, + light_ifr_api/1, max_requests_api/1, max_requests_added_api/1, + max_connections_api/1, max_packet_size_exceeded_api/1, + max_packet_size_ok_api/1, proxy_interface_api/1, proxy_interface_ipv6_api/1, + multiple_accept_api/1, implicit_context_api/1, + pseudo_implicit_context_api/1, pseudo_two_implicit_context_api/1, + oneway_implicit_context_api/1, implicit_context_roundtrip_api/1, + oneway_pseudo_implicit_context_api/1, flags_added_api/1, + oneway_pseudo_two_implicit_context_api/1, + local_interface_api/1, local_interface_ctx_override_api/1, + local_interface_acl_override_api/1, bad_giop_header_api/1, + bad_fragment_id_client_api/1, bad_id_cancel_request_api/1, + close_connections_api/1, close_connections_local_interface_api/1, + close_connections_local_interface_ctx_override_api/1, ssl_reconfigure_generation_3_api/1, + ssl_1_multi_orber_generation_3_api/1, ssl_2_multi_orber_generation_3_api/1, + close_connections_alt_iiop_addr_api/1, close_connections_multiple_profiles_api/1]). + + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([pseudo_calls/2, pseudo_casts/2, create_fake_server_ORB/5, do_connect/3]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for multi orber interfaces", + "This suite test intra-ORB communication. There are three scenarios:", + "* No security at all (multi_orber_api)", + "* Two secure orbs using ssl (ssl_multi_orb_api)", + "* One secure and one orb with no security. (ssl_multi_orb_api)"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +%% NOTE - the fragment test cases must be first since we explicitly set a request +%% id. Otherwise, the request-id counter would be increased and we cannot know +%% what it is. +cases() -> + [fragments_server_api, + fragments_max_server_api, + fragments_max_server_added_api, + fragments_client_api, + flags_added_api, + bad_fragment_id_client_api, + bad_giop_header_api, + bad_id_cancel_request_api, + implicit_context_api, + pseudo_implicit_context_api, + pseudo_two_implicit_context_api, + implicit_context_roundtrip_api, + oneway_implicit_context_api, + oneway_pseudo_implicit_context_api, + oneway_pseudo_two_implicit_context_api, + proxy_interface_api, + proxy_interface_ipv6_api, + local_interface_api, + local_interface_ctx_override_api, + local_interface_acl_override_api, + close_connections_api, + close_connections_local_interface_api, + close_connections_local_interface_ctx_override_api, + close_connections_alt_iiop_addr_api, + close_connections_multiple_profiles_api, + multiple_accept_api, + max_requests_api, + max_requests_added_api, + max_connections_api, + max_packet_size_exceeded_api, + max_packet_size_ok_api, + light_ifr_api, + multi_pseudo_orber_api, + multi_orber_api, + light_orber_api, + light_orber2_api, + basic_PI_api, + iiop_timeout_api, + iiop_timeout_added_api, + setup_connection_timeout_api, + setup_multi_connection_timeout_api, + setup_multi_connection_timeout_attempts_api, + setup_multi_connection_timeout_random_api, + ssl_1_multi_orber_api, + ssl_1_multi_orber_generation_3_api, + ssl_2_multi_orber_api, + ssl_2_multi_orber_generation_3_api, + ssl_reconfigure_generation_3_api, + ssl_reconfigure_api + ]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + Dog=test_server:timetrap(?default_timeout), + orber:jump_start(0), + oe_orber_test_server:oe_register(), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + oe_orber_test_server:oe_unregister(), + orber:jump_stop(), + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + Config. + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, no security +%%----------------------------------------------------------------- + +implicit_context_api(doc) -> ["IIOP Implicit Contex tests"]; +implicit_context_api(suite) -> []; +implicit_context_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + %% Create a remote server + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), + + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([])), + ?match(ok, + orber_test_server: + relay_call(Relay, + [{context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, + Loopback}}]}], + IOR)), + + ?match([_,_], orber:iiop_connections(out)), + Conns = ?match([_,_], + orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), + ?match(true, lists:keymember(Loopback, 1, Conns)), + ok. + +implicit_context_roundtrip_api(doc) -> + ["IIOP Implicit Contex roundtrip tests"]; +implicit_context_roundtrip_api(suite) -> []; +implicit_context_roundtrip_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + %% Create a remote server + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + Relay = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), + + IOR = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [])), + ?match(ok, + orber_test_server: + relay_call(Relay, + [{context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, + Loopback}}]}], + IOR)), + ?match([_,_], orber:iiop_connections(out)), + Conns = ?match([_,_], + orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), + ?match(true, lists:keymember(Loopback, 1, Conns)), + ok. + + + +oneway_implicit_context_api(doc) -> ["IIOP Implicit Contex oneway tests"]; +oneway_implicit_context_api(suite) -> []; +oneway_implicit_context_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + %% Create a remote server + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), + + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([])), + ?match(ok, + orber_test_server: + relay_cast(Relay, + [{context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, + Loopback}}]}], + IOR)), + + %% We must wait for a few seconds for the client to be able to set up the + %% connection (since it's a oneway operation). + timer:sleep(5000), + ?match([_,_], orber:iiop_connections(out)), + Conns = ?match([_,_], + orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), + ?match(true, lists:keymember(Loopback, 1, Conns)), + ok. + + +pseudo_implicit_context_api(doc) -> ["IIOP Implicit Contex tests (via pseudo object)"]; +pseudo_implicit_context_api(suite) -> []; +pseudo_implicit_context_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + %% Create a remote server + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), + + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])), + ?match(ok, + orber_test_server: + relay_call(Relay, + [{context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, + Loopback}}]}], + IOR)), + ?match([_,_], orber:iiop_connections(out)), + Conns = ?match([_,_], + orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), + ?match(true, lists:keymember(Loopback, 1, Conns)), + ok. + +pseudo_two_implicit_context_api(doc) -> + ["IIOP two Implicit Contex tests (via pseudo object)"]; +pseudo_two_implicit_context_api(suite) -> []; +pseudo_two_implicit_context_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + %% Create a remote server + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), + + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])), + put(oe_server_in_context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, + IP}}]), + ?match(ok, + orber_test_server: + relay_call(Relay, + [{context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, + Loopback}}]}], + IOR)), + ?match([_,_], orber:iiop_connections(out)), + Conns = ?match([_,_], + orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), + ?match(true, lists:keymember(Loopback, 1, Conns)), + ok. + +oneway_pseudo_implicit_context_api(doc) -> ["IIOP Implicit Contex tests (via pseudo object oneway)"]; +oneway_pseudo_implicit_context_api(suite) -> []; +oneway_pseudo_implicit_context_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + %% Create a remote server + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), + + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])), + ?match(ok, + orber_test_server: + relay_cast(Relay, + [{context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, + Loopback}}]}], + IOR)), + ?match([_,_], orber:iiop_connections(out)), + Conns = ?match([_,_], + orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), + ?match(true, lists:keymember(Loopback, 1, Conns)), + ok. + +oneway_pseudo_two_implicit_context_api(doc) -> + ["IIOP two Implicit Contex tests (via pseudo object oneway)"]; +oneway_pseudo_two_implicit_context_api(suite) -> []; +oneway_pseudo_two_implicit_context_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + %% Create a remote server + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), + + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])), + %% Add incoming implicit context which must be removed. + put(oe_server_in_context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, + IP}}]), + ?match(ok, + orber_test_server: + relay_cast(Relay, + [{context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, + Loopback}}]}], + IOR)), + ?match([_,_], orber:iiop_connections(out)), + Conns = ?match([_,_], + orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), + ?match(true, lists:keymember(Loopback, 1, Conns)), + ok. + + + +multiple_accept_api(doc) -> ["IIOP Multiple Accept tests"]; +multiple_accept_api(suite) -> []; +multiple_accept_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + %% The server ORB doesn't listen to 127.0.0.1 + ?match({'EXCEPTION',_}, + corba:string_to_object("corbaloc::1.2@" ++Loopback++":"++integer_to_list(ServerPort)++"/NameService")), + ?match([], orber:iiop_connections(out)), + + IOR1 = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR1)), + ?match([_], orber:iiop_connections(out)), + + {ok, Ref1} = ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [Loopback, normal])), + + IOR2 = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR2)), + ?match([_,_], orber:iiop_connections(out)), + + {ok, Ref2} = ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [Loopback, normal, 9543])), + ?match({error, eaddrinuse}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [Loopback, normal, 9543])), + + IOR3 = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++Loopback++":9543/NameService")), + ?match({'external', {Loopback, 9543, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR3)), + ?match([_,_,_], orber:iiop_connections(out)), + + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, + remove_listen_interface, [Ref1])), + %% Wait a few seconds to be sure that the connections really has been removed. + timer:sleep(4000), + ?match([_,_], orber:iiop_connections(out)), + + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, + remove_listen_interface, [Ref2])), + %% Wait a few seconds to be sure that the connections really has been removed. + timer:sleep(4000), + ?match([_], orber:iiop_connections(out)), + + ?match({'EXCEPTION',_}, + corba:string_to_object("corbaloc::1.2@"++Loopback++":9543/NameService")), + ?match({'EXCEPTION',_}, + corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")), + + IOR4 = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR4)), + + ok. + + +proxy_interface_api(doc) -> ["IIOP Proxy Interface tests", + "This case test if the server ORB use the correct", + "interface when exporting IOR:s"]; +proxy_interface_api(suite) -> []; +proxy_interface_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR1 = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR1)), + IOR2 = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR2)), + ok. + +proxy_interface_ipv6_api(doc) -> ["IIOP Proxy Interface tests", + "This case test if the server ORB use the correct", + "IPv6 interface when exporting IOR:s"]; +proxy_interface_ipv6_api(suite) -> []; +proxy_interface_ipv6_api(_Config) -> + case orber_test_lib:version_ok() of + true -> + proxy_interface_ipv6_api2(); + Reason -> + Reason + end. + +proxy_interface_ipv6_api2() -> + Loopback = orber_test_lib:get_loopback_interface(inet6), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_LOCAL_INTERFACE)}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_IPV6}])), + + IP = orber_test_lib:remote_apply(ClientNode, orber_test_lib, get_host, []), + + IOR1 = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])), + ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + orber_test_lib:remote_apply(ClientNode, iop_ior, get_key, [IOR1])), + IOR2 = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService"])), + ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + orber_test_lib:remote_apply(ClientNode, iop_ior, get_key, [IOR2])), + ok. + +local_interface_api(doc) -> ["IIOP Local Interface tests", + "This case test if the server ORB use the correct", + "local interface when connecting to another ORB"]; +local_interface_api(suite) -> []; +local_interface_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, Loopback}])), + Port = orber:iiop_port(), + ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService"])), + [{Loopback, RemotePort}] = + ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)), + + ?match([{IP, Port}], + orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [out])), + ?match([{IP, Port}], orber:find_sockname_by_peername(Loopback,RemotePort)), + ?match([{Loopback, RemotePort}], orber:find_peername_by_sockname(IP, Port)), + + ?match([{Loopback, RemotePort}], + orber_test_lib:remote_apply(ClientNode, orber, + find_sockname_by_peername, + [IP, Port])), + ?match([{IP, Port}], + orber_test_lib:remote_apply(ClientNode, orber, + find_peername_by_sockname, + [Loopback,RemotePort])), + + + ok. + +local_interface_ctx_override_api(doc) -> + ["IIOP Local Interface tests", + "This case test if the server ORB use the correct", + "local interface when connecting to another ORB"]; +local_interface_ctx_override_api(suite) -> []; +local_interface_ctx_override_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, IP}])), + Port = orber:iiop_port(), + ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService", + [#'IOP_ServiceContext' + {context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, Loopback}}]])), + [{Loopback, RemotePort}] = + ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)), + + ?match([{IP, Port, Loopback}], + orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [out])), + ?match([{IP, Port}], orber:find_sockname_by_peername(Loopback,RemotePort)), + ?match([{Loopback, RemotePort}], orber:find_peername_by_sockname(IP, Port)), + + ?match([{Loopback, RemotePort}], + orber_test_lib:remote_apply(ClientNode, orber, + find_sockname_by_peername, + [IP, Port])), + ?match([{IP, Port}], + orber_test_lib:remote_apply(ClientNode, orber, + find_peername_by_sockname, + [Loopback,RemotePort])), + + ok. + +local_interface_acl_override_api(doc) -> + ["IIOP Local Interface tests", + "This case test if the server ORB use the correct", + "local interface when connecting to another ORB"]; +local_interface_acl_override_api(suite) -> []; +local_interface_acl_override_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + ACL = [{tcp_out, IP ++ "/18", [Loopback]}], + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, IP}, + {iiop_acl, ACL}, + {flags, ?ORB_ENV_USE_ACL_OUTGOING}])), + Port = orber:iiop_port(), + ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService", + [#'IOP_ServiceContext' + {context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, IP}}]])), + ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)), + ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService"])), + + [{Loopback, RemotePort}] = + ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)), + ?match([{IP, Port, IP}], orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [out])), + ?match([{IP, Port}], orber:find_sockname_by_peername(Loopback,RemotePort)), + ?match([{Loopback, RemotePort}], orber:find_peername_by_sockname(IP, Port)), + + ?match([{Loopback, RemotePort}], + orber_test_lib:remote_apply(ClientNode, orber, + find_sockname_by_peername, + [IP, Port])), + ?match([{IP, Port}], + orber_test_lib:remote_apply(ClientNode, orber, + find_peername_by_sockname, + [Loopback,RemotePort])), + + ok. + + +iiop_timeout_api(doc) -> ["IIOP TIMEOUT API tests", + "This case test if timeout configuration behaves correctly"]; +iiop_timeout_api(suite) -> []; +iiop_timeout_api(_Config) -> + + %% Install two secure orber. + {ok, ClientNode, ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{iiop_timeout, 6}, + {iiop_connection_timeout, 3}, + {iiop_in_connection_timeout, 3}])), + ClientPort = orber_test_lib:remote_apply(ClientNode, orber, iiop_port, []), + + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{iiop_timeout, 6}, + {iiop_connection_timeout, 3}, + {iiop_in_connection_timeout, 12}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [timeout])), + + %% Tell client_orb to interoperate with server_orb. + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + lookup, + [ServerHost, ServerPort])), + %% Interop worked fine, perform delay tests. + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + timeouts, + [ServerHost, ServerPort, 6000])), + + %% Create a connection to the "client_orb", which will now act as server. + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++ClientHost++":"++integer_to_list(ClientPort)++"/NameService")), + %% Check that the connection is established. + ?match([{_, ClientPort}], orber:iiop_connections(out)), + %% Wait >3 seconds (i.e. iiop_in_connection_timeout) and check if the connection + %% have been closed. + timer:sleep(8000), + ?match([], orber:iiop_connections(out)), + + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, + [timeout])), + ok. + +iiop_timeout_added_api(doc) -> ["IIOP TIMEOUT API tests", + "This case test if timeout configuration behaves correctly"]; +iiop_timeout_added_api(suite) -> []; +iiop_timeout_added_api(_Config) -> + IP = orber_test_lib:get_host(), + {ok, Node, _Host} = ?match({ok,_,_}, orber_test_lib:js_node([])), + Port = 1 + orber_test_lib:remote_apply(Node, orber, iiop_port, []), + ?match({ok, _}, + orber_test_lib:remote_apply(Node, orber, + add_listen_interface, + [IP, normal, + [{iiop_in_connection_timeout, 3}, + {flags, ?ORB_ENV_LOCAL_INTERFACE}, + {iiop_port, Port}]])), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, + [timeout])), + + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService")), + %% Check that the connection is established. + ?match([{_, Port}], orber:iiop_connections(out)), + %% Wait >3 seconds (i.e. iiop_in_connection_timeout) and check if the connection + %% have been closed. + timer:sleep(8000), + ?match([], orber:iiop_connections(out)), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, + [timeout])), + ok. + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB using pseudo call/cast, no security +%%----------------------------------------------------------------- + +multi_pseudo_orber_api(doc) -> + ["MULTI ORB PSEUDO API tests", + "This case test if data encode/decode (IIOP) for pseudo objects", + "produce the correct result, i.e., the test_server echos", + "the input parameter or an exception is raised (MARSHAL)."]; +multi_pseudo_orber_api(suite) -> []; +multi_pseudo_orber_api(_Config) -> + %% --- Create a slave-node --- + {ok, Node, Host} = + ?match({ok,_,_}, orber_test_lib:js_node()), + Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, + [pseudo])), + + NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, + corba:string_to_object("corbaloc::1.1@"++Host++":"++ + integer_to_list(Port)++"/NameService")), + Obj = + ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))), + orber_test_lib:corba_object_tests(Obj, NSR), + + %% Can we even contact the object? + ?match(ok, orber_test_server:print(Obj)), + + %% Invoke one blocking call followed by several invokations. + spawn(?MODULE, pseudo_calls, [5, Obj]), + ?match({ok, 10000}, orber_test_server:pseudo_call_delay(Obj, 10000)), + spawn(?MODULE, pseudo_casts, [5, Obj]), + ?match(ok, orber_test_server:pseudo_cast_delay(Obj, 10000)), + + %%--- Testing code and decode arguments --- + orber_test_lib:test_coding(Obj), + + %% Test if exit is handled properly. + ?match({'EXCEPTION',{'TRANSIENT',_,_,_}}, + orber_test_server:stop_brutal(Obj)), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, + [pseudo])), + ok. + + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB with local flags definition set. +%%----------------------------------------------------------------- +flags_added_api(doc) -> + ["MULTI ORB PSEUDO with local flags definition set"]; +flags_added_api(suite) -> []; +flags_added_api(_Config) -> + %% --- Create a slave-node --- + IP = orber_test_lib:get_host(), + {ok, Node, _Host} = + ?match({ok,_,_}, orber_test_lib:js_node([])), + Port = 1 + orber_test_lib:remote_apply(Node, orber, iiop_port, []), + ?match({ok, _}, + orber_test_lib:remote_apply(Node, orber, + add_listen_interface, + [IP, normal, + [{flags, (?ORB_ENV_LOCAL_INTERFACE bor + ?ORB_ENV_EXCLUDE_CODESET_COMPONENT)}, + {iiop_port, Port}]])), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, + [pseudo])), + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.1@"++IP++":"++ + integer_to_list(Port)++"/NameService#mamba")), + ?match({'external', {IP, Port, _ObjectKey, _Counter, + #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, + profile_data= + #'IIOP_ProfileBody_1_1'{components=[]}}, + _NewHD}}, + iop_ior:get_key(Obj)), + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, + [pseudo])), + + ok. + + + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB with limited concurrent requests +%%----------------------------------------------------------------- +max_requests_api(doc) -> + ["MULTI ORB PSEUDO with limited concurrent requests tests"]; +max_requests_api(suite) -> []; +max_requests_api(_Config) -> + %% --- Create a slave-node --- + {ok, Node, Host} = + ?match({ok,_,_}, orber_test_lib:js_node([{iiop_max_in_requests, 1}])), + Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []), + max_requests(Node, Host, Port). + +max_requests_added_api(doc) -> + ["MULTI ORB PSEUDO with limited concurrent requests tests"]; +max_requests_added_api(suite) -> []; +max_requests_added_api(_Config) -> + %% --- Create a slave-node --- + [IP] = ?match([_], orber:host()), + {ok, Node, _Host} = + ?match({ok,_,_}, orber_test_lib:js_node([])), + Port = 1 + orber_test_lib:remote_apply(Node, orber, iiop_port, []), + ?match({ok, _}, + orber_test_lib:remote_apply(Node, orber, + add_listen_interface, + [IP, normal, + [{iiop_max_in_requests, 1}, + {flags, ?ORB_ENV_LOCAL_INTERFACE}, + {iiop_port, Port}]])), + max_requests(Node, IP, Port). + +max_requests(Node, Host, Port) -> + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, + [pseudo])), + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.1@"++Host++":"++ + integer_to_list(Port)++"/NameService#mamba")), + + %% Can we even contact the object? + ?match(ok, orber_test_server:print(Obj)), + + %% Invoke one blocking call followed by several invokations. + spawn(orber_test_server, pseudo_call_delay, [Obj, 15000]), + %% Wait for a second to be sure that the previous request has been sent + timer:sleep(1000), + {MegaSecsB, Before, _} = now(), + pseudo_calls(5, Obj), + {MegaSecsA, After, _} = now(), + %% Normally we we can perform hundreds of pseudo-calls per second. Hence, + %% if we add 8 seconds to 'Before' it should still be less since we only + %% allow one request at a time to the target ORB. + ?match(true, (MegaSecsB + (Before+8)*1000000) < (MegaSecsA + After*1000000)), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, + [pseudo])), + + ok. + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB with limited concurrent connections +%%----------------------------------------------------------------- +max_connections_api(doc) -> + ["MULTI ORB PSEUDO with limited concurrent connections tests"]; +max_connections_api(suite) -> []; +max_connections_api(_Config) -> + %% --- Create a slave-node --- + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{iiop_backlog, 0}, + {iiop_max_in_connections, 2}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + + %% Claim connection 1 & 2 + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.2@"++ServerHost++":"++ + integer_to_list(ServerPort)++"/NameService#mamba")), + %% Claim backlog + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node()), + + spawn(ClientNode, orber_test_server, print, [Obj]), + timer:sleep(5000), + ?match([_], orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [])), + + %% Try to connect. Should fail. Due to the behavior of different TCP stacks, backlog 1 + %% might not be the precise value. Hence, we also need to define the iiop_timeout. Otherwise + %% this test case will fail. For the same reason we must GC this connection. + {ok, ClientNodeII, _ClientHostII} = + ?match({ok,_,_}, orber_test_lib:js_node([{iiop_setup_connection_timeout, 5}, + {iiop_timeout, 5}, + {iiop_connection_timeout, 8}])), + + ?match({'EXCEPTION', _}, + orber_test_lib:remote_apply(ClientNodeII, orber_test_server, + testing_iiop_string, [Obj, "Fail"])), + + %% Remove 2 connections. We need to wait a moment so that both sides has detected it. + timer:sleep(5000), + ?match([_,_], orber:iiop_connections()), + ?match(ok, orber_iiop_pm:close_connection([{ServerHost, ServerPort}])), + timer:sleep(5000), + [{Host, Port}] = ?match([_], orber:iiop_connections()), + ?match(ok, orber_iiop_pm:close_connection([{Host, Port}])), + timer:sleep(5000), + ?match([], orber:iiop_connections()), + + ?match([_], orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [])), + + ?match([], orber_test_lib:remote_apply(ClientNodeII, orber, + iiop_connections, [])), + + ?match({ok, "OK"}, + orber_test_lib:remote_apply(ClientNodeII, orber_test_server, + testing_iiop_string, [Obj, "OK"])), + + timer:sleep(4000), + ?match([_], orber_test_lib:remote_apply(ClientNodeII, orber, + iiop_connections, [])), + + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, + [pseudo])), + + ok. + + +%%----------------------------------------------------------------- +%% API tests for terminating connection by using an IOR. +%%----------------------------------------------------------------- +close_connections_api(doc) -> + ["Close outgoing connection "]; +close_connections_api(suite) -> []; +close_connections_api(_Config) -> + %% --- Create a slave-node --- + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IP = orber_test_lib:get_host(), + + %% Create a connection + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.2@"++IP++":"++ + integer_to_list(ServerPort)++"/NameService#mamba")), + %% Check that it's up. + ?match([{IP, ServerPort}], orber:iiop_connections(out)), + %% Try to close using the wronge interface. + ?match(ok, orber:close_connection(Obj, Loopback)), + %% Should still be up. + ?match([{IP, ServerPort}], orber:iiop_connections(out)), + %% Try to close it properly + ?match(ok, orber:close_connection(Obj)), + %% Wait a moment so that both sides has detected it. + timer:sleep(5000), + %% Worked? + ?match([], orber:iiop_connections(out)), + ok. + + +close_connections_local_interface_api(doc) -> + ["IIOP Local Interface disconnect tests", + "This case test if the server ORB use the correct", + "local interface when connecting to another ORB"]; +close_connections_local_interface_api(suite) -> []; +close_connections_local_interface_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, Loopback}])), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, IP}])), + Port = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService"])), + + %% Check that the connnection is up and running using the default interface + ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, + iiop_connections, [in])), + ?match([{IP, Port}], + orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [out])), + %% Try to close the connection + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, + close_connection, [IOR])), + %% Wait a moment so that both sides has detected it. + timer:sleep(5000), + %% Now the connection shall be gone. + ?match([], orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [out])), + ?match([], orber_test_lib:remote_apply(ServerNode, orber, + iiop_connections, [in])), + + ok. + +close_connections_local_interface_ctx_override_api(doc) -> + ["IIOP Local Interface disconnect tests", + "This case test if the server ORB use the correct", + "local interface when connecting to another ORB"]; +close_connections_local_interface_ctx_override_api(suite) -> []; +close_connections_local_interface_ctx_override_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, IP}, + {ip_address, IP}])), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, IP}])), + Port = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService", + [#'IOP_ServiceContext' + {context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, Loopback}}]])), + + timer:sleep(2000), + %% Check that the connnection is up and running using the default interface + ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, + iiop_connections, [in])), + + ?match([{IP, Port, Loopback}], + orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [out])), + %% Try to close not supplying the interface. + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, + close_connection, [IOR])), + + timer:sleep(2000), + %% The connection shall still be up and running + ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, + iiop_connections, [in])), + ?match([{IP, Port, Loopback}], + orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [out])), + %% Try to close not supplying the interface. + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, + close_connection, [IOR, IP])), + + timer:sleep(2000), + %% The connection shall still be up and running + ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, + iiop_connections, [in])), + ?match([{IP, Port, Loopback}], + orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [out])), + + %% Try to close supplying the correct interface. + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, + close_connection, [IOR, Loopback])), + %% Wait a moment so that both sides has detected it. + timer:sleep(5000), + %% Now the connection shall be gone. + ?match([], orber_test_lib:remote_apply(ServerNode, orber, + iiop_connections, [in])), + ?match([], orber_test_lib:remote_apply(ClientNode, orber, + iiop_connections, [out])), + ok. + +close_connections_alt_iiop_addr_api(doc) -> + ["IIOP alternate address disconnect tests", + "This case test if the server ORB use the correct", + "local interface when connecting to another ORB"]; +close_connections_alt_iiop_addr_api(suite) -> []; +close_connections_alt_iiop_addr_api(_Config) -> + %% --- Create a slave-node --- + Loopback = orber_test_lib:get_loopback_interface(), + IP = orber_test_lib:get_host(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{giop_version, {1, 2}}, + {ip_address, {multiple, [IP, Loopback]}}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [{nameservice, Loopback, ServerPort}])), + %% Create two connections + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.2@"++IP++":"++ + integer_to_list(ServerPort)++"/NameService#mamba")), + ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.2@"++Loopback++":"++ + integer_to_list(ServerPort)++"/NameService#mamba")), + timer:sleep(2000), + %% The connection shall still be up and running + ?match([{_,_}, {_,_}], orber:iiop_connections(out)), + ?match([{_,_}, {_,_}], + orber_test_lib:remote_apply(ServerNode, orber, + iiop_connections, [in])), + + %% Try to close the connection + ?match(ok, orber:close_connection(Obj)), + %% Wait a moment so that both sides has detected it. + timer:sleep(5000), + %% Now the connections shall be gone. + ?match([], orber:iiop_connections(out)), + ?match([], orber_test_lib:remote_apply(ServerNode, orber, + iiop_connections, [in])), + ok. + +close_connections_multiple_profiles_api(doc) -> + ["IIOP alternate address disconnect tests", + "This case test if the server ORB use the correct", + "local interface when connecting to another ORB"]; +close_connections_multiple_profiles_api(suite) -> []; +close_connections_multiple_profiles_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + %% --- Create a slave-node --- + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, + {multiple, [Loopback, IP]}}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), + %% Create two connections + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.2@"++IP++":"++ + integer_to_list(ServerPort)++"/NameService#mamba")), + ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.2@"++Loopback++":"++ + integer_to_list(ServerPort)++"/NameService#mamba")), + %% The connection shall still be up and running + ?match([{_,_}, {_,_}], orber:iiop_connections(out)), + ?match([{_,_}, {_,_}], + orber_test_lib:remote_apply(ServerNode, orber, + iiop_connections, [in])), + + %% Try to close the connection + ?match(ok, orber:close_connection(Obj)), + %% Wait a moment so that both sides has detected it. + timer:sleep(5000), + %% Now the connections shall be gone. + ?match([], orber:iiop_connections(out)), + ?match([], orber_test_lib:remote_apply(ServerNode, orber, + iiop_connections, [in])), + ok. + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB with iiop_packet_size set +%%----------------------------------------------------------------- +max_packet_size_exceeded_api(doc) -> + ["Exceed the maximum request size"]; +max_packet_size_exceeded_api(suite) -> []; +max_packet_size_exceeded_api(_Config) -> + case catch gen_tcp:listen(0, [{packet,cdr}, {packet_size, 14}]) of + {'EXIT',badarg} -> + {skipped, "The inet option {packet_size, Max} not supported"}; + {ok, LS} -> + (catch gen_tcp:close(LS)), + %% --- Create a slave-node --- + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{iiop_packet_size, 1}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, + iiop_port, []), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")), + ok + end. + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB with iiop_packet_size set +%%----------------------------------------------------------------- +max_packet_size_ok_api(doc) -> + ["Not exceed the maximum request size"]; +max_packet_size_ok_api(suite) -> []; +max_packet_size_ok_api(_Config) -> + case catch gen_tcp:listen(0, [{packet,cdr}, {packet_size, 14}]) of + {'EXIT',badarg} -> + {skipped, "The inet option {packet_size, Max} not supported"}; + {ok, LS} -> + (catch gen_tcp:close(LS)), + %% --- Create a slave-node --- + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{iiop_packet_size, 5000}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, + iiop_port, []), + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")), + ok + end. + + + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, no security +%%----------------------------------------------------------------- + +light_ifr_api(doc) -> ["LIGHT IFR ORB API tests"]; +light_ifr_api(suite) -> []; +light_ifr_api(_Config) -> + + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, 128}])), + + ?match([_,_,_,_], orber_test_lib:remote_apply(ClientNode, orber, get_tables, [])), + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + install_test_data, + [nameservice])), + + + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, 128}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + ?match([_,_,_,_], orber_test_lib:remote_apply(ServerNode, orber, get_tables, [])), + + Obj = ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaname::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService#mamba")), + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, test_coding, [Obj])), + + ?match(0, orber_test_lib:remote_apply(ClientNode, orber_diagnostics, missing_modules, [])), + + ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, + [#orber_light_ifr{id = "FakeId1", + module=non_existing, + type=?IFR_StructDef}])), + ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, + [#orber_light_ifr{id = "FakeId2", + module=non_existing, + type=?IFR_UnionDef}])), + ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, + [#orber_light_ifr{id = "FakeId3", + module=non_existing, + type=?IFR_ExceptionDef}])), + ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, + [#orber_light_ifr{id = "FakeId4", + module=non_existing, + type=?IFR_InterfaceDef}])), + ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, + [#orber_light_ifr{id = "FakeId5", + module=orber_test_lib, + type=?IFR_InterfaceDef}])), + ?match(5, orber_test_lib:remote_apply(ClientNode, orber_diagnostics, missing_modules, [])), + + + ?match(ok, mnesia:dirty_write(#ir_UnionDef{ir_Internal_ID = "FakedIId1", + absolute_name="::Module::NonExisting"})), + ?match(ok, mnesia:dirty_write(#ir_StructDef{ir_Internal_ID = "FakedIId2", + absolute_name="::Module::NonExisting"})), + ?match(ok, mnesia:dirty_write(#ir_ExceptionDef{ir_Internal_ID = "FakedIId3", + absolute_name="::Module::NonExisting"})), + ?match(ok, mnesia:dirty_write(#ir_InterfaceDef{ir_Internal_ID = "FakedIId4", + absolute_name="::Module::NonExisting"})), + ?match(ok, mnesia:dirty_write(#ir_InterfaceDef{ir_Internal_ID = "FakedIId5", + absolute_name="::orber::test::lib"})), + + ?match(5, orber_diagnostics:missing_modules()), + + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, + [nameservice])), + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + uninstall_test_data, + [nameservice])), + ok. + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, no security +%%----------------------------------------------------------------- + +light_orber_api(doc) -> ["LIGHT ORB API tests", + "This case test if a light Orber can communicate correctly", + "with an fully installed Orber."]; +light_orber_api(suite) -> []; +light_orber_api(_Config) -> + %% --- Create a slave-node --- + LocalHost = net_adm:localhost(), + {ok, Node, _Host} = + ?match({ok,_,_}, orber_test_lib:js_node([{lightweight, ["iiop://"++LocalHost++":"++integer_to_list(orber:iiop_port())]}], + lightweight)), + ?match(ok, orber:info(io)), + ?match([_], orber_test_lib:remote_apply(Node, orber_env, get_lightweight_nodes,[])), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, + [light])), + + Obj1=(catch orber_test_server:oe_create(state,[{pseudo,true}])), + ?match({_,pseudo,orber_test_server_impl, _,_, _}, Obj1), + Obj2=(catch orber_test_server:oe_create(state,[])), + ?match({_,key,_, _,_, _}, Obj2), + + NS = corba:resolve_initial_references("NameService"), + 'CosNaming_NamingContext':bind(NS, lname:new(["mamba"]), Obj1), + 'CosNaming_NamingContext':bind(NS, lname:new(["viper"]), Obj2), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + light_tests, + [LocalHost, + orber:iiop_port(), "viper"])), + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + light_tests, + [LocalHost, + orber:iiop_port(), "mamba"])), + + %% Clean up. + + catch corba:dispose(Obj1), + catch corba:dispose(Obj2), + catch 'CosNaming_NamingContext':destroy(NS), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, + [light])), + ok. +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, no security +%%----------------------------------------------------------------- + +light_orber2_api(doc) -> ["LIGHT ORB API tests", + "This case test if a light Orber can communicate correctly", + "with an fully installed Orber. This case test if we can", + "start as lightweight without first setting the environment", + "variable"]; +light_orber2_api(suite) -> []; +light_orber2_api(_Config) -> + %% --- Create a slave-node --- + LocalHost = net_adm:localhost(), + {ok, Node, _Host} = + ?match({ok,_,_}, orber_test_lib:js_node([], + {lightweigth, ["iiop://"++LocalHost++":"++integer_to_list(orber:iiop_port())]})), + ?match(ok, orber:info(io)), + ?match([_], orber_test_lib:remote_apply(Node, orber_env, get_lightweight_nodes,[])), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, + [light])), + + Obj1=(catch orber_test_server:oe_create(state,[{pseudo,true}])), + ?match({_,pseudo,orber_test_server_impl, _,_, _}, Obj1), + Obj2=(catch orber_test_server:oe_create(state,[])), + ?match({_,key,_, _,_, _}, Obj2), + + NS = corba:resolve_initial_references("NameService"), + 'CosNaming_NamingContext':bind(NS, lname:new(["mamba"]), Obj1), + 'CosNaming_NamingContext':bind(NS, lname:new(["viper"]), Obj2), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + light_tests, + [LocalHost, + orber:iiop_port(), "viper"])), + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + light_tests, + [LocalHost, + orber:iiop_port(), "mamba"])), + + %% Clean up. + + catch corba:dispose(Obj1), + catch corba:dispose(Obj2), + catch 'CosNaming_NamingContext':destroy(NS), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, + [light])), + ok. + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, no security +%%----------------------------------------------------------------- + +multi_orber_api(doc) -> ["MULTI ORB API tests", + "This case test if data encode/decode (IIOP)", + "produce the correct result, i.e., the test_server echos", + "the input parameter or an exception is raised (MARSHAL)."]; +multi_orber_api(suite) -> []; +multi_orber_api(_Config) -> + + NewICObj1 = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([])), + NewICObj2 = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{regname, {local, newic2}}])), + NewICObj3 = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{regname, {global, newic3}}])), + ?match(ok, orber_test_server:print(NewICObj1)), + ?match(ok, orber_test_server:print(NewICObj2)), + ?match(ok, orber_test_server:print(NewICObj3)), + catch corba:dispose(NewICObj1), + catch corba:dispose(NewICObj2), + catch corba:dispose(NewICObj3), + + %% --- Create a slave-node --- + {ok, Node, Host} = + ?match({ok,_,_}, orber_test_lib:js_node()), + Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, + [nameservice])), + + NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, + corba:string_to_object("corbaloc::1.2@"++Host++":"++ + integer_to_list(Port)++"/NameService")), + + ?match({'EXCEPTION',{'CosNaming_NamingContext_NotFound',_,_,_}}, + 'CosNaming_NamingContext':resolve(NSR, lname:new(["not_exist"]))), + + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))), + ?match(ok, orber_test_server:print(Obj)), + + Obj12B = ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++Host++":"++integer_to_list(Port)++"/Mamba")), + + Obj11B = ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.1@"++Host++":"++integer_to_list(Port)++"/Mamba")), + + Obj10B = ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Mamba")), + + context_test(Obj12B), + context_test(Obj11B), + + ?match(ok, orber_test_server:print(Obj12B)), + ?match(ok, orber_test_server:print(Obj11B)), + ?match(ok, orber_test_server:print(Obj10B)), + ?match({'EXCEPTION',{'CosNaming_NamingContextExt_InvalidAddress',_}}, + corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Wrong")), + + ?match(ok, orber_test_lib:corba_object_tests(Obj12B, NSR)), + ?match(ok, orber_test_lib:corba_object_tests(Obj11B, NSR)), + ?match(ok, orber_test_lib:corba_object_tests(Obj10B, NSR)), + + %%--- Testing code and decode arguments --- + orber_test_lib:test_coding(Obj), + + ?match({'EXCEPTION',#'BAD_CONTEXT'{}}, + orber_test_server: + print(Obj12B, + [{context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, + {127,0,0,1}}}]}])), + + ?match({'EXCEPTION',{'TRANSIENT',_,_,_}}, + orber_test_server:stop_brutal(Obj12B)), + ?match({'EXCEPTION',{'TRANSIENT',_,_,_}}, + orber_test_server:print(Obj12B)), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, + [nameservice])), + ok. + + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, no security, using basic interceptors +%%----------------------------------------------------------------- +basic_PI_api(doc) -> ["MULTI ORB API tests", + "This case test if data encode/decode (IIOP)", + "produce the correct result when using basic interceptors,", + "i.e., the test_server echos", + "the input parameter or an exception is raised (MARSHAL)."]; +basic_PI_api(suite) -> []; +basic_PI_api(_Config) -> + %% Change configuration to use Basic Interceptors. + orber:configure_override(interceptors, {native, [orber_test_lib]}), + %% --- Create a slave-node --- + {ok, Node, Host} = + ?match({ok,_,_}, orber_test_lib:js_node([{interceptors, {native, [orber_test_lib]}}])), + Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, + [nameservice])), + + Obj12 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.2@"++Host++":"++integer_to_list(Port)++"/NameService#mamba")), + + Obj11 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.1@"++Host++":"++integer_to_list(Port)++"/NameService#mamba")), + + Obj10 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.0@"++Host++":"++integer_to_list(Port)++"/NameService#mamba")), + + ?match(ok, corba:print_object(Obj12)), + ?match(ok, corba:print_object(Obj11, error_report)), + ?match(ok, corba:print_object(Obj10, {error_report, "Reason"})), + + ?match(ok, orber_test_server:print(Obj12)), + ?match(ok, orber_test_server:print(Obj11)), + ?match(ok, orber_test_server:print(Obj10)), + + + Obj12B = ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++Host++":"++integer_to_list(Port)++"/Mamba")), + + Obj11B = ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.1@"++Host++":"++integer_to_list(Port)++"/Mamba")), + + Obj10B = ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Mamba")), + + ?match(ok, corba:print_object(Obj12B, info_msg)), + ?match(ok, corba:print_object(Obj11B, {info_msg, "Comment"})), + ?match([_|_], corba:print_object(Obj10B, string)), + + ?match(ok, orber_test_server:print(Obj12B)), + ?match(ok, orber_test_server:print(Obj11B)), + ?match(ok, orber_test_server:print(Obj10B)), + ?match({'EXCEPTION',{'CosNaming_NamingContextExt_InvalidAddress',_}}, + corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Wrong")), + + ?match(ok, orber_test_lib:alternate_iiop_address(Host, Port)), + + context_test(Obj12B), + context_test(Obj11B), + + %%--- Testing code and decode arguments --- + orber_test_lib:test_coding(Obj12), + orber_test_lib:test_coding(Obj11), + orber_test_lib:test_coding(Obj10), + + application:set_env(orber, interceptors, false), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, + [nameservice])), + ok. + + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, ssl security depth 1 +%%----------------------------------------------------------------- + +ssl_1_multi_orber_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", + "This case set up two secure orbs and test if they can", + "communicate. The case also test to access one of the", + "secure orbs which must raise a NO_PERMISSION exception."]; +ssl_1_multi_orber_api(suite) -> []; +ssl_1_multi_orber_api(_Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + 1, [{iiop_ssl_port, 0}]), + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + 1, [{iiop_ssl_port, 0}]), + ssl_suite(ServerOptions, ClientOptions), + ok + end. + +ssl_1_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", + "This case set up two secure orbs and test if they can", + "communicate. The case also test to access one of the", + "secure orbs which must raise a NO_PERMISSION exception."]; +ssl_1_multi_orber_generation_3_api(suite) -> []; +ssl_1_multi_orber_generation_3_api(_Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + case orber_test_lib:ssl_version() of + 3 -> + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + 1, [{ssl_generation, 3}, + {iiop_ssl_port, 0}]), + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + 1, [{ssl_generation, 3}, + {iiop_ssl_port, 0}]), + ssl_suite(ServerOptions, ClientOptions), + ok; + _ -> + {skipped, "Required SSL generation not available"} + end + end. + + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, ssl security depth 2 +%%----------------------------------------------------------------- + +ssl_2_multi_orber_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", + "This case set up two secure orbs and test if they can", + "communicate. The case also test to access one of the", + "secure orbs which must raise a NO_PERMISSION exception."]; +ssl_2_multi_orber_api(suite) -> []; +ssl_2_multi_orber_api(_Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + 2, [{iiop_ssl_port, 0}]), + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + 2, [{iiop_ssl_port, 0}]), + ssl_suite(ServerOptions, ClientOptions), + ok + end. + +ssl_2_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", + "This case set up two secure orbs and test if they can", + "communicate. The case also test to access one of the", + "secure orbs which must raise a NO_PERMISSION exception."]; +ssl_2_multi_orber_generation_3_api(suite) -> []; +ssl_2_multi_orber_generation_3_api(_Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + case orber_test_lib:ssl_version() of + 3 -> + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + 2, [{ssl_generation, 3}, + {iiop_ssl_port, 0}]), + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + 2, [{ssl_generation, 3}, + {iiop_ssl_port, 0}]), + ssl_suite(ServerOptions, ClientOptions), + ok; + _ -> + {skipped, "Required SSL generation not available"} + end + end. +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, ssl security depth 2 +%%----------------------------------------------------------------- + +ssl_reconfigure_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", + "This case set up two secure orbs and test if they can", + "communicate. The case also test to access one of the", + "secure orbs which must raise a NO_PERMISSION exception."]; +ssl_reconfigure_api(suite) -> []; +ssl_reconfigure_api(_Config) -> + ssl_reconfigure([]). + +ssl_reconfigure_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", + "This case set up two secure orbs and test if they can", + "communicate. The case also test to access one of the", + "secure orbs which must raise a NO_PERMISSION exception."]; +ssl_reconfigure_generation_3_api(suite) -> []; +ssl_reconfigure_generation_3_api(_Config) -> + case orber_test_lib:ssl_version() of + 3 -> + ssl_reconfigure([{ssl_generation, 3}]); + + _ -> + {skipped, "Required SSL generation not available"} + end. + +ssl_reconfigure(ExtraSSLOptions) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, + orber_test_lib:js_node([{iiop_port, 0}, + {flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ip_address, IP}|ExtraSSLOptions])), + orber_test_lib:remote_apply(ServerNode, ssl, start, []), + orber_test_lib:remote_apply(ServerNode, crypto, start, []), + orber_test_lib:remote_apply(ServerNode, ssl, seed, ["testing"]), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [ssl])), + ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [Loopback, normal, [{iiop_port, 5648}, + {iiop_ssl_port, 5649}, + {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]])), + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + 2, [{flags, ?ORB_ENV_LOCAL_INTERFACE}, + {iiop_port, 5648}, + {iiop_ssl_port, 5649}, + {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]), + ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [Loopback, ssl, ServerOptions])), + + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + 2, [{iiop_ssl_port, 0}|ExtraSSLOptions]), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), + + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + install_test_data, + [ssl])), + orber_test_lib:remote_apply(ClientNode, ssl, start, []), + orber_test_lib:remote_apply(ServerNode, crypto, start, []), + orber_test_lib:remote_apply(ClientNode, ssl, seed, ["testing"]), + Obj = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, + string_to_object, ["corbaname:iiop:1.1@"++Loopback++":5648/NameService#mamba", + [{context, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {configuration, ClientOptions}}]}]])), + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_server, + print, [Obj])), + + ok + end. + + + +%%----------------------------------------------------------------- +%% API tests for Orber to Java ORB, no security +%%----------------------------------------------------------------- + +%orber_java_api(doc) -> ["ERLANG-ORB <-> JAVA-ORB API tests", +% "This case test if data encode/decode (IIOP)", +% "produce the correct result, i.e., the test_server echos", +% "the input parameter or an exception is raised (MARSHAL)."]; +%orber_java_api(suite) -> []; +%orber_java_api(Config) -> +% ok. + +%%------------------------------------------------------------ +%% function : ssl_suite +%% Arguments: Config +%% Depth +%% Returns : ok +%% Effect : +%%------------------------------------------------------------ + +ssl_suite(ServerOptions, ClientOptions) -> + + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), + + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), + + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [ssl])), + %% Tell the client to interoperate with the server. The purpose of this + %% operation is to look up, using NameService, an object reference and + %% use it to contact the object. + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + lookup, + [ServerHost, ServerPort])), + + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + alternate_ssl_iiop_address, + [ServerHost, ServerPort, SSLServerPort])), + + %% 'This' node is not secure. Contact the server. Must refuse connection. + NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, + corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++ + integer_to_list(ServerPort)++"/NameService")), + + %% Should be 'NO_PERMISSION'?? + ?match({'EXCEPTION',{'COMM_FAILURE',_,_,_}}, + 'CosNaming_NamingContext':resolve(NSR, lname:new(["not_exist"]))), + + %% Should be 'NO_PERMISSION'?? + ?match({'EXCEPTION',{'COMM_FAILURE',_,_,_}}, + 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))), + + %% Uninstall. + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, + [ssl])), + ok. + +%%----------------------------------------------------------------- +%% iiop_setup_connection_timeout API tests for ORB to ORB. +%%----------------------------------------------------------------- +setup_connection_timeout_api(doc) -> ["iiop_setup_connection_timeout API tests for ORB to ORB."]; +setup_connection_timeout_api(suite) -> []; +setup_connection_timeout_api(_Config) -> + ?match(ok, application:set_env(orber, iiop_backlog, 0)), + %% Wait to be sure that the configuration has kicked in. + timer:sleep(2000), + {ok, Ref, Port} = create_fake_server_ORB(normal, 0, [], listen, []), + ?match(ok, orber:configure(iiop_setup_connection_timeout, 5)), + ?match(ok, orber:info(io)), + IP = orber_test_lib:get_host(), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + timer:sleep(2000), + Corbaloc = "corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService", + ?match({'EXCEPTION', _E}, corba:string_to_object(Corbaloc)), + destroy_fake_ORB(Ref), + ?match(ok, application:set_env(orber, iiop_backlog, 5)), + ok. + +%%----------------------------------------------------------------- +%% iiop_setup_connection_timeout API tests for ORB to ORB. +%%----------------------------------------------------------------- +setup_multi_connection_timeout_api(doc) -> + ["iiop_multi_setup_connection_timeout API tests for ORB to ORB."]; +setup_multi_connection_timeout_api(suite) -> []; +setup_multi_connection_timeout_api(_Config) -> + ?match(ok, application:set_env(orber, iiop_backlog, 0)), + %% Wait to be sure that the configuration has kicked in. + timer:sleep(2000), + {ok, Ref, Port} = create_fake_server_ORB(normal, 0, [], listen, []), + ?match(ok, application:set_env(orber, iiop_out_ports, {6042, 6234})), + ?match(ok, orber:configure(iiop_setup_connection_timeout, 5)), + ?match(ok, orber:info(io)), + IP = orber_test_lib:get_host(), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + Corbaloc = "corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService", + timer:sleep(2000), + ?match({'EXCEPTION', _E}, corba:string_to_object(Corbaloc)), + destroy_fake_ORB(Ref), + ?match(ok, application:set_env(orber, iiop_backlog, 5)), + ?match(ok, application:set_env(orber, iiop_out_ports, undefined)), + ok. + +setup_multi_connection_timeout_attempts_api(doc) -> + ["iiop_multi_setup_connection_timeout API tests for ORB to ORB."]; +setup_multi_connection_timeout_attempts_api(suite) -> []; +setup_multi_connection_timeout_attempts_api(_Config) -> + ?match(ok, application:set_env(orber, iiop_backlog, 0)), + %% Wait to be sure that the configuration has kicked in. + timer:sleep(2000), + {ok, Ref, Port} = create_fake_server_ORB(normal, 0, [], listen, []), + ?match(ok, application:set_env(orber, iiop_out_ports, {6042, 6234})), + ?match(ok, application:set_env(orber, iiop_out_ports_attempts, 1)), + ?match(ok, orber:configure(iiop_setup_connection_timeout, 5)), + ?match(ok, orber:info(io)), + IP = orber_test_lib:get_host(), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + Corbaloc = "corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService", + timer:sleep(2000), + ?match({'EXCEPTION', _E}, corba:string_to_object(Corbaloc)), + destroy_fake_ORB(Ref), + ?match(ok, application:set_env(orber, iiop_backlog, 5)), + ?match(ok, application:set_env(orber, iiop_out_ports, undefined)), + ok. + +setup_multi_connection_timeout_random_api(doc) -> + ["iiop_multi_setup_connection_timeout API tests for ORB to ORB."]; +setup_multi_connection_timeout_random_api(suite) -> []; +setup_multi_connection_timeout_random_api(_Config) -> + ?match(ok, application:set_env(orber, iiop_backlog, 0)), + %% Wait to be sure that the configuration has kicked in. + timer:sleep(2000), + {ok, Ref, Port} = create_fake_server_ORB(normal, 0, [], listen, []), + ?match(ok, application:set_env(orber, iiop_out_ports, {6042, 6234})), + ?match(ok, application:set_env(orber, iiop_out_ports_random, true)), + ?match(ok, orber:configure(iiop_setup_connection_timeout, 5)), + ?match(ok, orber:info(io)), + IP = orber_test_lib:get_host(), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + spawn(?MODULE, do_connect, [IP, Port, [{active, false}]]), + Corbaloc = "corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService", + timer:sleep(2000), + ?match({'EXCEPTION', _E}, corba:string_to_object(Corbaloc)), + destroy_fake_ORB(Ref), + ?match(ok, application:set_env(orber, iiop_backlog, 5)), + ?match(ok, application:set_env(orber, iiop_out_ports, undefined)), + ok. + +%%----------------------------------------------------------------- +%% Sending an incorrect header to the server-side ORB. +%%----------------------------------------------------------------- +bad_giop_header_api(doc) -> ["Sending an incorrect header to the server-side ORB."]; +bad_giop_header_api(suite) -> []; +bad_giop_header_api(_Config) -> + orber:configure_override(interceptors, {native,[orber_iiop_tracer]}), + orber:configure(orber_debug_level, 10), + ?match(ok, orber:info(io)), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node()), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + Req = <<"GIOP",1,2,0,100,0,0,0,5,0,0,0,10,50>> , + ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], + message_error, [Req])), + + application:set_env(orber, interceptors, false), + orber:configure(orber_debug_level, 0), + ok. + + +%%----------------------------------------------------------------- +%% Fragmented IIOP tests (Server-side). +%%----------------------------------------------------------------- +-define(REQUEST_ID, 0). + +-define(REPLY_FRAG_1, <<71,73,79,80,1,2,2,1,0,0,0,41,0,0,0,?REQUEST_ID,0,0,0,0,0,0,0,1,78,69,79,0,0,0,0,2,0,10,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,4,49>>). +%% The fragments are identical for requests and replies. +-define(FRAG_2, <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,?REQUEST_ID,50>>). +-define(FRAG_3, <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,?REQUEST_ID,51>>). +-define(FRAG_4, <<71,73,79,80,1,2,0,7,0,0,0,5,0,0,0,?REQUEST_ID,0>>). + + +fragments_server_api(doc) -> ["fragments API tests for server-side ORB."]; +fragments_server_api(suite) -> []; +fragments_server_api(_Config) -> + %% --- Create a slave-node --- + {ok, Node, Host} = + ?match({ok,_,_}, orber_test_lib:js_node()), + Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []), + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, + [nameservice])), + + NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, + corba:string_to_object("corbaloc::1.2@"++Host++":"++ + integer_to_list(Port)++"/NameService")), + + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))), + + Any = #any{typecode = {tk_string,0}, + value = "123"}, + Target = #'GIOP_TargetAddress'{label = ?GIOP_KeyAddr, + value = iop_ior:get_objkey(Obj)}, + %% Fix a request header. + {Hdr, Body, HdrLen, _What, _Flags} = + cdr_encode:enc_request_split( + #giop_env{version = {1,2}, objkey = Target, + request_id = ?REQUEST_ID, + response_expected = true, + op = testing_iiop_any, + parameters = [49], ctx = [], + tc = {tk_void,[tk_char],[]}, + host = [orber_test_lib:get_host()], + iiop_port = orber:iiop_port(), + iiop_ssl_port = orber:iiop_ssl_port(), + domain = orber:domain(), + partial_security = orber:partial_security()}), + NewBody = + case size(Body) of + 1 -> + <<0,0,0,18,0,0,0,0,0,0,0,4,49>> ; + Size -> + Aligned = Size -1, + <<AligmnetData:Aligned/binary,49>> = Body, + list_to_binary([AligmnetData, <<0,0,0,18,0,0,0,0,0,0,0,4,49>> ]) + end, + + MessSize = HdrLen+size(NewBody), + ReqFrag = list_to_binary([ <<"GIOP",1:8,2:8,2:8,0:8, + MessSize:32/big-unsigned-integer>> , Hdr |NewBody]), + ?match(Any, fake_client_ORB(normal, Host, Port, [], fragments, + [ReqFrag, ?FRAG_2, ?FRAG_3, ?FRAG_4])), + + ok. + +%%----------------------------------------------------------------- +%% Fragmented IIOP tests (Server-side). Exceeding Maximum. +%%----------------------------------------------------------------- +fragments_max_server_api(doc) -> ["Maximum fragments API tests for server-side ORB."]; +fragments_max_server_api(suite) -> []; +fragments_max_server_api(_Config) -> + %% --- Create a slave-node --- + IP = orber_test_lib:get_host(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{iiop_max_fragments, 2}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + fragments_max_server(ServerNode, IP, ServerPort). + +fragments_max_server_added_api(doc) -> ["Maximum fragments API tests for server-side ORB."]; +fragments_max_server_added_api(suite) -> []; +fragments_max_server_added_api(_Config) -> + %% --- Create a slave-node --- + IP = orber_test_lib:get_host(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([])), + ServerPort = 1 + orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [IP, normal, + [{iiop_max_fragments, 2}, + {flags, ?ORB_ENV_LOCAL_INTERFACE}, + {iiop_port, ServerPort}]])), + fragments_max_server(ServerNode, IP, ServerPort). + +fragments_max_server(ServerNode, ServerHost, ServerPort) -> + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [nameservice])), + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname::1.2@"++ServerHost++":"++ + integer_to_list(ServerPort)++"/NameService#mamba")), + Target = #'GIOP_TargetAddress'{label = ?GIOP_KeyAddr, + value = iop_ior:get_objkey(Obj)}, + %% Fix a request header. + {Hdr, Body, HdrLen, _What, _Flags} = + cdr_encode:enc_request_split( + #giop_env{version = {1,2}, + objkey = Target, + request_id = ?REQUEST_ID, + response_expected = true, + op = testing_iiop_any, + parameters = [49], ctx = [], + tc = {tk_void,[tk_char],[]}, + host = [orber_test_lib:get_host()], + iiop_port = orber:iiop_port(), + iiop_ssl_port = orber:iiop_ssl_port(), + domain = orber:domain(), + partial_security = orber:partial_security()}), + NewBody = + case size(Body) of + 1 -> + <<0,0,0,18,0,0,0,0,0,0,0,4,49>> ; + Size -> + Aligned = Size -1, + <<AligmnetData:Aligned/binary,49>> = Body, + list_to_binary([AligmnetData, <<0,0,0,18,0,0,0,0,0,0,0,4,49>> ]) + end, + + MessSize = HdrLen+size(NewBody), + ReqFrag = list_to_binary([ <<"GIOP",1:8,2:8,2:8,0:8, + MessSize:32/big-unsigned-integer>> , Hdr |NewBody]), + ?match(#'IMP_LIMIT'{}, + fake_client_ORB(normal, ServerHost, ServerPort, [], fragments_max, + [ReqFrag, ?FRAG_2, ?FRAG_3, ?FRAG_4])), + + ok. + +%%----------------------------------------------------------------- +%% Fragmented IIOP tests (Client-side). +%%----------------------------------------------------------------- +fragments_client_api(doc) -> ["fragments API tests for client-side ORB."]; +fragments_client_api(suite) -> []; +fragments_client_api(_Config) -> + Any = #any{typecode = {tk_string,0}, + value = "123"}, + application:set_env(orber, interceptors, {native,[orber_iiop_tracer]}), + orber:configure(orber_debug_level, 10), + orber:info(), + IOR = ?match({'IOP_IOR',_,_}, + iop_ior:create_external({1, 2}, "IDL:FAKE:1.0", + "localhost", 6004, "FAKE", [])), + spawn(?MODULE, create_fake_server_ORB, [normal, 6004, [], fragments, + [?REPLY_FRAG_1, ?FRAG_2, + ?FRAG_3, ?FRAG_4]]), + ?match({ok, Any}, orber_test_server:testing_iiop_any(IOR, Any)), + application:set_env(orber, interceptors, false), + orber:configure(orber_debug_level, 0), + ok. + +%%----------------------------------------------------------------- +%% Fragmented IIOP tests (Client-side). +%%----------------------------------------------------------------- +bad_fragment_id_client_api(doc) -> ["fragments API tests for client-side ORB."]; +bad_fragment_id_client_api(suite) -> []; +bad_fragment_id_client_api(_Config) -> + application:set_env(orber, interceptors, {native,[orber_iiop_tracer]}), + orber:configure(orber_debug_level, 10), + orber:info(), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node()), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + Req = <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,100,50>> , + ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], + message_error, [Req])), + + application:set_env(orber, interceptors, false), + orber:configure(orber_debug_level, 0), + + ok. + +%%----------------------------------------------------------------- +%% Non-existing request id +%%----------------------------------------------------------------- +bad_id_cancel_request_api(doc) -> ["Description", "more description"]; +bad_id_cancel_request_api(suite) -> []; +bad_id_cancel_request_api(Config) when is_list(Config) -> + Req10 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 0}, + request_id = 556}), + Req11 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 1}, + request_id = 556}), + Req12 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 2}, + request_id = 556}), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node()), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], + message_error, [Req10])), + ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], + message_error, [Req11])), + ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], + message_error, [Req12])), + ok. + +%%----------------------------------------------------------------- +%% Local functions. +%%----------------------------------------------------------------- + +do_connect(Host, Port, Options) -> + gen_tcp:connect(Host, Port, Options), + timer:sleep(20000). + +pseudo_calls(0, _) -> + ok; +pseudo_calls(Times, Obj) -> + orber_test_server:pseudo_call(Obj), + New = Times - 1, + pseudo_calls(New, Obj). +pseudo_casts(0, _) -> + ok; +pseudo_casts(Times, Obj) -> + orber_test_server:pseudo_cast(Obj), + New = Times - 1, + pseudo_casts(New, Obj). + +context_test(Obj) -> + CodeSetCtx = #'CONV_FRAME_CodeSetContext'{char_data = 65537, + wchar_data = 65801}, + FTGrp = #'FT_FTGroupVersionServiceContext'{object_group_ref_version = ?ULONGMAX}, + FTReq = #'FT_FTRequestServiceContext'{client_id = "ClientId", + retention_id = ?LONGMAX, + expiration_time = ?ULONGLONGMAX}, + + IDToken1 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAbsent, + value = true}, + IDToken2 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAnonymous, + value = false}, + IDToken3 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTPrincipalName, + value = [0,255]}, + IDToken4 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTX509CertChain, + value = [1,255]}, + IDToken5 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTDistinguishedName, + value = [2,255]}, + IDToken6 = #'CSI_IdentityToken'{label = ?ULONGMAX, + value = [3,255]}, + + MTEstablishContext1 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken1, + client_authentication_token = [1, 255]}}, + MTEstablishContext2 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken2, + client_authentication_token = [1, 255]}}, + MTEstablishContext3 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken3, + client_authentication_token = [1, 255]}}, + MTEstablishContext4 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken4, + client_authentication_token = [1, 255]}}, + MTEstablishContext5 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken5, + client_authentication_token = [1, 255]}}, + MTEstablishContext6 = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = + [#'CSI_AuthorizationElement' + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken6, + client_authentication_token = [1, 255]}}, + MTCompleteEstablishContext = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTCompleteEstablishContext, + value = #'CSI_CompleteEstablishContext'{client_context_id = ?ULONGLONGMAX, + context_stateful = false, + final_context_token = [1, 255]}}, + MTContextError = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTContextError, + value = #'CSI_ContextError'{client_context_id = ?ULONGLONGMAX, + major_status = 1, + minor_status = 2, + error_token = [2,255]}}, + MTMessageInContext = #'CSI_SASContextBody' + {label = ?CSI_MsgType_MTMessageInContext, + value = #'CSI_MessageInContext'{client_context_id = ?ULONGLONGMAX, + discard_context = true}}, + Ctx = [#'IOP_ServiceContext'{context_id=?IOP_CodeSets, + context_data = CodeSetCtx}, + #'IOP_ServiceContext'{context_id=?IOP_FT_GROUP_VERSION, + context_data = FTGrp}, + #'IOP_ServiceContext'{context_id=?IOP_FT_REQUEST, + context_data = FTReq}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext1}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext2}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext3}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext4}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext5}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTEstablishContext6}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTCompleteEstablishContext}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTContextError}, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + context_data = MTMessageInContext}, + #'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {any_kind_of_data, {127,0,0,1}, 4001}}], + ?match(ok, orber_test_server:testing_iiop_context(Obj, [{context, Ctx}])). + + +create_fake_server_ORB(Type, Port, Options, listen, _Data) -> + {ok, _ListenSocket, NewPort} = + orber_socket:listen(Type, Port, + [{backlog, 0}, {active, false}|Options]), + Socket = orber_socket:connect(Type, 'localhost', NewPort, [{active, false}|Options]), + {ok, {Type, Socket}, NewPort}; +create_fake_server_ORB(Type, Port, Options, Action, Data) -> + {ok, ListenSocket, _NewPort} = + orber_socket:listen(Type, Port, [{active, false}|Options]), + Socket = orber_socket:accept(Type, ListenSocket), + do_server_action(Type, Socket, Action, Data), + orber_socket:close(Type, Socket), + ok. + +destroy_fake_ORB({Type, Socket}) -> + orber_socket:close(Type, Socket); +destroy_fake_ORB(_) -> + ok. + +fake_client_ORB(Type, Host, Port, Options, connect, _Data) -> + Socket = orber_socket:connect(Type, Host, Port, [{active, false}|Options]), + {Type, Socket}; +fake_client_ORB(Type, Host, Port, Options, Action, Data) -> + Socket = orber_socket:connect(Type, Host, Port, [{active, false}|Options]), + Result = do_client_action(Type, Socket, Action, Data), + orber_socket:close(Type, Socket), + Result. + + + +do_server_action(Type, Socket, fragments, FragList) -> + timer:sleep(3000), + {ok, _B} = gen_tcp:recv(Socket, 0), + ok = send_data(Type, Socket, FragList); +do_server_action(_Type, _Socket, _Action, _Data) -> + ok. + +do_client_action(Type, Socket, fragments, FragList) -> + ok = send_data(Type, Socket, FragList), + timer:sleep(3000), + {ok, Bytes} = gen_tcp:recv(Socket, 0), + {#reply_header{request_id = ?REQUEST_ID, reply_status = no_exception}, ok, [Par]} = + cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes), + Par; +do_client_action(Type, Socket, fragments_max, FragList) -> + ok = send_data(Type, Socket, FragList), + timer:sleep(3000), + {ok, Bytes} = gen_tcp:recv(Socket, 0), + {#reply_header{request_id = ?REQUEST_ID, reply_status = system_exception}, Exc, []} = + cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes), + Exc; +do_client_action(Type, Socket, message_error, Data) -> + ok = send_data(Type, Socket, Data), + timer:sleep(3000), + {ok,Bytes} = gen_tcp:recv(Socket, 0), + 'message_error' = cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes), + ok; +do_client_action(_Type, _Socket, _Action, _Data) -> + ok. + +send_data(_Type, _Socket, []) -> + ok; +send_data(Type, Socket, [H|T]) -> + orber_socket:write(Type, Socket, H), + send_data(Type, Socket, T). + diff --git a/lib/orber/test/naming_context_SUITE.erl b/lib/orber/test/naming_context_SUITE.erl new file mode 100644 index 0000000000..4406e01d5a --- /dev/null +++ b/lib/orber/test/naming_context_SUITE.erl @@ -0,0 +1,385 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for Name service +%% +%%----------------------------------------------------------------- +-module(naming_context_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include_lib("orber/include/corba.hrl"). + +-define(default_timeout, ?t:minutes(5)). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- + +-export([name_context/1, check_list/1, name_context_ext/1]). + +-export([init_all/1, finish_all/1, init_per_testcase/2, fin_per_testcase/2]). + + +%%----------------------------------------------------------------- +%% Macros +%%----------------------------------------------------------------- +-define(REMAP_EXCEPT(F), case catch F of + {'EXCEPTION', E} -> exit(E); + {'EXIT', E} -> exit(E); + R -> R + end). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [name_context, check_list, name_context_ext]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + ?line Dog=test_server:timetrap(?default_timeout), + orber:jump_start(0), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + orber:jump_stop(), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + Config. + +finish_all(Config) -> + Config. + +%%----------------------------------------------------------------- +%% Test Case: name handling tests +%% Description: +%%----------------------------------------------------------------- +name_context(doc) -> ["Description", "more description"]; +name_context(suite) -> []; +name_context(_) -> + ?REMAP_EXCEPT(name_context_run()). + +name_context_run() -> + ?line Ns = corba:resolve_initial_references("NameService"), + + ?match({'EXCEPTION', #'NO_PERMISSION'{}}, + 'CosNaming_NamingContextExt':destroy(Ns)), + + %% Create a test context. + ?line Tc = 'CosNaming_NamingContext':bind_new_context(Ns, + [#'CosNaming_NameComponent'{id="testcontext", + kind=""}]), + %% Start testing + ?line 'CosNaming_NamingContext':bind(Tc, [#'CosNaming_NameComponent' + {id="hej", + kind=""}], Ns), + ?line Ns = 'CosNaming_NamingContext':resolve(Tc, + [#'CosNaming_NameComponent'{id="hej", + kind=""}]), + ?line Nc = 'CosNaming_NamingContext':new_context(Tc), + ?line 'CosNaming_NamingContext':bind(Tc, [#'CosNaming_NameComponent' + {id="stop", + kind=""}], Nc), + ?line Nc = 'CosNaming_NamingContext':resolve(Tc, + [#'CosNaming_NameComponent'{id="stop", + kind=""}]), + ?line {'EXCEPTION', E0} = + (catch 'CosNaming_NamingContext':bind(Tc, + [#'CosNaming_NameComponent'{id="stop", + kind=""}], Ns)), + ?line ok = 'CosNaming_NamingContext':rebind(Tc, + [#'CosNaming_NameComponent'{id="stop", + kind=""}], Ns), + ?line {'CosNaming_NamingContext_AlreadyBound', _} = E0, + ?line 'CosNaming_NamingContext':bind_context(Tc, + [#'CosNaming_NameComponent'{id="evaluate", + kind=""}], Nc), + ?line Nc = + 'CosNaming_NamingContext':resolve(Tc, + [#'CosNaming_NameComponent'{id="evaluate", + kind=""}]), + ?line 'CosNaming_NamingContext':bind(Tc, + [#'CosNaming_NameComponent'{id="evaluate", + kind=""}, + #'CosNaming_NameComponent'{id="hej", + kind=""}], Ns), + ?line ok = 'CosNaming_NamingContext':rebind(Tc, + [#'CosNaming_NameComponent'{id="evaluate", + kind=""}, + #'CosNaming_NameComponent'{id="hej", + kind=""}], Ns), + ?line Ns = 'CosNaming_NamingContext':resolve(Tc, + [#'CosNaming_NameComponent'{id="evaluate", + kind=""}, + #'CosNaming_NameComponent'{id="hej", + kind=""}]), + ?line {'EXCEPTION', E1} = + (catch 'CosNaming_NamingContext':resolve(Tc, + [#'CosNaming_NameComponent'{id="stop", + kind=""}, + #'CosNaming_NameComponent'{id="hej", + kind=""}])), + ?line ?match(ok, orber_diagnostics:nameservice()), + + ?line {'CosNaming_NamingContext_CannotProceed', _,_,_} = E1, + ?line {'EXCEPTION', E2} = (catch 'CosNaming_NamingContext':destroy(Nc)), + ?line {'CosNaming_NamingContext_NotEmpty', _} = E2, + ?line ok = 'CosNaming_NamingContext':unbind(Tc, + [#'CosNaming_NameComponent'{id="evaluate", + kind=""}, + #'CosNaming_NameComponent'{id="hej", + kind=""}]), + ?line ok = 'CosNaming_NamingContext':destroy(Nc), + ?line ok = 'CosNaming_NamingContext':unbind(Tc, + [#'CosNaming_NameComponent'{id="evaluate", + kind=""}]), + ?line ok = 'CosNaming_NamingContext':unbind(Tc, + [#'CosNaming_NameComponent'{id="stop", + kind=""}]), + ?line ok = 'CosNaming_NamingContext':unbind(Tc, + [#'CosNaming_NameComponent'{id="hej", + kind=""}]), + ?line case 'CosNaming_NamingContext':list(Tc, 3) of + {ok, [], ?ORBER_NIL_OBJREF} -> + ok; + _ -> + exit(not_empty) + end, + ?line ok = 'CosNaming_NamingContext':unbind(Ns, + [#'CosNaming_NameComponent'{id="testcontext", + kind=""}]), + ?line ok = 'CosNaming_NamingContext':destroy(Tc), + ok. + + + +check_list(doc) -> + ["Check that the CosNaming::NamingContext::list()", + "returns ok.", + "Own Id: OTP-2023"]; +check_list(suite) -> []; +check_list(Config) when is_list(Config) -> + ?REMAP_EXCEPT(check_list_run(Config)). + +check_list_run(_Config) -> + create_default_contexts(), + ?line Ns = corba:resolve_initial_references("NameService"), + ?line {_, BL, _} = ?match({ok, _, ?ORBER_NIL_OBJREF}, + 'CosNaming_NamingContext':list(Ns, 256)), + + FF = fun(X) -> XX = hd(X#'CosNaming_Binding'.binding_name), + XX#'CosNaming_NameComponent'.id end, + + L = lists:sort(lists:map(FF, BL)), + ?line ["host", "workgroup"] = L, + + %% Test next_n/2 + ?line {_, _, BI} = ?match({ok, [], _BI}, 'CosNaming_NamingContext':list(Ns, 0)), + ?line ?match({true, []}, 'CosNaming_BindingIterator':next_n(BI, 0)), + ?line ?match({true, [_]}, 'CosNaming_BindingIterator':next_n(BI, 1)), + ?line ?match({false, [_]}, 'CosNaming_BindingIterator':next_n(BI, 1)), + ?line ?match({false, []}, 'CosNaming_BindingIterator':next_n(BI, 1)), + ?line ?match(ok, 'CosNaming_BindingIterator':destroy(BI)), + + ?line {_, _, BI2} = ?match({ok, [], _BI2}, 'CosNaming_NamingContext':list(Ns, 0)), + ?line ?match({true, _}, 'CosNaming_BindingIterator':next_one(BI2)), + ?line ?match({true, _}, 'CosNaming_BindingIterator':next_one(BI2)), + ?line ?match({false, _}, 'CosNaming_BindingIterator':next_one(BI2)), + ?line ?match(ok, 'CosNaming_BindingIterator':destroy(BI2)), + ?line ?match(ok, orber_diagnostics:nameservice()), + ok. + +create_default_contexts() -> + HostComponent = lname_component:set_id(lname_component:create(), + "host"), + HostsComponent = lname_component:set_id(lname_component:create(), + "hosts"), + ResourcesComponent = lname_component:set_id(lname_component:create(), + "resources"), + DevelopmentComponent = lname_component:set_id(lname_component:create(), + "development"), + FactoriesComponent = lname_component:set_id(lname_component:create(), + "factories"), + WGComponent = lname_component:set_id(lname_component:create(), + "workgroup"), + %% Creation of Naming Context host and it's subcontexts + NS = corba:resolve_initial_references("NameService"), + H = 'CosNaming_NamingContext':bind_new_context(NS, + lname:insert_component(lname:create(), 1, HostComponent)), + HR = 'CosNaming_NamingContext':bind_new_context(H, + lname:insert_component(lname:create(), 1, ResourcesComponent)), + 'CosNaming_NamingContext':bind_new_context(HR, + lname:insert_component(lname:create(), 1, FactoriesComponent)), + HD = 'CosNaming_NamingContext':bind_new_context(H, + lname:insert_component(lname:create(), 1, DevelopmentComponent)), + HDR = 'CosNaming_NamingContext':bind_new_context(HD, + lname:insert_component(lname:create(), 1, ResourcesComponent)), + 'CosNaming_NamingContext':bind_new_context(HDR, + lname:insert_component(lname:create(), 1, FactoriesComponent)), + %% Creation of Naming Context workgroup and it's subcontexts + W = 'CosNaming_NamingContext':bind_new_context(NS, + lname:insert_component(lname:create(), 1, WGComponent)), + 'CosNaming_NamingContext':bind_new_context(W, + lname:insert_component(lname:create(), 1, HostsComponent)), + WR = 'CosNaming_NamingContext':bind_new_context(W, + lname:insert_component(lname:create(), 1, ResourcesComponent)), + 'CosNaming_NamingContext':bind_new_context(WR, + lname:insert_component(lname:create(), 1, FactoriesComponent)), + WD = 'CosNaming_NamingContext':bind_new_context(W, + lname:insert_component(lname:create(), 1, DevelopmentComponent)), + WDR = 'CosNaming_NamingContext':bind_new_context(WD, + lname:insert_component(lname:create(), 1, ResourcesComponent)), + 'CosNaming_NamingContext':bind_new_context(WDR, + lname:insert_component(lname:create(), 1, FactoriesComponent)), + ok. + +%%----------------------------------------------------------------- +%% Test Case: +%% Description: +%%----------------------------------------------------------------- +name_context_ext(doc) -> ["Description", "more description"]; +name_context_ext(suite) -> []; +name_context_ext(_Config) -> + ?REMAP_EXCEPT(name_context_ext_run()). + +name_context_ext_run() -> + ?line NS = ?match({_,pseudo,_, _,_, _}, + corba:resolve_initial_references("NameService")), + + Name1 = [#'CosNaming_NameComponent'{id="\\<id1\\>", kind="kind1"}, + #'CosNaming_NameComponent'{id="id2", kind="kind2"}], + String1 = "\\<id1\\>.kind1/id2.kind2", + Name2 = [#'CosNaming_NameComponent'{id="id1", kind=""}, + #'CosNaming_NameComponent'{id="id2", kind=""}, + #'CosNaming_NameComponent'{id="id3", kind=""}], + String2 = "id1/id2/id3", + Name3 = [#'CosNaming_NameComponent'{id="id1", kind="kind1"}, + #'CosNaming_NameComponent'{id="", kind=""}, + #'CosNaming_NameComponent'{id="id3", kind="kind3"}], + String3 = "id1.kind1/./id3.kind3", + Name4 = [#'CosNaming_NameComponent'{id="id1", kind="kind1"}, + #'CosNaming_NameComponent'{id="i.d.2", kind="kind2"}, + #'CosNaming_NameComponent'{id="id3", kind="kind3"}], + String4 = "id1.kind1/i\\.d\\.2.kind2/id3.kind3", + Name5 = [#'CosNaming_NameComponent'{id="id1", kind=""}, + #'CosNaming_NameComponent'{id="i/d/2", kind="kind2"}, + #'CosNaming_NameComponent'{id="id3", kind=""}], + String5 = "id1/i\\/d\\/2.kind2/id3", + + BadString1 = "id1./id2/id3", + BadString2 = "id1//id3", + + ?match(String1, 'CosNaming_NamingContextExt':to_string(NS, Name1)), + ?match(String2, 'CosNaming_NamingContextExt':to_string(NS, Name2)), + ?match(String3, 'CosNaming_NamingContextExt':to_string(NS, Name3)), + ?match(String4, 'CosNaming_NamingContextExt':to_string(NS, Name4)), + ?match(String5, 'CosNaming_NamingContextExt':to_string(NS, Name5)), + ?match(Name1, 'CosNaming_NamingContextExt':to_name(NS, String1)), + ?match(Name2, 'CosNaming_NamingContextExt':to_name(NS, String2)), + ?match(Name3, 'CosNaming_NamingContextExt':to_name(NS, String3)), + ?match(Name4, 'CosNaming_NamingContextExt':to_name(NS, String4)), + ?match(Name5, 'CosNaming_NamingContextExt':to_name(NS, String5)), + + ?match({'EXCEPTION', {'CosNaming_NamingContext_InvalidName',_}}, + 'CosNaming_NamingContextExt':to_name(NS, BadString1)), + ?match({'EXCEPTION', {'CosNaming_NamingContext_InvalidName',_}}, + 'CosNaming_NamingContextExt':to_name(NS, BadString2)), + + %% Create a test context. + ?line Tc = ?match({_,pseudo,_, _,_, _}, + 'CosNaming_NamingContext':bind_new_context(NS, + [#'CosNaming_NameComponent'{id="testcontext", + kind=""}])), + ?match(ok, 'CosNaming_NamingContext':bind(Tc, [#'CosNaming_NameComponent' + {id="hej", + kind=""}], NS)), + + ?match(NS, 'CosNaming_NamingContextExt':resolve_str(Tc, "hej")), + + ?match("corbaloc:rir:", 'CosNaming_NamingContextExt':to_url(Tc, "rir:", "")), + ?match("corbaname:rir:/NameService#org/erlang/", + 'CosNaming_NamingContextExt':to_url(Tc, "rir:/NameService", "org/erlang/")), + ?match("corbaloc::1.1@555%3cxyz.com:9999/Dev/NameService", + 'CosNaming_NamingContextExt':to_url(Tc, ":1.1@555\\<xyz.com:9999/Dev/NameService", "")), + + %% Bad port + ?match({'EXCEPTION', {'CosNaming_NamingContextExt_InvalidAddress',_}}, + 'CosNaming_NamingContextExt':to_url(Tc, ":[email protected]:99a9/", "")), + %% BAd IIOP-version + ?match({'EXCEPTION', {'CosNaming_NamingContextExt_InvalidAddress',_}}, + 'CosNaming_NamingContextExt':to_url(Tc, ":[email protected]:99a9/", "")), + %% Bad IIOP-version + ?match({'EXCEPTION', {'CosNaming_NamingContextExt_InvalidAddress',_}}, + 'CosNaming_NamingContextExt':to_url(Tc, ":@555xyz.com:99a9/", "")), + %% Bad protocol + ?match({'EXCEPTION', {'CosNaming_NamingContextExt_InvalidAddress',_}}, + 'CosNaming_NamingContextExt':to_url(Tc, "iop:@555xyz.com:99a9/", "")), + %% Unsupported protocol + ?match({'EXCEPTION', {'CosNaming_NamingContextExt_InvalidAddress',_}}, + 'CosNaming_NamingContextExt':to_url(Tc, "atm:@555xyz.com:9999/", "")), + %% Bad Name + ?match({'EXCEPTION', {'CosNaming_NamingContext_InvalidName',_}}, + 'CosNaming_NamingContextExt':to_url(Tc, ":555xyz.com:9999/", "id1./id2.kind2")), + + ok. + + diff --git a/lib/orber/test/orber.spec b/lib/orber/test/orber.spec new file mode 100644 index 0000000000..9d19ea7fc1 --- /dev/null +++ b/lib/orber/test/orber.spec @@ -0,0 +1,19 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +{topcase, {dir, "../orber_test"}}. diff --git a/lib/orber/test/orber_SUITE.erl b/lib/orber/test/orber_SUITE.erl new file mode 100644 index 0000000000..f54da02c0e --- /dev/null +++ b/lib/orber/test/orber_SUITE.erl @@ -0,0 +1,179 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +-module(orber_SUITE). +-include("test_server.hrl"). + + +-define(default_timeout, ?t:minutes(15)). +-define(application, orber). + +% Test server specific exports +-export([all/1]). +-export([init_per_testcase/2, fin_per_testcase/2]). + +% Test cases must be exported. +-export([app_test/1, undefined_functions/1, install_load_order/1, + install_local_content/1]). + +%% +%% all/1 +%% +all(doc) -> + []; +all(suite) -> + [app_test, undefined_functions, + install_load_order, install_local_content]. + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog=?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +% +% Test cases starts here. +% +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ?line ok=?t:app_test(orber), + ok. + +%% Install Orber using the load_order option. +install_load_order(suite) -> + []; +install_load_order(doc) -> + []; +install_load_order(_Config) -> + orber:jump_stop(), + case catch install_load_order2() of + ok -> + orber:jump_stop(); + What -> + orber:jump_stop(), + exit(What) + end. + +install_load_order2() -> + application:load(orber), + mnesia:start(), + corba:orb_init([{iiop_port, 0}]), + orber:install([node()], [{ifr_storage_type, ram_copies}, + {load_order, 10}]), + orber:start(), + [H|_] = orber:get_tables(), + 10 = mnesia:table_info(H, load_order), + ok. + +%% Install Orber using the local_content option. +install_local_content(suite) -> + []; +install_local_content(doc) -> + []; +install_local_content(_Config) -> + orber:jump_stop(), + case catch install_local_content2() of + ok -> + orber:jump_stop(); + What -> + orber:jump_stop(), + exit(What) + end. + +install_local_content2() -> + application:load(orber), + mnesia:start(), + corba:orb_init([{iiop_port, 0}]), + orber:install([node()], [{ifr_storage_type, ram_copies}, + {local_content, true}]), + orber:start(), + [H|_] = orber:get_tables(), + true = mnesia:table_info(H, local_content), + ok. + + + +%% Check for undefined functions +undefined_functions(suite) -> + []; +undefined_functions(doc) -> + []; +undefined_functions(_Config) -> + App = orber, + Root = code:root_dir(), + LibDir = code:lib_dir(App), + EbinDir = filename:join([LibDir,"ebin"]), + AppFilePath = filename:join([LibDir,"ebin", "orber.app"]), + {ok, [{application,orber,AppFile}]} = file:consult(AppFilePath), + io:format("Using ~p~n~p~n", [AppFilePath, AppFile]), + Mods = key1search(modules, AppFile), + XRefTestName = undef_funcs_make_name(App, xref_test_name), + {ok, XRef} = xref:start(XRefTestName), + ok = xref:set_default(XRef, + [{verbose,false},{warnings,false}]), + XRefName = undef_funcs_make_name(App, xref_name), + {ok, XRefName} = xref:add_release(XRef, Root, {name,XRefName}), + {ok, App} = xref:replace_application(XRef, App, EbinDir), + {ok, Undefs} = xref:analyze(XRef, undefined_function_calls), + xref:stop(XRef), + analyze_undefined_function_calls(Undefs, Mods, []). + +analyze_undefined_function_calls([], _, []) -> + ok; +analyze_undefined_function_calls([], _, AppUndefs) -> + exit({suite_failed, {undefined_function_calls, AppUndefs}}); +analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs], + AppModules, AppUndefs) -> + %% Check that this module is our's + case lists:member(Mod,AppModules) of + true -> + {Calling,Called} = AppUndef, + {Mod1,Func1,Ar1} = Calling, + {Mod2,Func2,Ar2} = Called, + io:format("undefined function call: " + "~n ~w:~w/~w calls ~w:~w/~w~n", + [Mod1,Func1,Ar1,Mod2,Func2,Ar2]), + analyze_undefined_function_calls(Undefs, AppModules, + [AppUndef|AppUndefs]); + false -> + io:format("dropping ~p~n", [Mod]), + analyze_undefined_function_calls(Undefs, AppModules, AppUndefs) + end. + +%% This function is used simply to avoid cut-and-paste errors later... +undef_funcs_make_name(App, PostFix) -> + list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)). + +key1search(Key, L) -> + case lists:keysearch(Key, 1, L) of + false -> + fail({not_found, Key, L}); + {value, {Key, Value}} -> + Value + end. + +fail(Reason) -> + exit({suite_failed, Reason}). + + + diff --git a/lib/orber/test/orber_acl_SUITE.erl b/lib/orber/test/orber_acl_SUITE.erl new file mode 100644 index 0000000000..2c2a768af2 --- /dev/null +++ b/lib/orber/test/orber_acl_SUITE.erl @@ -0,0 +1,303 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for the ACL functions +%% +%%----------------------------------------------------------------- +-module(orber_acl_SUITE). + +-include("test_server.hrl"). + +-define(default_timeout, ?t:minutes(5)). + +-define(match(ExpectedRes,Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Testing API for ACL (Access Control List)"]; +all(suite) -> + [ipv4_verify, ipv4_range, ipv4_interfaces, ipv4_bm, + ipv6_verify, ipv6_range, ipv6_interfaces, ipv6_bm]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_all(Config) -> + if + list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + Config. + + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case : +%% Description: +%%----------------------------------------------------------------- +ipv4_verify(doc) -> ["Testing IPv4 Verify Operation."]; +ipv4_verify(suite) -> []; +ipv4_verify(_) -> + ?match(true, orber_acl:verify("192.168.64.148", "192.168.64.0/17", inet)), + ?match({false,"192.168.128.0","192.168.255.255"}, + orber_acl:verify("192.168.64.148", "192.168.255.0/17", inet)), + ?match(true, orber_acl:verify("192.168.255.148", "192.168.128.0/17", inet)), + ?match(true, orber_acl:verify("192.168.128.148", "192.168.128.0/17", inet)), + ?match(true, orber_acl:verify("192.168.255.255", "192.168.128.0/16", inet)), + ?match({false,"192.168.0.0","192.168.255.255"}, + orber_acl:verify("192.169.255.255", "192.168.128.0/16", inet)), + ?match(true, orber_acl:verify("192.168.128.255", "192.168.128.0/24", inet)), + ?match({false,"192.168.128.0","192.168.128.255"}, + orber_acl:verify("192.168.255.255", "192.168.128.0/24", inet)), + ?match({false,"192.168.128.0","192.168.128.127"}, + orber_acl:verify("192.168.128.255", "192.168.128.0/25", inet)), + ?match(true, orber_acl:verify("192.168.128.255", "192.168.128.128/25", inet)), + ?match(true, orber_acl:verify("192.168.128.128", "192.168.128.128/32", inet)), + ?match({false,"192.168.128.128.","192.168.128.128."}, + orber_acl:verify("192.168.128.255", "192.168.128.128/32", inet)), + ?match(true, orber_acl:verify("192.168.128.128", "192.168.128.128", inet)), + ?match({false,"192.168.128.128.","192.168.128.128."}, + orber_acl:verify("192.168.128.255", "192.168.128.128", inet)), + ?match(true, orber_acl:verify("192.168.128.255", "192.168.128.128/7", inet)), + ok. + +%%----------------------------------------------------------------- +%% Test Case : +%% Description: +%%----------------------------------------------------------------- +ipv4_range(doc) -> ["Testing IPv4 Range Operation."]; +ipv4_range(suite) -> []; +ipv4_range(_) -> + ?match({ok,"192.168.0.0", "192.168.127.255"}, + orber_acl:range("192.168.64.0/17")), + ?match({ok, "192.168.128.0", "192.168.255.255"}, + orber_acl:range("192.168.255.0/17")), + ?match({ok,"192.168.128.0","192.168.255.255"}, + orber_acl:range("192.168.128.0/17")), + ?match({ok,"192.168.0.0","192.168.255.255"}, + orber_acl:range("192.168.128.0/16")), + ?match({ok,"192.168.128.0","192.168.128.255"}, + orber_acl:range("192.168.128.0/24")), + ?match({ok,"192.168.128.0","192.168.128.127"}, + orber_acl:range("192.168.128.0/25")), + ?match({ok,"192.168.128.128","192.168.128.255"}, + orber_acl:range("192.168.128.128/25")), + ?match({ok,"192.168.128.128.","192.168.128.128."}, + orber_acl:range("192.168.128.128/32")), + ?match({ok,"192.168.128.128.","192.168.128.128."}, + orber_acl:range("192.168.128.128")), + ?match({ok,"192.0.0.0","193.255.255.255"}, + orber_acl:range("192.168.128.128/7")), + ok. + +%%----------------------------------------------------------------- +%% Test Case : +%% Description: +%%----------------------------------------------------------------- +ipv4_interfaces(doc) -> ["Testing IPv4 Interfaces Operation."]; +ipv4_interfaces(suite) -> []; +ipv4_interfaces(_) -> + ?match({ok, _}, + orber_acl:init_acl([{tcp_in, "192.168.128.0/18", ["10.1.1.1"]}, + {tcp_in, "192.167.64.0/18#4001/5001", ["10.1.1.2"]}, + {tcp_in, "192.166.192.0/18"}], inet)), + {ok, IPTuple1} = ?match({ok, _}, inet:getaddr("192.168.128.0", inet)), + ?match({true, ["10.1.1.1"], 0}, orber_acl:match(IPTuple1, tcp_in, true)), + ?match({false, [], 0}, orber_acl:match(IPTuple1, tcp_out, true)), + {ok, IPTuple2} = ?match({ok, _}, inet:getaddr("192.167.64.0", inet)), + ?match({true, ["10.1.1.2"], {4001,5001}}, orber_acl:match(IPTuple2, tcp_in, true)), + ?match({false, [], 0}, orber_acl:match(IPTuple2, tcp_out, true)), + {ok, IPTuple3} = ?match({ok, _}, inet:getaddr("192.166.192.0", inet)), + ?match({true, [], 0}, orber_acl:match(IPTuple3, tcp_in, true)), + ?match(false, orber_acl:match(IPTuple3, tcp_out)), + ?match(ok, orber_acl:clear_acl()), + ok. + +%%----------------------------------------------------------------- +%% Test Case : +%% Description: +%%----------------------------------------------------------------- +ipv4_bm(doc) -> ["Benchmarking runtime critical IPv4 Operations."]; +ipv4_bm(suite) -> []; +ipv4_bm(_) -> + ?match({ok, _, _, _}, bm2([{tcp_in, "192.168.64.0/17"}], inet, "192.168.64.148")), + ok. +%%----------------------------------------------------------------- +%% Test Case : +%% Description: +%%----------------------------------------------------------------- +ipv6_verify(doc) -> ["Testing IPv6 Verify Operation."]; +ipv6_verify(suite) -> []; +ipv6_verify(_) -> + case orber_test_lib:version_ok() of + true -> + ?match(true, orber_acl:verify("2002:C0A8:0:0:0:0:0:0", "2002:C0A8::/48", inet6)), + ?match(true, orber_acl:verify("2002:C0A8:0:FFFF:FFFF:FFFF:FFFF:FFFF", "2002:C0A8::/48", inet6)), + ?match({false,"2002:C0A8:0:0:0:0:0:0", "2002:C0A8:0:FFFF:FFFF:FFFF:FFFF:FFFF"}, + orber_acl:verify("2002:C0A8:1:FFFF:FFFF:FFFF:FFFF:FFFF", "2002:C0A8::/48", inet6)), + ?match(true, orber_acl:verify("2002:C0A8:1:FFFF:FFFF:FFFF:FFFF:FFFF", "2002:C0A8::/47", inet6)), + ?match({false,"2002:C0A8:0:0:0:0:0:0", "2002:C0A8:1:FFFF:FFFF:FFFF:FFFF:FFFF"}, + orber_acl:verify("2002:C0A8:2:FFFF:FFFF:FFFF:FFFF:FFFF", "2002:C0A8::/47", inet6)), + ok; + Reason -> + Reason + end. + +%%----------------------------------------------------------------- +%% Test Case : +%% Description: +%%----------------------------------------------------------------- +ipv6_range(doc) -> ["Testing IPv6 Range Operation."]; +ipv6_range(suite) -> []; +ipv6_range(_) -> + case orber_test_lib:version_ok() of + true -> + ?match({ok,"2002:C0A8:0:0:0:0:0:0", "2002:C0A8:0:FFFF:FFFF:FFFF:FFFF:FFFF"}, + orber_acl:range("2002:C0A8::/48", inet6)), + ?match({ok,"2002:C0A8:0:0:0:0:0:0", "2002:C0A8:1:FFFF:FFFF:FFFF:FFFF:FFFF"}, + orber_acl:range("2002:C0A8::/47", inet6)), + ok; + Reason -> + Reason + end. + +%%----------------------------------------------------------------- +%% Test Case : +%% Description: +%%----------------------------------------------------------------- +ipv6_interfaces(doc) -> ["Testing IPv6 Interfaces Operation."]; +ipv6_interfaces(suite) -> []; +ipv6_interfaces(_) -> + case orber_test_lib:version_ok() of + true -> + ?match({ok, _}, orber_acl:init_acl([{tcp_in, "2002:C0A8::/49", ["0:0:0:0:0:0:10.1.1.1"]}], inet6)), + {ok, IPTuple1} = ?match({ok, _}, inet:getaddr("2002:C0A8:0:7FFF:FFFF:FFFF:FFFF:FFFF", inet6)), + ?match({true, ["0:0:0:0:0:0:10.1.1.1"], 0}, orber_acl:match(IPTuple1, tcp_in, true)), + ?match(false, orber_acl:match(IPTuple1, tcp_out)), + ?match(ok, orber_acl:clear_acl()), + ok; + Reason -> + Reason + end. + +%%----------------------------------------------------------------- +%% Test Case : +%% Description: +%%----------------------------------------------------------------- +ipv6_bm(doc) -> ["Benchmarking runtime critical IPv6 Operations."]; +ipv6_bm(suite) -> []; +ipv6_bm(_) -> + case orber_test_lib:version_ok() of + true -> + ?match({ok, _, _, _}, bm2([{tcp_in, "2002:C0A8::/48"}], inet6, "2002:C0A8:0:0:0:0:0:0")), + ok; + Reason -> + Reason + end. + +%%----------------------------------------------------------------- +%% Local Functions +%%----------------------------------------------------------------- +-define(NO_OF_TIMES, 1000). + +bm2(Filters, Family, Ip) -> + {ok, IPTuple} = inet:getaddr(Ip, Family), + orber_acl:init_acl(Filters, Family), + TimeBefore1 = erlang:now(), + bm_loop(IPTuple, ?NO_OF_TIMES), + TimeAfter1 = erlang:now(), + orber_acl:clear_acl(), + Time1 = computeTime(TimeBefore1, TimeAfter1), + orber_acl:init_acl(Filters, Family), + TimeBefore2 = erlang:now(), + bm_loop2(Ip, ?NO_OF_TIMES, Family), + TimeAfter2 = erlang:now(), + orber_acl:clear_acl(), + Time2 = computeTime(TimeBefore2, TimeAfter2), + orber_acl:init_acl(Filters, Family), + TimeBefore3 = erlang:now(), + bm_loop2(IPTuple, ?NO_OF_TIMES, Family), + TimeAfter3 = erlang:now(), + orber_acl:clear_acl(), + Time3 = computeTime(TimeBefore3, TimeAfter3), + {ok, round(?NO_OF_TIMES/Time1), round(?NO_OF_TIMES/Time2), round(?NO_OF_TIMES/Time3)}. + + +bm_loop(_Ip, 0) -> + ok; +bm_loop(Ip, N) -> + true = orber_acl:match(Ip, tcp_in), + bm_loop(Ip, N-1). + +bm_loop2(_Ip, 0, _Family) -> + ok; +bm_loop2(Ip, N, Family) -> + {ok, IPTuple} = inet:getaddr(Ip, Family), + true = orber_acl:match(IPTuple, tcp_in), + bm_loop2(Ip, N-1, Family). + +computeTime({_MegaSecb, Secb, MicroSecb}, {_MegaSeca, Seca, MicroSeca}) -> + (Seca - Secb) + ((MicroSeca - MicroSecb) / 1000000). + + +%%----------------------------------------------------------------- +%% END OF MODULE +%%----------------------------------------------------------------- diff --git a/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl b/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl new file mode 100644 index 0000000000..3ac0cb7921 --- /dev/null +++ b/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl @@ -0,0 +1,280 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(orber_firewall_ipv4_in_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include_lib("orber/src/ifr_objects.hrl"). +-include("idl_output/orber_test_server.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl"). + +-define(default_timeout, ?t:minutes(15)). + +-define(match(ExpectedRes,Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, + init_per_testcase/2, fin_per_testcase/2, + deny_port_api/1, deny_port_range_api/1, deny_host_api/1, + deny_peerhost_api/1, allow_port_range_api/1, + allow_host_api/1, allow_peerhost_api/1, check_address_api/1]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for orber's firewall functionallity."]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +%% NOTE - the fragment test cases must bu first since we explicitly set a request +%% id. Otherwise, the request-id counter would be increased and we cannot know +%% what it is. +cases() -> + [deny_port_api, deny_port_range_api, deny_host_api, deny_peerhost_api, + allow_port_range_api, allow_host_api, allow_peerhost_api, check_address_api]. + + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + if + is_list(Config) -> + orber:jump_start([{iiop_port, 0}, + {iiop_out_ports, {5980, 6000}}]), + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + orber:jump_stop(), + Config. + +%%----------------------------------------------------------------- +%% Incomming connections - Deny +%%----------------------------------------------------------------- +deny_port_api(doc) -> ["Deny Access due to invalid local port"]; +deny_port_api(suite) -> []; +deny_port_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING}, + {iiop_acl, [{tcp_in, IP++"/32#7000"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +deny_port_range_api(doc) -> ["Deny Access due to invalid local port range"]; +deny_port_range_api(suite) -> []; +deny_port_range_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING}, + {iiop_acl, [{tcp_in, IP++"/32#7000/8000"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + + +deny_host_api(doc) -> ["Deny Access due to invalid host"]; +deny_host_api(suite) -> []; +deny_host_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING}, + {iiop_acl, [{tcp_in, "123.123.123.123/32"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +deny_peerhost_api(doc) -> ["Deny Access due to invalid peerhost"]; +deny_peerhost_api(suite) -> []; +deny_peerhost_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING}, + {iiop_acl, [{tcp_in, IP++"/32", ["123.123.123.123"]}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +%%----------------------------------------------------------------- +%% Incomming connections - Allow +%%----------------------------------------------------------------- +allow_port_range_api(doc) -> ["Allow Access due to valid local port range"]; +allow_port_range_api(suite) -> []; +allow_port_range_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING}, + {iiop_acl, [{tcp_in, IP++"/32#5980/6000"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match(false, corba_object:not_existent(IOR)), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + + +allow_host_api(doc) -> ["Allow Access due to valid host"]; +allow_host_api(suite) -> []; +allow_host_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING}, + {iiop_acl, [{tcp_in, IP++"/32"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match(false, corba_object:not_existent(IOR)), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +allow_peerhost_api(doc) -> ["Allow Access due to valid peerhost"]; +allow_peerhost_api(suite) -> []; +allow_peerhost_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING}, + {iiop_acl, [{tcp_in, IP++"/32", [IP]}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService", + [#'IOP_ServiceContext' + {context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, IP}}])), + ?match(false, corba_object:not_existent(IOR, + [#'IOP_ServiceContext' + {context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, IP}}])), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +%%----------------------------------------------------------------- +%% Test corbaloc strings +%%----------------------------------------------------------------- +check_address_api(doc) -> ["Test corbaloc strings"]; +check_address_api(suite) -> []; +check_address_api(_Config) -> + ?match({[[iiop,{1,0},"10.0.0.1",2809]],"NameService"}, + orber_cosnaming_utils:addresses(":10.0.0.1/NameService")), + ?match({[[iiop,{1,0},"10.0.0.1",2809]],[]}, + orber_cosnaming_utils:addresses(":10.0.0.1")), + ?match({[[iiop,{1,2},"10.0.0.1",2809]],"NameService"}, + orber_cosnaming_utils:addresses(":[email protected]/NameService")), + ?match({[[iiop,{1,0},"10.0.0.1",4001]],"NameService"}, + orber_cosnaming_utils:addresses(":10.0.0.1:4001/NameService")), + ?match({[[iiop,{1,1},"10.0.0.1",4001]],"NameService"}, + orber_cosnaming_utils:addresses(":[email protected]:4001/NameService")), + ?match({[[iiop,{1,1},"10.0.0.1",4001]],[]}, + orber_cosnaming_utils:addresses(":[email protected]:4001")), + ?match({[[iiop,{1,1},"10.0.0.1",4001]],[]}, + orber_cosnaming_utils:addresses("iiop:[email protected]:4001")), + ?match({[[iiop,{1,1},"10.0.0.1",4001]],[]}, + orber_cosnaming_utils:addresses("iiop:[email protected]:4001/")), + + ?match({[[iiop,{1,1},"myhost",4001]],[]}, + orber_cosnaming_utils:addresses("iiop:1.1@myhost:4001")), + ?match({[[iiop,{1,1},"myhost.full.name",4001]],"NameService"}, + orber_cosnaming_utils:addresses("iiop:[email protected]:4001/NameService")), + ?match({[[iiop,{1,1},"myhost",4001], + [iiop,{1,1},"myhost.full.name",2809]],"NameService"}, + orber_cosnaming_utils:addresses("iiop:1.1@myhost:4001,iiop:[email protected]/NameService")), + + ?match({[[iiop,{1,1},"123.12.23.2",4001], + [iiop,{1,1},"10.0.0.1",4001]], "NameService"}, + orber_cosnaming_utils:addresses(":[email protected]:4001,:[email protected]:4001/NameService")), + ?match({[[iiop,{1,1},"123.12.23.2",4001], + [iiop,{1,1},"10.0.0.1",4001]], []}, + orber_cosnaming_utils:addresses(":[email protected]:4001,:[email protected]:4001")), + ?match({[[iiop,{1,0},"123.12.23.2",4001], + [iiop,{1,1},"10.0.0.1",4001]], "NameService"}, + orber_cosnaming_utils:addresses(":123.12.23.2:4001,:[email protected]:4001/NameService")), + ?match({[[iiop,{1,1},"123.12.23.2",4001], + [iiop,{1,0},"10.0.0.1",4001]], "NameService"}, + orber_cosnaming_utils:addresses(":[email protected]:4001,:10.0.0.1:4001/NameService")), + ?match({[[iiop,{1,1},"123.12.23.2",2809], + [iiop,{1,1},"10.0.0.1",4001]], "NameService"}, + orber_cosnaming_utils:addresses(":[email protected],:[email protected]:4001/NameService")), + ?match({[[iiop,{1,1},"123.12.23.2",4001], + [iiop,{1,1},"10.0.0.1",2809]], "NameService"}, + orber_cosnaming_utils:addresses(":[email protected]:4001,:[email protected]/NameService")), + ?match({[[iiop,{1,0},"123.12.23.2",2809], + [iiop,{1,0},"10.0.0.1",2809]], "NameService"}, + orber_cosnaming_utils:addresses(":123.12.23.2,:10.0.0.1/NameService")), + ?match({[[iiop,{1,0},"123.12.23.2",2809], + [iiop,{1,0},"10.0.0.1",2809]], []}, + orber_cosnaming_utils:addresses(":123.12.23.2,:10.0.0.1/")), + ?match({[[iiop,{1,0},"123.12.23.2",2809], + [iiop,{1,0},"10.0.0.1",2809]], []}, + orber_cosnaming_utils:addresses("iiop:123.12.23.2,:10.0.0.1/")), + + [IP] = ?match([_], orber:host()), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_INCOMING}, + {iiop_acl, [{tcp_in, IP++"/32"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + + ok. + diff --git a/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl b/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl new file mode 100644 index 0000000000..193fc72f7c --- /dev/null +++ b/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl @@ -0,0 +1,224 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(orber_firewall_ipv4_out_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include_lib("orber/src/ifr_objects.hrl"). +-include("idl_output/orber_test_server.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl"). + +-define(default_timeout, ?t:minutes(15)). + +-define(match(ExpectedRes,Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, + init_per_testcase/2, fin_per_testcase/2, + deny_port_api/1, deny_port_range_api/1, deny_host_api/1, + allow_port_api/1, allow_port_range_api/1, allow_host_api/1, + local_interface_api/1]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for orber's firewall functionallity."]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +%% NOTE - the fragment test cases must bu first since we explicitly set a request +%% id. Otherwise, the request-id counter would be increased and we cannot know +%% what it is. +cases() -> + [deny_port_api, deny_port_range_api, deny_host_api, + allow_port_api, allow_port_range_api, allow_host_api, + local_interface_api]. + + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + if + is_list(Config) -> + orber:jump_start([{iiop_port, 0}, + {iiop_out_ports, {5980, 6000}}]), + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + orber:jump_stop(), + Config. + +%%----------------------------------------------------------------- +%% Incomming connections - Deny +%%----------------------------------------------------------------- +deny_port_api(doc) -> ["Deny Access due to invalid local port"]; +deny_port_api(suite) -> []; +deny_port_api(_Config) -> + [IP] = ?match([_], orber:host()), + ServerPort = orber:iiop_port(), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING}, + {iiop_acl, [{tcp_out, IP++"/32#" ++ integer_to_list(ServerPort+10)}]}])), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])), +% ?line catch orber_test_lib:destroy_node(ClientNode, timeout), + ok. + +deny_port_range_api(doc) -> ["Deny Access due to invalid local port range"]; +deny_port_range_api(suite) -> []; +deny_port_range_api(_Config) -> + [IP] = ?match([_], orber:host()), + ServerPort = orber:iiop_port(), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING}, + {iiop_acl, [{tcp_out, IP++"/32#"++integer_to_list(ServerPort+100)++ "/" ++ integer_to_list(ServerPort+120)}]}])), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])), +% ?line catch orber_test_lib:destroy_node(ClientNode, timeout), + ok. + + +deny_host_api(doc) -> ["Deny Access due to invalid host"]; +deny_host_api(suite) -> []; +deny_host_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING}, + {iiop_acl, [{tcp_out, "123.123.123.123/32"}]}])), + ServerPort = orber:iiop_port(), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])), +% ?line catch orber_test_lib:destroy_node(ClientNode, timeout), + ok. + +%%----------------------------------------------------------------- +%% Incomming connections - Allow +%%----------------------------------------------------------------- +allow_port_api(doc) -> ["Allow Access due to valid local port range"]; +allow_port_api(suite) -> []; +allow_port_api(_Config) -> + [IP] = ?match([_], orber:host()), + ServerPort = orber:iiop_port(), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING}, + {iiop_acl, [{tcp_out, IP++"/32#"++integer_to_list(ServerPort)}]}])), + IOR = + ?match({'IOP_IOR',_,_}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])), + ?match(false, + orber_test_lib:remote_apply(ClientNode, corba_object, not_existent, [IOR])), +% ?line catch orber_test_lib:destroy_node(ClientNode, timeout), + ok. + +allow_port_range_api(doc) -> ["Allow Access due to valid local port range"]; +allow_port_range_api(suite) -> []; +allow_port_range_api(_Config) -> + [IP] = ?match([_], orber:host()), + ServerPort = orber:iiop_port(), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING}, + {iiop_acl, [{tcp_out, IP++"/32#" ++ integer_to_list(ServerPort-10) ++ "/" ++ integer_to_list(ServerPort+10)}]}])), + IOR = + ?match({'IOP_IOR',_,_}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])), + ?match(false, + orber_test_lib:remote_apply(ClientNode, corba_object, not_existent, [IOR])), +% ?line catch orber_test_lib:destroy_node(ClientNode, timeout), + ok. + + +allow_host_api(doc) -> ["Allow Access due to valid host"]; +allow_host_api(suite) -> []; +allow_host_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING}, + {iiop_acl, [{tcp_out, IP++"/32"}]}])), + ServerPort = orber:iiop_port(), + IOR = + ?match({'IOP_IOR',_,_}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])), + ?match(false, + orber_test_lib:remote_apply(ClientNode, corba_object, not_existent, [IOR])), +% ?line catch orber_test_lib:destroy_node(ClientNode, timeout), + ok. + +local_interface_api(doc) -> ["Allow Access due to valid host via a spcific interface"]; +local_interface_api(suite) -> []; +local_interface_api(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{iiop_port, 0}, + {iiop_out_ports, {5980, 6000}}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_ACL_OUTGOING}, + {iiop_acl, [{tcp_out, IP, [Loopback]}]}])), + IOR = + ?match({'IOP_IOR',_,_}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])), + ?match(false, + orber_test_lib:remote_apply(ClientNode, corba_object, not_existent, [IOR])), +% ?line catch orber_test_lib:destroy_node(ClientNode, timeout), + ok. + diff --git a/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl b/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl new file mode 100644 index 0000000000..83f48cba0c --- /dev/null +++ b/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl @@ -0,0 +1,311 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(orber_firewall_ipv6_in_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include_lib("orber/src/ifr_objects.hrl"). +-include("idl_output/orber_test_server.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl"). + +-define(default_timeout, ?t:minutes(15)). + +-define(match(ExpectedRes,Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, + init_per_testcase/2, fin_per_testcase/2, + deny_port_api/1, deny_port_range_api/1, deny_host_api/1, + deny_peerhost_api/1, allow_port_range_api/1, + allow_host_api/1, allow_peerhost_api/1, check_address_api/1]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for orber's firewall functionallity."]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +%% NOTE - the fragment test cases must bu first since we explicitly set a request +%% id. Otherwise, the request-id counter would be increased and we cannot know +%% what it is. +cases() -> + [deny_port_api, deny_port_range_api, deny_host_api, deny_peerhost_api, + allow_port_range_api, allow_host_api, allow_peerhost_api, + check_address_api]. + + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + orber:jump_start([{iiop_port, 0}, + {iiop_out_ports, {5980, 6000}}, + {flags, ?ORB_ENV_USE_IPV6}]), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + orber:jump_stop(), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + case orber_test_lib:version_ok() of + true -> + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end; + Reason -> + Reason + end. + +finish_all(Config) -> + Config. + + +%%----------------------------------------------------------------- +%% Incomming connections - Deny +%%----------------------------------------------------------------- +deny_port_api(doc) -> ["Deny Access due to invalid local port"]; +deny_port_api(suite) -> []; +deny_port_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_INCOMING)}, + {iiop_acl, [{tcp_in, IP++"/128#7000"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")), + % ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +deny_port_range_api(doc) -> ["Deny Access due to invalid local port range"]; +deny_port_range_api(suite) -> []; +deny_port_range_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_INCOMING)}, + {iiop_acl, [{tcp_in, IP++"/128#7000/8000"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + + +deny_host_api(doc) -> ["Deny Access due to invalid host"]; +deny_host_api(suite) -> []; +deny_host_api(_Config) -> + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_INCOMING)}, + {iiop_acl, [{tcp_in, "0:0:0:0:0:0:10.1.1.1/128"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +deny_peerhost_api(doc) -> ["Deny Access due to invalid peer host"]; +deny_peerhost_api(suite) -> []; +deny_peerhost_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, + orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_INCOMING)}, + {iiop_acl, [{tcp_in, IP++"/128", ["0:0:0:0:0:0:10.1.1.1"]}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +%%----------------------------------------------------------------- +%% Incomming connections - Allow +%%----------------------------------------------------------------- +allow_port_range_api(doc) -> ["Allow Access due to valid local port range"]; +allow_port_range_api(suite) -> []; +allow_port_range_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_INCOMING)}, + {iiop_acl, [{tcp_in, IP++"/128#5980/6000"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")), + ?match(false, corba_object:not_existent(IOR)), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + + +allow_host_api(doc) -> ["Allow Access due to valid host"]; +allow_host_api(suite) -> []; +allow_host_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_INCOMING)}, + {iiop_acl, [{tcp_in, IP++"/128"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")), + ?match(false, corba_object:not_existent(IOR)), + +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +allow_peerhost_api(doc) -> ["Allow Access due to valid host"]; +allow_peerhost_api(suite) -> []; +allow_peerhost_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_INCOMING)}, + {iiop_acl, [{tcp_in, IP++"/128", [IP]}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService", + [#'IOP_ServiceContext' + {context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, IP}}])), + ?match(false, corba_object:not_existent(IOR, + [#'IOP_ServiceContext' + {context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, IP}}])), + +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +%%----------------------------------------------------------------- +%% Test corbaloc strings +%%----------------------------------------------------------------- +check_address_api(doc) -> ["Test corbaloc strings"]; +check_address_api(suite) -> []; +check_address_api(_Config) -> + ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]],"NameService"}, + orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:C02A:2A2A/NameService")), + ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]],[]}, + orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:C02A:2A2A")), + ?match({[[iiop,{1,2},"0:0:0:0:0:FFFF:C02A:2A2A",2809]],"NameService"}, + orber_cosnaming_utils:addresses(":1.2@0:0:0:0:0:FFFF:C02A:2A2A/NameService")), + ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],"NameService"}, + orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")), + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],"NameService"}, + orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")), + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],[]}, + orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001")), + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]],[]}, + orber_cosnaming_utils:addresses("iiop:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001")), + + ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809]],"NameService"}, + orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11/NameService")), + ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809]],[]}, + orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11")), + ?match({[[iiop,{1,2},"0:0:0:0:0:FFFF:10.11.11.11",2809]],"NameService"}, + orber_cosnaming_utils:addresses(":1.2@0:0:0:0:0:FFFF:10.11.11.11/NameService")), + ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",4001]],"NameService"}, + orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11:4001/NameService")), + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001]],"NameService"}, + orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001/NameService")), + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001]],[]}, + orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001/")), + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001]],[]}, + orber_cosnaming_utils:addresses("iiop:1.1@0:0:0:0:0:FFFF:10.11.11.11:4001/")), + + ?match({[[iiop,{1,1},"myhost",4001]],[]}, + orber_cosnaming_utils:addresses("iiop:1.1@myhost:4001")), + ?match({[[iiop,{1,1},"myhost.full.name",4001]],"NameService"}, + orber_cosnaming_utils:addresses("iiop:[email protected]:4001/NameService")), + ?match({[[iiop,{1,1},"myhost",4001], + [iiop,{1,1},"myhost.full.name",2809]],"NameService"}, + orber_cosnaming_utils:addresses("iiop:1.1@myhost:4001,iiop:[email protected]/NameService")), + + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001], + [iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"}, + orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")), + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001], + [iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], []}, + orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001")), + ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",4001], + [iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"}, + orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")), + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001], + [iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"}, + orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")), + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",2809], + [iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",4001]], "NameService"}, + orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11,:1.1@0:0:0:0:0:FFFF:C02A:2A2A:4001/NameService")), + ?match({[[iiop,{1,1},"0:0:0:0:0:FFFF:10.11.11.11",4001], + [iiop,{1,1},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], "NameService"}, + orber_cosnaming_utils:addresses(":1.1@0:0:0:0:0:FFFF:10.11.11.11:4001,:1.1@0:0:0:0:0:FFFF:C02A:2A2A/NameService")), + ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809], + [iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], "NameService"}, + orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11,:0:0:0:0:0:FFFF:C02A:2A2A/NameService")), + ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809], + [iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], []}, + orber_cosnaming_utils:addresses(":0:0:0:0:0:FFFF:10.11.11.11,:0:0:0:0:0:FFFF:C02A:2A2A/")), + ?match({[[iiop,{1,0},"0:0:0:0:0:FFFF:10.11.11.11",2809], + [iiop,{1,0},"0:0:0:0:0:FFFF:C02A:2A2A",2809]], []}, + orber_cosnaming_utils:addresses("iiop:0:0:0:0:0:FFFF:10.11.11.11,:0:0:0:0:0:FFFF:C02A:2A2A/")), + + [IP] = ?match([_], orber:host()), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_INCOMING)}, + {iiop_acl, [{tcp_in, IP++"/128"}]}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + ?match({'IOP_IOR',_,_}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + + diff --git a/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl b/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl new file mode 100644 index 0000000000..e1856b9a47 --- /dev/null +++ b/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl @@ -0,0 +1,231 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(orber_firewall_ipv6_out_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include_lib("orber/src/ifr_objects.hrl"). +-include("idl_output/orber_test_server.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl"). + +-define(default_timeout, ?t:minutes(15)). + +-define(match(ExpectedRes,Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, + init_per_testcase/2, fin_per_testcase/2, + deny_port_api/1, deny_port_range_api/1, deny_host_api/1, + allow_port_api/1, allow_port_range_api/1, allow_host_api/1, + local_interface_api/1]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for orber's firewall functionallity."]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +%% NOTE - the fragment test cases must bu first since we explicitly set a request +%% id. Otherwise, the request-id counter would be increased and we cannot know +%% what it is. +cases() -> + [deny_port_api, deny_port_range_api, deny_host_api, + allow_port_api, allow_port_range_api, allow_host_api, + local_interface_api]. + + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + orber:jump_start([{iiop_port, 0}, + {iiop_out_ports, {5980, 6000}}, + {flags, ?ORB_ENV_USE_IPV6}]), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + orber:jump_stop(), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + case orber_test_lib:version_ok() of + true -> + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end; + Reason -> + Reason + end. + +finish_all(Config) -> + Config. + + +%%----------------------------------------------------------------- +%% Incomming connections - Deny +%%----------------------------------------------------------------- +deny_port_api(doc) -> ["Deny Access due to invalid local port"]; +deny_port_api(suite) -> []; +deny_port_api(_Config) -> + [IP] = ?match([_], orber:host()), + ServerPort = orber:iiop_port(), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_OUTGOING)}, + {iiop_acl, [{tcp_out, IP++"/128#" ++ integer_to_list(ServerPort+10)}]}])), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + orber_test_lib:remote_apply(ServerNode, corba, string_to_object, + ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +deny_port_range_api(doc) -> ["Deny Access due to invalid local port range"]; +deny_port_range_api(suite) -> []; +deny_port_range_api(_Config) -> + [IP] = ?match([_], orber:host()), + ServerPort = orber:iiop_port(), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_OUTGOING)}, + {iiop_acl, [{tcp_out, IP++"/128#"++integer_to_list(ServerPort+100)++ "/" ++ integer_to_list(ServerPort+120)}]}])), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + orber_test_lib:remote_apply(ServerNode, corba, string_to_object, + ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + + +deny_host_api(doc) -> ["Deny Access due to invalid host"]; +deny_host_api(suite) -> []; +deny_host_api(_Config) -> + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_OUTGOING)}, + {iiop_acl, [{tcp_out, "0:0:0:0:0:0:10.1.1.1/128"}]}])), + ServerPort = orber:iiop_port(), + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + orber_test_lib:remote_apply(ServerNode, corba, string_to_object, + ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +%%----------------------------------------------------------------- +%% Incomming connections - Allow +%%----------------------------------------------------------------- +allow_port_api(doc) -> ["Allow Access due to valid local port"]; +allow_port_api(suite) -> []; +allow_port_api(_Config) -> + [IP] = ?match([_], orber:host()), + ServerPort = orber:iiop_port(), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_OUTGOING)}, + {iiop_acl, [{tcp_out, IP++"/128#" ++ integer_to_list(ServerPort)}]}])), + IOR = + ?match({'IOP_IOR',_,_}, + orber_test_lib:remote_apply(ServerNode, corba, string_to_object, + ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])), + ?match(false, + orber_test_lib:remote_apply(ServerNode, corba_object, not_existent, [IOR])), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +allow_port_range_api(doc) -> ["Allow Access due to valid local port range"]; +allow_port_range_api(suite) -> []; +allow_port_range_api(_Config) -> + [IP] = ?match([_], orber:host()), + ServerPort = orber:iiop_port(), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_OUTGOING)}, + {iiop_acl, [{tcp_out, IP++"/128#" ++ integer_to_list(ServerPort-10) ++ "/" ++ integer_to_list(ServerPort+10)}]}])), + IOR = + ?match({'IOP_IOR',_,_}, + orber_test_lib:remote_apply(ServerNode, corba, string_to_object, + ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])), + ?match(false, + orber_test_lib:remote_apply(ServerNode, corba_object, not_existent, [IOR])), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + + +allow_host_api(doc) -> ["Allow Access due to valid host"]; +allow_host_api(suite) -> []; +allow_host_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_OUTGOING)}, + {iiop_acl, [{tcp_out, IP}]}])), + ServerPort = orber:iiop_port(), + IOR = + ?match({'IOP_IOR',_,_}, + orber_test_lib:remote_apply(ServerNode, corba, string_to_object, + ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])), + ?match(false, + orber_test_lib:remote_apply(ServerNode, corba_object, not_existent, [IOR])), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + +local_interface_api(doc) -> ["Allow Access due to valid host via a spcific interface"]; +local_interface_api(suite) -> []; +local_interface_api(_Config) -> + [IP] = ?match([_], orber:host()), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + ?ORB_ENV_USE_ACL_OUTGOING)}, + {iiop_acl, [{tcp_out, IP, [IP]}]}])), + ServerPort = orber:iiop_port(), + IOR = + ?match({'IOP_IOR',_,_}, + orber_test_lib:remote_apply(ServerNode, corba, string_to_object, + ["corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService"])), + ?match(false, + orber_test_lib:remote_apply(ServerNode, corba_object, not_existent, [IOR])), +% ?line catch orber_test_lib:destroy_node(ServerNode, timeout), + ok. + diff --git a/lib/orber/test/orber_nat_SUITE.erl b/lib/orber/test/orber_nat_SUITE.erl new file mode 100644 index 0000000000..5b295dd1aa --- /dev/null +++ b/lib/orber/test/orber_nat_SUITE.erl @@ -0,0 +1,372 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2006-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(orber_nat_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include_lib("orber/src/ifr_objects.hrl"). +-include("idl_output/orber_test_server.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming_NamingContext.hrl"). + + +-define(default_timeout, ?t:minutes(15)). + +-define(match(ExpectedRes,Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, cases/0, init_all/1, finish_all/1, + init_per_testcase/2, fin_per_testcase/2, + nat_ip_address/1, nat_ip_address_multiple/1, + nat_ip_address_local/1, nat_ip_address_local_local/1, + nat_iiop_port/1, nat_iiop_port_local/1, + nat_iiop_port_local_local/1, nat_iiop_ssl_port/1, + nat_iiop_ssl_port_local/1]). + + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for multi orber interfaces", + "This suite test intra-ORB communication. There are three scenarios:", + "* No security at all (multi_orber_api)", + "* Two secure orbs using ssl (ssl_multi_orb_api)", + "* One secure and one orb with no security. (ssl_multi_orb_api)"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [ + nat_ip_address, + nat_ip_address_multiple, + nat_ip_address_local, + nat_iiop_port, + nat_iiop_port_local, + nat_ip_address_local_local, + nat_iiop_port_local_local, + nat_iiop_ssl_port, + nat_iiop_ssl_port_local + ]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + Dog=test_server:timetrap(?default_timeout), + orber:jump_start([{iiop_port, 0}, + {flags, 0}]), + oe_orber_test_server:oe_register(), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + oe_orber_test_server:oe_unregister(), + orber:jump_stop(), + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + Config. + +%%----------------------------------------------------------------- +%% API tests for NAT +%%----------------------------------------------------------------- + +nat_ip_address(doc) -> ["This case test if the server ORB use the correct", + "interface when exporting IOR:s"]; +nat_ip_address(suite) -> []; +nat_ip_address(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT}, + {nat_ip_address, Loopback}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR)), + ok. + +nat_ip_address_multiple(doc) -> ["This case test if the server ORB use the correct", + "interface when exporting IOR:s"]; +nat_ip_address_multiple(suite) -> []; +nat_ip_address_multiple(_Config) -> + IP = orber_test_lib:get_host(), + + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT}, + {nat_ip_address, {multiple, ["10.0.0.1"]}}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR)), + ok. + +nat_ip_address_local(doc) -> ["This case test if the server ORB use the correct", + "interface when exporting IOR:s"]; +nat_ip_address_local(suite) -> []; +nat_ip_address_local(_Config) -> + IP = orber_test_lib:get_host(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT}, + {nat_ip_address, {local, "10.0.0.1", [{IP, "127.0.0.1"}]}}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR)), + ok. + +nat_ip_address_local_local(doc) -> ["This case test if the server ORB use the correct", + "interface when exporting IOR:s"]; +nat_ip_address_local_local(suite) -> []; +nat_ip_address_local_local(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, + (?ORB_ENV_LOCAL_INTERFACE bor + ?ORB_ENV_ENABLE_NAT)}, + {nat_ip_address, {local, "10.0.0.1", [{IP, "10.0.0.2"}]}}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR1 = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {"10.0.0.2", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR1)), + IOR2 = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR2)), + ok. + +nat_iiop_port(doc) -> ["This case test if the server ORB use the correct", + "port when exporting IOR:s"]; +nat_iiop_port(suite) -> []; +nat_iiop_port(_Config) -> + IP = orber_test_lib:get_host(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT}, + {nat_iiop_port, 42}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {_IP, 42, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR)), + ok. + +nat_iiop_port_local(doc) -> ["This case test if the server ORB use the correct", + "port when exporting IOR:s"]; +nat_iiop_port_local(suite) -> []; +nat_iiop_port_local(_Config) -> + IP = orber_test_lib:get_host(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT}, + {nat_iiop_port, {local, 42, [{4001, 43}]}}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + IOR = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {_IP, 42, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR)), + ok. + +nat_iiop_port_local_local(doc) -> ["This case test if the server ORB use the correct", + "port when exporting IOR:s"]; +nat_iiop_port_local_local(suite) -> []; +nat_iiop_port_local_local(_Config) -> + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, + (?ORB_ENV_LOCAL_INTERFACE bor + ?ORB_ENV_ENABLE_NAT)}, + {ip_address, IP}])), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, [nat_iiop_port, {local, 42, [{ServerPort, 43}]}]), + IOR1 = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), + ?match({'external', {IP, 43, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR1)), + {ok, Ref} = ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [Loopback, normal, 10088])), + IOR2 = ?match(#'IOP_IOR'{}, + corba:string_to_object("corbaloc::1.2@"++Loopback++":10088/NameService")), + ?match({'external', {IP, 42, _ObjectKey, _Counter, _TP, _NewHD}}, + iop_ior:get_key(IOR2)), + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, + remove_listen_interface, [Ref])), + ok. + + +%%----------------------------------------------------------------- +%% API tests for ORB to ORB, ssl security depth 1 +%%----------------------------------------------------------------- + +nat_iiop_ssl_port(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", + "Make sure NAT works for SSL"]; +nat_iiop_ssl_port(suite) -> []; +nat_iiop_ssl_port(_Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + IP = orber_test_lib:get_host(), + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + 1, [{iiop_ssl_port, 0}, + {flags, ?ORB_ENV_ENABLE_NAT}, + {ip_address, IP}]), + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + 1, [{iiop_ssl_port, 0}]), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), + NATSSLServerPort = SSLServerPort+1, + {ok, Ref} = ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [IP, ssl, NATSSLServerPort])), + orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, + [nat_iiop_ssl_port, + {local, NATSSLServerPort, [{4001, 43}]}]), + + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [ssl])), + + IOR1 = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, + string_to_object, + ["corbaname::1.2@"++IP++":"++ + integer_to_list(ServerPort)++"/NameService#mamba"])), + + ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP, + #host_data{protocol = ssl, + ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}}, + iop_ior:get_key(IOR1)), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, + [ssl])), + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, + remove_listen_interface, [Ref])), + ok + end. + +nat_iiop_ssl_port_local(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", + "Make sure NAT works for SSL"]; +nat_iiop_ssl_port_local(suite) -> []; +nat_iiop_ssl_port_local(_Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + IP = orber_test_lib:get_host(), + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + 1, [{iiop_ssl_port, 0}, + {flags, + (?ORB_ENV_LOCAL_INTERFACE bor + ?ORB_ENV_ENABLE_NAT)}, + {ip_address, IP}]), + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + 1, [{iiop_ssl_port, 0}]), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), + NATSSLServerPort = SSLServerPort+1, + {ok, Ref} = ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [IP, ssl, NATSSLServerPort])), + orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, + [nat_iiop_ssl_port, + {local, NATSSLServerPort, [{NATSSLServerPort, NATSSLServerPort}]}]), + + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [ssl])), + + IOR1 = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, + string_to_object, + ["corbaname::1.2@"++IP++":"++ + integer_to_list(ServerPort)++"/NameService#mamba"])), + + ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP, + #host_data{protocol = ssl, + ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}}, + iop_ior:get_key(IOR1)), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, + [ssl])), + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, + remove_listen_interface, [Ref])), + ok + end. + diff --git a/lib/orber/test/orber_test.idl b/lib/orber/test/orber_test.idl new file mode 100644 index 0000000000..3d943f2d18 --- /dev/null +++ b/lib/orber/test/orber_test.idl @@ -0,0 +1,95 @@ +// +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// +module Module +{ + + enum Enum {horse, pig, cow}; + + struct Struct0 { + long l; + short s; + char c; + }; + + struct Struct1 { + string s; + unsigned short us; + unsigned long ul; + }; + + struct Struct2 { + sequence <long> long_sequence; + Enum e; + octet o; + }; + + struct HEADER { + short EID; + short NDW; + short SSID; + }; + + enum Enum1 {orange,banana, apple}; + + union Union switch (short) { + case 0: short First; + case 1: string Second; + case 2: char Third; + }; + + union Union1 switch (Enum){ + case horse: short horse; + case pig: sequence <string> Second; + case cow: Enum1 Third; + }; + + union Union2 switch (Enum){ + case horse: long a[10]; + case pig: Union u; + case cow: Union1 u1; + }; + + exception Except1 { + string why; + sequence <string> rest_of_name; + }; + + exception Except2 { + Enum1 e; + Struct2 s; + }; + + exception Except3 { + Union1 u; + unsigned short s; + Object o ; + }; + + exception Except4 {}; + + interface I1 { + void a(); + }; + + interface I2 { + void a(); + }; + +}; + diff --git a/lib/orber/test/orber_test_lib.erl b/lib/orber/test/orber_test_lib.erl new file mode 100644 index 0000000000..a694dc58c4 --- /dev/null +++ b/lib/orber/test/orber_test_lib.erl @@ -0,0 +1,1498 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(orber_test_lib). +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/include/ifr_types.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include("idl_output/orber_test_server.hrl"). +-include_lib("orber/COSS/CosNaming/CosNaming.hrl"). + +-define(match(ExpectedRes,Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-export([js_node/2, + js_node/1, + js_node/0, + slave_sup/0, + remote_apply/4, + install_test_data/1, + light_tests/3, + uninstall_test_data/1, + destroy_node/2, + lookup/2, + alternate_iiop_address/2, + create_alternate_iiop_address/2, + alternate_ssl_iiop_address/3, + create_alternate_ssl_iiop_address/3, + test_coding/1, + test_coding/2, + corba_object_tests/2, + timeouts/3, + precond/3, + postcond/4, + oe_get_interface/0, + create_components_IOR/1, + get_options/2, + get_options/3, + get_options/4, + version_ok/0, + ssl_version/0, + get_loopback_interface/0, + get_loopback_interface/1, + get_host/0, + get_host/1]). + +%% Interceptor functions. +-export([new_out_connection/3, + new_in_connection/3, + closed_in_connection/1, + closed_out_connection/1, + in_request_encoded/6, + in_reply_encoded/6, + out_reply_encoded/6, + out_request_encoded/6, + in_request/6, + in_reply/6, + out_reply/6, + out_request/6]). + +%%------------------------------------------------------------ +%% function : ssl_version +%% Arguments: +%% Returns : integer() +%% Effect : +%% +%%------------------------------------------------------------ +ssl_version() -> + case catch erlang:system_info(otp_release) of + Version when is_list(Version) -> + if + "R12B" < Version -> + 3; + true -> + 2 + end; + _ -> + 2 + end. + +%%------------------------------------------------------------ +%% function : version_ok +%% Arguments: +%% Returns : true | {skipped, Reason} +%% Effect : +%% +%%------------------------------------------------------------ +version_ok() -> + {ok, Hostname} = inet:gethostname(), + case inet:getaddr(Hostname, inet6) of + {error,nxdomain} -> + {skipped, "Inet cannot handle IPv6"}; + _ -> + case inet:getaddr("0:0:0:0:0:FFFF:127.0.0.1", inet6) of + {error,nxdomain} -> + {skipped, "Inet cannot handle IPv6"}; + _ -> + case gen_tcp:listen(0, [{reuseaddr, true}, inet6]) of + {ok, LSock} -> + gen_tcp:close(LSock), + true; + {error, _} -> + {skipped, "Inet cannot handle IPv6"} + end + end + end. +%%------------------------------------------------------------ +%% function : get_host +%% Arguments: Family - inet | inet6 +%% Returns : string() +%% Effect : +%% +%%------------------------------------------------------------ +get_host() -> + get_host(inet). +get_host(Family) -> + case os:type() of + {win32, _} -> + case os:version() of + {6, _, _} when Family == inet -> + "127.0.0.1"; + {6, _, _} -> + "0:0:0:0:0:FFFF:7F00:0001"; + _ -> + [IP] = ?match([_], orber:host()), + IP + end; + _ -> + [IP] = ?match([_], orber:host()), + IP + end. + +%%------------------------------------------------------------ +%% function : get_loopback_interface +%% Arguments: Family - inet | inet6 +%% Returns : string() +%% Effect : +%% +%%------------------------------------------------------------ +get_loopback_interface() -> + get_loopback_interface(inet). +get_loopback_interface(Family) -> + case os:type() of + {win32, _} -> + case os:version() of + {6, _, _} when Family == inet -> + "127.0.0.2"; + {6, _, _} -> + "0:0:0:0:0:FFFF:7F00:0002"; + _ when Family == inet -> + "127.0.0.1"; + _ -> + "0:0:0:0:0:FFFF:7F00:0001" + end; + _ when Family == inet -> + "127.0.0.1"; + _ -> + "0:0:0:0:0:FFFF:7F00:0001" + end. + +%%------------------------------------------------------------ +%% function : js_node/4 +%% Arguments: Port - which iiop_port (integer()) +%% InitOptions - [{Key, Value}] +%% {Type, StartOptions} - {lightweight, [{Key, Value}]} +%% Returns : {ok, Node} | {error, _} +%% Effect : Starts a new slave-node with given (optinally) +%% extra arguments. If fails it retries 'Retries' times. +%%------------------------------------------------------------ +js_node() -> + js_node([], []). + +js_node(InitOptions) when is_list(InitOptions) -> + js_node(InitOptions, []). + +js_node(InitOptions, StartOptions) when is_list(InitOptions) -> + {A,B,C} = erlang:now(), + [_, Host] = string:tokens(atom_to_list(node()), [$@]), + _NewInitOptions = check_options(InitOptions), + js_node_helper(Host, 0, lists:concat([A,'_',B,'_',C]), + InitOptions, 10, StartOptions). + +js_node_helper(Host, Port, Name, Options, Retries, StartOptions) -> + case starter(Host, Name, create_paths()) of + {ok, NewNode} -> + case net_adm:ping(NewNode) of + pong -> + start_ssl(lists:member({secure, ssl}, Options), NewNode), + {ok, Cwd} = file:get_cwd(), + Path = code:get_path(), + ok = rpc:call(NewNode, file, set_cwd, [Cwd]), + true = rpc:call(NewNode, code, set_path, [Path]), + rpc:call(NewNode, application, load, [orber]), + ok = rpc:call(NewNode, corba, orb_init, + [[{iiop_port, Port}, + {orber_debug_level, 10}|Options]]), + start_orber(StartOptions, NewNode), + spawn_link(NewNode, ?MODULE, slave_sup, []), + rpc:multicall([node() | nodes()], global, sync, []), + ok = rpc:call(NewNode, orber, info, [io]), + {ok, NewNode, Host}; + _ -> + {error, "net_adm:ping(Node) failed"} + end; + {error, Reason} when Retries == 0 -> + {error, Reason}; + {error, Reason} -> + io:format("Could not start slavenode ~p:~p due to: ~p~n", + [Host, Port, Reason]), + timer:sleep(500), + js_node_helper(Host, Port, Name, Options, Retries-1, StartOptions) + end. + +check_options(Options) -> + case {os:type(), os:version()} of + {{win32, _}, {6, _, _}} -> + %% Vista, need to run additional checks. + case {orber_tb:keysearch(ip_address, Options), + orber_tb:keysearch(flags, Options, 0)} of + {undefined, Flags} -> + case ?ORB_FLAG_TEST(Flags, ?ORB_ENV_USE_IPV6) of + true -> + [{ip_address, get_host(inet6)}|Options]; + false -> + [{ip_address, get_host(inet)}|Options] + end; + _ -> + Options + end; + _ -> + Options + end. + +starter(Host, Name, Args) -> + case os:type() of + vxworks -> + test_server:start_node(Name, slave, [{args,Args}]); + _ -> + slave:start_link(Host, Name, Args) + end. + +slave_sup() -> + process_flag(trap_exit, true), + receive + {'EXIT', _, _} -> + case os:type() of + vxworks -> + erlang:halt(); + _ -> + ignore + end + end. + +start_ssl(true, Node) -> + rpc:call(Node, ssl, start, []), + rpc:call(Node, crypto, start, []), + rpc:call(Node, ssl, seed, ["testing"]); +start_ssl(_, _) -> + ok. + +start_orber({lightweigth, Options}, Node) -> + ok = rpc:call(Node, orber, start_lightweight, [Options]); +start_orber(lightweight, Node) -> + ok = rpc:call(Node, orber, start_lightweight, []); +start_orber(_, Node) -> + ok = rpc:call(Node, orber, jump_start, []). + + +%%----------------------------------------------------------------- +%% Type - ssl | iiop_ssl +%% Role - 'server' | 'client' +%% Options - [{Key, Value}] +%%----------------------------------------------------------------- +get_options(Type, Role) -> + get_options(Type, Role, 2, []). + +get_options(ssl, Role, Level) -> + get_options(ssl, Role, Level, []). + +get_options(ssl, Role, 2, Options) -> + Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), + [{depth, 2}, + {verify, 2}, + {keyfile, filename:join([Dir, Role, "key.pem"])}, + {cacertfile, filename:join([Dir, Role, "cacerts.pem"])}, + {certfile, filename:join([Dir, Role, "cert.pem"])}|Options]; +get_options(iiop_ssl, _Role, 2, Options) -> + Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), + [{ssl_server_depth, 2}, + {ssl_server_verify, 2}, + {ssl_server_certfile, filename:join([Dir, "server", "cert.pem"])}, + {ssl_server_cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, + {ssl_server_keyfile, filename:join([Dir, "server", "key.pem"])}, + {ssl_client_depth, 2}, + {ssl_client_verify, 2}, + {ssl_client_certfile, filename:join([Dir, "client", "cert.pem"])}, + {ssl_client_cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, + {ssl_client_keyfile, filename:join([Dir, "client", "key.pem"])}, + {secure, ssl}|Options]; +get_options(iiop_ssl, _Role, 1, Options) -> + Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), + [{ssl_server_depth, 1}, + {ssl_server_verify, 0}, + {ssl_server_certfile, filename:join([Dir, "server", "cert.pem"])}, + {ssl_server_cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, + {ssl_server_keyfile, filename:join([Dir, "server", "key.pem"])}, + {ssl_client_depth, 1}, + {ssl_client_verify, 0}, + {ssl_client_certfile, filename:join([Dir, "client", "cert.pem"])}, + {ssl_client_cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, + {ssl_client_keyfile, filename:join([Dir, "client", "key.pem"])}, + {secure, ssl}|Options]. + + +create_paths() -> + Path = filename:dirname(code:which(?MODULE)), + " -pa " ++ Path ++ " -pa " ++ + filename:join(Path, "idl_output") ++ + " -pa " ++ + filename:join(Path, "all_SUITE_data") ++ + " -pa " ++ + filename:dirname(code:which(orber)). + +%%------------------------------------------------------------ +%% function : destroy_node +%% Arguments: Node - which node to destroy. +%% Type - normal | ssl +%% Returns : +%% Effect : +%%------------------------------------------------------------ + +destroy_node(Node, Type) -> + stopper(Node, Type). + +stopper(Node, _Type) -> + case os:type() of + vxworks -> + test_server:stop_node(Node); + _ -> + slave:stop(Node) + end. + + +%%------------------------------------------------------------ +%% function : remote_apply +%% Arguments: N - Node, M - Module, +%% F - Function, A - Arguments (list) +%% Returns : +%% Effect : +%%------------------------------------------------------------ +remote_apply(N, M,F,A) -> + case rpc:call(N, M, F, A) of + {badrpc, Reason} -> + exit(Reason); + Other -> + Other + end. + + + +%%------------------------------------------------------------ +%% function : install_test_data +%% Arguments: WhichSuite +%% Returns : ok +%% Effect : Installs test data associated with 'WhichSuite' +%%------------------------------------------------------------ + +install_test_data(nameservice) -> + oe_orber_test_server:oe_register(), + Mamba = orber_test_server:oe_create([], [{regname, {local, mamba}}]), + true = corba:add_initial_service("Mamba", Mamba), + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "mamba"), + N = lname:insert_component(lname:create(), 1, NC1), + 'CosNaming_NamingContext':bind(NS, N,Mamba); + +install_test_data({nameservice, AltAddr, AltPort}) -> + oe_orber_test_server:oe_register(), + Obj = orber_test_server:oe_create([], [{regname, {local, mamba}}]), + Mamba = corba:add_alternate_iiop_address(Obj, AltAddr, AltPort), + true = corba:add_initial_service("Mamba", Mamba), + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "mamba"), + N = lname:insert_component(lname:create(), 1, NC1), + 'CosNaming_NamingContext':bind(NS, N,Mamba); + +install_test_data(timeout) -> + oe_orber_test_server:oe_register(), + Mamba = orber_test_server:oe_create([], {local, mamba}), + Viper = orber_test_timeout_server:oe_create([], {local, viper}), + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "mamba"), + N1 = lname:insert_component(lname:create(), 1, NC1), + NC2 = lname_component:set_id(lname_component:create(), "viper"), + N2 = lname:insert_component(lname:create(), 1, NC2), + 'CosNaming_NamingContext':bind(NS, N1, Mamba), + 'CosNaming_NamingContext':bind(NS, N2, Viper); + +install_test_data(pseudo) -> + oe_orber_test_server:oe_register(), + Mamba = orber_test_server:oe_create([], [{pseudo,true}]), + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "mamba"), + N = lname:insert_component(lname:create(), 1, NC1), + 'CosNaming_NamingContext':bind(NS, N,Mamba); + +install_test_data(ssl) -> + oe_orber_test_server:oe_register(), + Mamba = orber_test_server:oe_create([], [{regname, {local, mamba}}]), + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "mamba"), + N = lname:insert_component(lname:create(), 1, NC1), + 'CosNaming_NamingContext':bind(NS, N,Mamba); + +install_test_data(ssl_simple) -> + oe_orber_test_server:oe_register(); + +install_test_data(light) -> + %% Nothing to do at the moment but we might in the future + ok; + +install_test_data(_) -> + {error, "no_implement"}. + + +%%------------------------------------------------------------ +%% function : uninstall_test_data +%% Arguments: WhichSuite +%% Returns : ok +%% Effect : Uninstalls test data associated with 'WhichSuite' +%%------------------------------------------------------------ + +uninstall_test_data(pseudo) -> + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "mamba"), + N = lname:insert_component(lname:create(), 1, NC1), + _Obj = (catch 'CosNaming_NamingContext':resolve(NS, N)), + catch 'CosNaming_NamingContext':destroy(NS), + oe_orber_test_server:oe_unregister(); + +uninstall_test_data(timeout) -> + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "mamba"), + N1 = lname:insert_component(lname:create(), 1, NC1), + + NC2 = lname_component:set_id(lname_component:create(), "viper"), + N2 = lname:insert_component(lname:create(), 1, NC2), + Mamba = (catch 'CosNaming_NamingContext':resolve(NS, N1)), + Viper = (catch 'CosNaming_NamingContext':resolve(NS, N2)), + catch corba:dispose(Mamba), + catch corba:dispose(Viper), + catch 'CosNaming_NamingContext':destroy(NS), + oe_orber_test_server:oe_unregister(); + +uninstall_test_data(nameservice) -> + true = corba:remove_initial_service("Mamba"), + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "mamba"), + N = lname:insert_component(lname:create(), 1, NC1), + Obj = (catch 'CosNaming_NamingContext':resolve(NS, N)), + catch corba:dispose(Obj), + catch 'CosNaming_NamingContext':destroy(NS), + oe_orber_test_server:oe_unregister(); + +uninstall_test_data(ssl) -> + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), "mamba"), + N = lname:insert_component(lname:create(), 1, NC1), + Obj = (catch 'CosNaming_NamingContext':resolve(NS, N)), + catch corba:dispose(Obj), + catch 'CosNaming_NamingContext':destroy(NS), + oe_orber_test_server:oe_unregister(); + +uninstall_test_data(ssl_simple) -> + oe_orber_test_server:oe_unregister(); + +uninstall_test_data(light) -> + %% Nothing to do at the moment but we might in the future + ok; + +uninstall_test_data(_) -> + {error, "no_implement"}. + +%%------------------------------------------------------------ +%% function : corba_object_tests +%% Arguments: TestServerObj a orber_test_server ref +%% OtherObj - any other Orber object. +%% Returns : term() +%% Effect : +%%------------------------------------------------------------ + +corba_object_tests(TestServerObj, OtherObj) -> + ?match(false, + corba_object:is_a(TestServerObj, "IDL:orber_parent/inherrit:1.0")), + ?match(true, + corba_object:is_a(TestServerObj, "IDL:omg.org/orber_parent/inherrit:1.0")), + ?match(true, + corba_object:is_a(TestServerObj, "IDL:omg.org/orber_test/server:1.0")), + ?match(false, + corba_object:is_a(TestServerObj, "IDL:orber_test/server:1.0")), + ?match(false, + corba_object:is_a(TestServerObj, "IDL:omg.org/orber_parent/inherrit:1.1")), + ?match(false, + corba_object:is_a(TestServerObj, "NotValidIFRID")), + ?match(false, + corba_object:is_nil(TestServerObj)), + ?match(false, + corba_object:is_equivalent(OtherObj,TestServerObj)), + ?match(true, + corba_object:is_equivalent(TestServerObj,TestServerObj)), + ?match(false, corba_object:non_existent(TestServerObj)), + ?match(false, corba_object:not_existent(TestServerObj)), + ?match(#fullinterfacedescription{}, corba_object:get_interface(TestServerObj)), + + ok. + +%%------------------------------------------------------------ +%% function : lookup +%% Arguments: Port - which port the other orb uses. +%% Returns : term() +%% Effect : +%%------------------------------------------------------------ + +lookup(Host, Port) -> + Key = Host++":"++integer_to_list(Port), + NSR = corba:resolve_initial_references_remote("NameService", + ["iiop://"++Key]), + + NC1 = lname_component:set_id(lname_component:create(), "not_exist"), + N1 = lname:insert_component(lname:create(), 1, NC1), + ?match({'EXCEPTION',{'CosNaming_NamingContext_NotFound',_,_,_}}, + 'CosNaming_NamingContext':resolve(NSR, N1)), + + NC2 = lname_component:set_id(lname_component:create(), "mamba"), + N2 = lname:insert_component(lname:create(), 1, NC2), + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + 'CosNaming_NamingContext':resolve(NSR, N2)), + orber_test_server:print(Obj), + Obj2 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + corba:string_to_object("corbaname:iiop:1.1@"++Key++"/NameService#mamba")), + + orber_test_server:print(Obj2), + + NSR2 = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, + corba:string_to_object("corbaloc:iiop:1.1@"++Key++"/NameService")), + Obj3 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + 'CosNaming_NamingContext':resolve(NSR2, N2)), + orber_test_server:print(Obj3). + +%%------------------------------------------------------------ +%% function : alternate_iiop_address +%% Arguments: Port - which port the other orb uses. +%% Returns : term() +%% Effect : +%%------------------------------------------------------------ +alternate_iiop_address(Host, Port) -> + IOR = create_alternate_iiop_address(Host, Port), + + ?match(false, corba_object:non_existent(IOR)), + ?match({'object_forward',_}, corba:locate(IOR)), + ?match({'object_forward',_}, corba:locate(IOR, 10000)), + ok. + +%%------------------------------------------------------------ +%% function : create_alternate_iiop_address +%% Arguments: Port - which port the other orb uses. +%% Returns : term() +%% Effect : +%%------------------------------------------------------------ +create_alternate_iiop_address(Host, Port) -> + MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE, + component_data = ?ORBER_ORB_TYPE_1}, + #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS, + component_data = ?DEFAULT_CODESETS}, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + component_data = #'ALTERNATE_IIOP_ADDRESS'{ + 'HostID' = Host, + 'Port' = Port}}, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + component_data = #'ALTERNATE_IIOP_ADDRESS'{ + 'HostID' = Host, + 'Port' = 8000}}, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + component_data = #'ALTERNATE_IIOP_ADDRESS'{ + 'HostID' = Host, + 'Port' = 8000}}], + #'IOP_IOR'{type_id=TypeID, + profiles=P1} = _IORA = iop_ior:create({1,2}, + "IDL:omg.org/CosNaming/NamingContextExt:1.0", + [Host], 8000, -1, + "NameService", MC, 0, 0), + #'IOP_IOR'{profiles=P2} = _IORB = iop_ior:create({1,1}, + "IDL:omg.org/CosNaming/NamingContextExt:1.0", + [Host], 8000, -1, + "NameService", [], 0, 0), + #'IOP_IOR'{type_id=TypeID, profiles=P2++P1}. + + +%%------------------------------------------------------------ +%% function : create_components_IOR +%% Arguments: +%% Returns : term() +%% Effect : +%%------------------------------------------------------------ +create_components_IOR(Version) -> + MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE, + component_data = ?ORBER_ORB_TYPE_1}, + #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS, + component_data = ?DEFAULT_CODESETS}, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + component_data = #'ALTERNATE_IIOP_ADDRESS'{ + 'HostID' = "127.0.0.1", + 'Port' = 4001}}, + #'IOP_TaggedComponent'{tag = ?TAG_SSL_SEC_TRANS, + component_data = #'SSLIOP_SSL'{target_supports = 0, + target_requires = 1, + port = 2}}, + #'IOP_TaggedComponent'{tag = ?TAG_FT_GROUP, + component_data = + #'FT_TagFTGroupTaggedComponent' + {version = #'GIOP_Version'{major = 1, + minor = 2}, + ft_domain_id = "FT_FTDomainId", + object_group_id = ?ULONGLONGMAX, + object_group_ref_version = ?LONGMAX}}, + #'IOP_TaggedComponent'{tag = ?TAG_FT_PRIMARY, + component_data = + #'FT_TagFTPrimaryTaggedComponent'{primary = true}}, + #'IOP_TaggedComponent'{tag = ?TAG_FT_HEARTBEAT_ENABLED, + component_data = + #'FT_TagFTHeartbeatEnabledTaggedComponent'{heartbeat_enabled = true}}, + #'IOP_TaggedComponent'{tag = ?TAG_CSI_SEC_MECH_LIST, + component_data = + #'CSIIOP_CompoundSecMechList' + {stateful = false, + mechanism_list = + [#'CSIIOP_CompoundSecMech' + {target_requires = 6, + transport_mech = + #'IOP_TaggedComponent' + {tag=?TAG_TLS_SEC_TRANS, + component_data=#'CSIIOP_TLS_SEC_TRANS' + {target_supports = 7, + target_requires = 8, + addresses = + [#'CSIIOP_TransportAddress'{host_name = "127.0.0.1", + port = 6001}]}}, + as_context_mech = + #'CSIIOP_AS_ContextSec' + {target_supports = 9, target_requires = 10, + client_authentication_mech = [1, 255], + target_name = [2,255]}, + sas_context_mech = + #'CSIIOP_SAS_ContextSec' + {target_supports = 11, target_requires = 12, + privilege_authorities = + [#'CSIIOP_ServiceConfiguration' + {syntax = ?ULONGMAX, + name = [3,255]}], + supported_naming_mechanisms = [[4,255],[5,255]], + supported_identity_types = ?ULONGMAX}}, + #'CSIIOP_CompoundSecMech' + {target_requires = 6, + transport_mech = + #'IOP_TaggedComponent' + {tag=?TAG_NULL_TAG, + component_data=[]}, + as_context_mech = + #'CSIIOP_AS_ContextSec' + {target_supports = 9, target_requires = 10, + client_authentication_mech = [1, 255], + target_name = [2,255]}, + sas_context_mech = + #'CSIIOP_SAS_ContextSec' + {target_supports = 11, target_requires = 12, + privilege_authorities = + [#'CSIIOP_ServiceConfiguration' + {syntax = ?ULONGMAX, + name = [3,255]}], + supported_naming_mechanisms = [[4,255],[5,255]], + supported_identity_types = ?ULONGMAX}}, + #'CSIIOP_CompoundSecMech' + {target_requires = 6, + transport_mech = + #'IOP_TaggedComponent' + {tag=?TAG_SECIOP_SEC_TRANS, + component_data=#'CSIIOP_SECIOP_SEC_TRANS' + {target_supports = 7, + target_requires = 8, + mech_oid = [0,255], + target_name = [0,255], + addresses = + [#'CSIIOP_TransportAddress'{host_name = "127.0.0.1", + port = 6001}]}}, + as_context_mech = + #'CSIIOP_AS_ContextSec' + {target_supports = 9, target_requires = 10, + client_authentication_mech = [1, 255], + target_name = [2,255]}, + sas_context_mech = + #'CSIIOP_SAS_ContextSec' + {target_supports = 11, target_requires = 12, + privilege_authorities = + [#'CSIIOP_ServiceConfiguration' + {syntax = ?ULONGMAX, + name = [3,255]}], + supported_naming_mechanisms = [[4,255],[5,255]], + supported_identity_types = ?ULONGMAX}}]}}], + iop_ior:create(Version, "IDL:omg.org/CosNaming/NamingContextExt:1.0", + ["127.0.0.1"], 5001, -1, + "NameService", MC, 0, 0). + + +%%------------------------------------------------------------ +%% function : alternate_ssl_iiop_address +%% Arguments: Port - which port the other orb uses. +%% Returns : term() +%% Effect : +%%------------------------------------------------------------ +alternate_ssl_iiop_address(Host, Port, SSLPort) -> + IOR = create_alternate_ssl_iiop_address(Host, Port, SSLPort), + + ?match(false, corba_object:non_existent(IOR)), + ?match({'object_forward',_}, corba:locate(IOR)), + ?match({'object_forward',_}, corba:locate(IOR, 10000)), + ok. + + +%%------------------------------------------------------------ +%% function : create_alternate_ssl_iiop_address +%% Arguments: Port - which port the other orb uses. +%% Returns : term() +%% Effect : +%%------------------------------------------------------------ +create_alternate_ssl_iiop_address(Host, Port, SSLPort) -> + MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE, + component_data = ?ORBER_ORB_TYPE_1}, + #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS, + component_data = ?DEFAULT_CODESETS}, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + component_data = #'ALTERNATE_IIOP_ADDRESS'{ + 'HostID' = Host, + 'Port' = Port}}, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + component_data = #'ALTERNATE_IIOP_ADDRESS'{ + 'HostID' = Host, + 'Port' = 8000}}, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + component_data = #'ALTERNATE_IIOP_ADDRESS'{ + 'HostID' = Host, + 'Port' = 8000}}, + #'IOP_TaggedComponent'{tag=?TAG_SSL_SEC_TRANS, + component_data=#'SSLIOP_SSL'{target_supports = 2, + target_requires = 2, + port = SSLPort}}], + #'IOP_IOR'{type_id=TypeID, + profiles=P1} = _IORA = iop_ior:create_external({1,2}, + "IDL:omg.org/CosNaming/NamingContextExt:1.0", + Host, 8000, + "NameService", MC), + #'IOP_IOR'{profiles=P2} = _IORB = iop_ior:create_external({1,1}, + "IDL:omg.org/CosNaming/NamingContextExt:1.0", + Host, 8000, + "NameService", []), + #'IOP_IOR'{type_id=TypeID, profiles=P2++P1}. + + +%%------------------------------------------------------------ +%% function : timeouts +%% Arguments: Port - which port the other orb uses. +%% Returns : term() +%% Effect : +%%------------------------------------------------------------ + +timeouts(Host, Port, ReqT) -> + NSR = corba:resolve_initial_references_remote("NameService", + ["iiop://"++Host++":"++integer_to_list(Port)]), + NC1 = lname_component:set_id(lname_component:create(), "mamba"), + N1 = lname:insert_component(lname:create(), 1, NC1), + NC2 = lname_component:set_id(lname_component:create(), "viper"), + N2 = lname:insert_component(lname:create(), 1, NC2), + Mamba = 'CosNaming_NamingContext':resolve(NSR, N1), + Viper = 'CosNaming_NamingContext':resolve(NSR, N2), + + ?match({'EXCEPTION',{'TIMEOUT',_,_,_}}, + orber_test_timeout_server:twoway_function(Viper, ReqT, ReqT*2)), + ?match(ok, orber_test_timeout_server:oneway_function(Viper, ReqT*2)), + + ?match({'EXCEPTION',{'TIMEOUT',_,_,_}}, + orber_test_server:testing_iiop_twoway_delay(Mamba, ReqT)), + ?match(ok, orber_test_server:testing_iiop_oneway_delay(Mamba, ReqT)), + + %% Since the objects are stalled we must wait until they are available again + %% to be able to run any more tests and get the correct results. + timer:sleep(ReqT*4), + + ?match(ok, orber_test_timeout_server:twoway_function(Viper, ReqT*2, ReqT)), + ?match(ok, orber_test_timeout_server:oneway_function(Viper, ReqT*2)), + + ?match(ok, orber_test_server:testing_iiop_twoway_delay(Mamba, 0)), + ?match(ok, orber_test_server:testing_iiop_oneway_delay(Mamba, 0)), + + timer:sleep(ReqT*4), + ok. + +%%------------------------------------------------------------ +%% function : light_tests +%% Arguments: Host - which node to contact. +%% Port - which port the other orb uses. +%% Returns : term() +%% Effect : +%%------------------------------------------------------------ + +light_tests(Host, Port, ObjName) -> + NSR = corba:resolve_initial_references_remote("NameService", + ["iiop://"++Host++":"++integer_to_list(Port)]), + NC1 = lname_component:set_id(lname_component:create(), "not_exist"), + N1 = lname:insert_component(lname:create(), 1, NC1), + %% We cannot handle any unknown replies (besides those found in stub). + ?match({'EXCEPTION', + {'CosNaming_NamingContext_NotFound', + "IDL:omg.org/CosNaming/NamingContext/NotFound:1.0",_,_}}, + 'CosNaming_NamingContext':resolve(NSR, N1)), + NC2 = lname_component:set_id(lname_component:create(), ObjName), + N2 = lname:insert_component(lname:create(), 1, NC2), + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + 'CosNaming_NamingContext':resolve(NSR, N2)), + Nodes = orber:get_lightweight_nodes(), + io:format("Light Nodes: ~p~n", [Nodes]), + orber_test_server:print(Obj), + test_coding(Obj), + ok. + + +%%------------------------------------------------------------ +%% function : test_coding_simple +%% Arguments: ObjReference +%% Returns : term() +%% Effect : test encode/decode for all simple datatypes. +%%------------------------------------------------------------ + +test_coding(Obj) -> + test_coding(Obj, false). + +test_coding(Obj, Local) -> + %%--- Testing code and decode arguments --- + ?match({ok, 1.5}, orber_test_server:testing_iiop_float(Obj, 1.5)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_float(Obj, atom)), + + ?match({ok,1.0}, orber_test_server:testing_iiop_double(Obj, 1.0)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_double(Obj, "wrong")), + + ?match({ok,0}, orber_test_server:testing_iiop_short(Obj, 0)), + ?match({ok,?SHORTMAX}, orber_test_server:testing_iiop_short(Obj, ?SHORTMAX)), + ?match({ok,?SHORTMIN}, orber_test_server:testing_iiop_short(Obj, ?SHORTMIN)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_short(Obj, atomic)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_short(Obj, ?SHORTMAX+1)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_short(Obj, ?SHORTMIN-1)), + + ?match({ok,0}, orber_test_server:testing_iiop_ushort(Obj, 0)), + ?match({ok,?USHORTMAX}, orber_test_server:testing_iiop_ushort(Obj, ?USHORTMAX)), + ?match({ok,?USHORTMIN}, orber_test_server:testing_iiop_ushort(Obj, ?USHORTMIN)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_ushort(Obj, ?USHORTMAX+1)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_ushort(Obj, ?USHORTMIN-1)), + + ?match({ok,0}, orber_test_server:testing_iiop_long(Obj, 0)), + ?match({ok,?LONGMAX}, orber_test_server:testing_iiop_long(Obj, ?LONGMAX)), + ?match({ok,?LONGMIN}, orber_test_server:testing_iiop_long(Obj, ?LONGMIN)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_long(Obj, "wrong")), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_long(Obj, ?LONGMAX+1)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_long(Obj, ?LONGMIN-1)), + + ?match({ok,0}, orber_test_server:testing_iiop_longlong(Obj, 0)), + ?match({ok,?LONGLONGMAX}, orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMAX)), + ?match({ok,?LONGLONGMIN}, orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMIN)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_longlong(Obj, "wrong")), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMAX+1)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMIN-1)), + + ?match({ok,0}, orber_test_server:testing_iiop_ulong(Obj, 0)), + ?match({ok,?ULONGMAX}, orber_test_server:testing_iiop_ulong(Obj, ?ULONGMAX)), + ?match({ok,?ULONGMIN}, orber_test_server:testing_iiop_ulong(Obj, ?ULONGMIN)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_ulong(Obj, ?ULONGMAX+1)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_ulong(Obj, ?ULONGMIN-1)), + + ?match({ok,0}, orber_test_server:testing_iiop_ulonglong(Obj, 0)), + ?match({ok,?ULONGLONGMAX}, orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMAX)), + ?match({ok,?ULONGLONGMIN}, orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMIN)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMAX+1)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMIN-1)), + + ?match({ok,98}, orber_test_server:testing_iiop_char(Obj, 98)), + ?match({ok,$b}, orber_test_server:testing_iiop_char(Obj, $b)), + + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_char(Obj, atomic)), + + ?match({ok,65535}, orber_test_server:testing_iiop_wchar(Obj, 65535)), + ?match({ok,$b}, orber_test_server:testing_iiop_wchar(Obj, $b)), + + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_wchar(Obj, atomic)), + + ?match({ok,true}, orber_test_server:testing_iiop_bool(Obj, true)), + ?match({ok,false}, orber_test_server:testing_iiop_bool(Obj, false)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_bool(Obj, atom)), + + ?match({ok,1}, orber_test_server:testing_iiop_octet(Obj, 1)), +% No real guards for this case. +% ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, +% orber_test_server:testing_iiop_octet(Obj, 1.5)), + IOR12 = create_components_IOR({1,2}), + ?match({ok,Obj}, orber_test_server:testing_iiop_obj(Obj, Obj)), + ?match({ok,IOR12}, orber_test_server:testing_iiop_obj(Obj, IOR12)), + PObj = orber_test_server:oe_create([], [{pseudo,true}]), + ?match({ok, _}, orber_test_server:testing_iiop_obj(Obj, PObj)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_obj(Obj, "no_object")), + ?match({ok,"string"}, orber_test_server:testing_iiop_string(Obj, "string")), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_string(Obj, "ToLongString")), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_string(Obj, atomic)), + + ?match({ok,[65535]}, orber_test_server:testing_iiop_wstring(Obj, [65535])), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_wstring(Obj, "ToLongWstring")), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_wstring(Obj, atomic)), + + ?match({ok, one}, + orber_test_server:testing_iiop_enum(Obj, one)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_enum(Obj, three)), + ?match({ok,[1,2,3]}, + orber_test_server:testing_iiop_seq(Obj, [1,2,3])), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_seq(Obj, [1,2,3,4])), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_seq(Obj, false)), + + + ?match({ok,[#orber_test_server_struc{a=1, b=2}]}, + orber_test_server:testing_iiop_struc_seq(Obj, + [#orber_test_server_struc{a=1, b=2}])), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_struc_seq(Obj, false)), + + ?match({ok,[#orber_test_server_uni{label=1, value=66}]}, + orber_test_server:testing_iiop_uni_seq(Obj, + [#orber_test_server_uni{label=1, value=66}])), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_uni_seq(Obj, false)), + + ?match({ok,{"one", "two"}}, + orber_test_server:testing_iiop_array(Obj, {"one", "two"})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_array(Obj, {"one", "two", "three"})), + ?match({ok,#orber_test_server_struc{a=1, b=2}}, + orber_test_server:testing_iiop_struct(Obj, + #orber_test_server_struc{a=1, b=2})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_struct(Obj, + #orber_test_server_struc{a="WRONG", b=2})), + ?match({ok,#orber_test_server_uni{label=1, value=66}}, + orber_test_server:testing_iiop_union(Obj, + #orber_test_server_uni{label=1, value=66})), + + ?match({ok,#orber_test_server_uni_d{label=1, value=66}}, + orber_test_server:testing_iiop_union_d(Obj, + #orber_test_server_uni_d{label=1, value=66})), + + ?match({ok,#orber_test_server_uni_d{label=2, value=true}}, + orber_test_server:testing_iiop_union_d(Obj, + #orber_test_server_uni_d{label=2, value=true})), + + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_union_d(Obj, + #orber_test_server_uni_d{label=2, value=66})), + + case Local of + true -> + ?match({ok,#orber_test_server_uni{label=2, value=66}}, + orber_test_server:testing_iiop_union(Obj, + #orber_test_server_uni{label=2, value=66})); + false -> + ?match({ok,#orber_test_server_uni{label=2, value=undefined}}, + orber_test_server:testing_iiop_union(Obj, + #orber_test_server_uni{label=2, value=66})) + end, + + C1 = orber_test_server:fixed52const1(), + C2 = orber_test_server:fixed52const2(), + C3 = orber_test_server:fixed52const3(), + + C4 = orber_test_server:fixed52negconst1(), + C5 = orber_test_server:fixed52negconst2(), + C6 = orber_test_server:fixed52negconst3(), + + ?match({ok,C1}, orber_test_server:testing_iiop_fixed(Obj, C1)), + ?match({ok,C2}, orber_test_server:testing_iiop_fixed(Obj, C2)), + ?match({ok,C3}, orber_test_server:testing_iiop_fixed(Obj, C3)), + ?match({ok,C4}, orber_test_server:testing_iiop_fixed(Obj, C4)), + ?match({ok,C5}, orber_test_server:testing_iiop_fixed(Obj, C5)), + ?match({ok,C6}, orber_test_server:testing_iiop_fixed(Obj, C6)), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_fixed(Obj, #fixed{digits = 5, + scale = 2, + value = 123450})), + + ?match(ok, orber_test_server:testing_iiop_void(Obj)), + + ?match({'EXCEPTION',{'BAD_QOS',_,_,_}}, + orber_test_server:pseudo_call_raise_exc(Obj, 1)), + ?match({'EXCEPTION',{'BAD_QOS',_,_,_}}, + orber_test_server:pseudo_call_raise_exc(Obj, 2)), + ?match({'EXCEPTION',{'orber_test_server_UserDefinedException',_}}, + orber_test_server:raise_local_exception(Obj)), + ?match({'EXCEPTION',{'orber_test_server_ComplexUserDefinedException',_, + [#orber_test_server_struc{a=1, b=2}]}}, + orber_test_server:raise_complex_local_exception(Obj)), + %% Test all TypeCodes + ?match({ok, #any{typecode = tk_long, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, + value = 1})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, + value = "wrong"})), + ?match({ok, #any{typecode = tk_float, value = 1.5}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_float, + value = 1.5})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, + value = "wrong"})), + ?match({ok, #any{typecode = tk_double}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_double, + value = 1.0})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_double, + value = "wrong"})), + ?match({ok, #any{typecode = tk_short, value = -1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_short, + value = -1})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_short, + value = atomic})), + ?match({ok, #any{typecode = tk_ushort, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ushort, + value = 1})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ushort, + value = -1})), + ?match({ok, #any{typecode = tk_long, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, + value = 1})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, + value = "wrong"})), + ?match({ok, #any{typecode = tk_longlong, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_longlong, + value = 1})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_longlong, + value = "wrong"})), + ?match({ok, #any{typecode = tk_ulong, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, + value = 1})), + ?match({ok, #any{typecode = tk_ulong, value = 4294967295}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, + value = 4294967295})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, + value = 4294967296})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, + value = -1})), + ?match({ok, #any{typecode = tk_ulonglong, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulonglong, + value = 1})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulonglong, + value = -1})), + ?match({ok, #any{typecode = tk_char, value = 98}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char, + value = 98})), + ?match({ok, #any{typecode = tk_char, value = $b}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char, + value = $b})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char, + value = atomic})), + ?match({ok, #any{typecode = tk_wchar, value = 65535}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar, + value = 65535})), + ?match({ok, #any{typecode = tk_wchar, value = $b}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar, + value = $b})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar, + value = atomic})), + ?match({ok, #any{typecode = tk_boolean, value = true}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean, + value = true})), + ?match({ok, #any{typecode = tk_boolean, value = false}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean, + value = false})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean, + value = 1})), + ?match({ok, #any{typecode = tk_octet, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_octet, + value = 1})), + ?match({ok, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"}, value = Obj}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"}, + value = Obj})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"}, + value = "No Object"})), + ?match({ok, #any{typecode = {tk_string, 6}, value = "string"}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_string, 6}, + value = "string"})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_string, + value = atomic})), + ?match({ok, #any{typecode = {tk_wstring, 1}, value = [65535]}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_wstring, 1}, + value = [65535]})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_wstring, 1}, + value = atomic})), + ?match({ok, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]}, + value = two}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]}, + value = two})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]}, + value = three})), + + + ?match({ok, #any{typecode = {tk_sequence, tk_long, 3}, + value = [1,2,3]}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_sequence, tk_long, 3}, + value = [1,2,3]})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_sequence, tk_long, 3}, + value = false})), + + + + ?match({ok, #any{typecode = {tk_array,{tk_string,0},2}, + value = {"one", "two"}}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2}, + value = {"one", "two"}})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2}, + value = {"one", "two", "three"}})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2}, + value = {1, 2}})), + ?match({ok, #any{typecode = {tk_struct,"IDL:omg.org/orber_test/server/struc:1.0", + "struc", + [{"a",tk_long},{"b",tk_short}]}, + value = #orber_test_server_struc{a=1, b=2}}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_struct,"IDL:omg.org/orber_test/server/struc:1.0", + "struc", + [{"a",tk_long},{"b",tk_short}]}, + value = #orber_test_server_struc{a=1, b=2}})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_struct,"IDL:omg.org/orber_test/server/struc:1.0", + "struc", + [{"a",tk_long},{"b",tk_short}]}, + value = #orber_test_server_struc{a=1, b="string"}})), + ?match({ok, #any{typecode = + {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", + "uni", tk_long, -1, [{1,"a",tk_long}]}, + value = #orber_test_server_uni{label=1, value=66}}}, + orber_test_server: + testing_iiop_any(Obj, + #any{typecode = + {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", + "uni", tk_long, -1, [{1,"a",tk_long}]}, + value = #orber_test_server_uni{label=1, value=66}})), + case Local of + true -> + ?match({ok, #any{typecode = + {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", + "uni", tk_long, -1, [{1,"a",tk_long}]}, + value = #orber_test_server_uni{label=2, value=66}}}, + orber_test_server: + testing_iiop_any(Obj, + #any{typecode = + {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", + "uni", tk_long, -1, [{1,"a",tk_long}]}, + value = #orber_test_server_uni{label=2, value=66}})); + false -> + ?match({ok, #any{typecode = + {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", + "uni", tk_long, -1, [{1,"a",tk_long}]}, + value = #orber_test_server_uni{label=2, value=undefined}}}, + orber_test_server: + testing_iiop_any(Obj, + #any{typecode = + {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", + "uni", tk_long, -1, [{1,"a",tk_long}]}, + value = #orber_test_server_uni{label=2, value=66}})) + end, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server: + testing_iiop_any(Obj, + #any{typecode = + {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", + "uni", tk_long, -1, [{1,"a",tk_long}]}, + value = #orber_test_server_uni{label=1, value="string"}})), + + ?match({ok, #any{typecode = {tk_fixed,5,2}, + value = #fixed{digits = 5, scale = 2, value = 12345}}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,5,2}, + value = #fixed{digits = 5, + scale = 2, + value = 12345}})), + ?match({ok, #any{typecode = {tk_fixed,10,2}, + value = #fixed{digits = 10, scale = 2, value = 1234567890}}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,10,2}, + value = #fixed{digits = 10, + scale = 2, + value = 1234567890}})), + ?match({ok, #any{typecode = {tk_fixed,6,2}, + value = #fixed{digits = 6, scale = 2, value = 300000}}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,6,2}, + value = #fixed{digits = 6, + scale = 2, + value = 300000}})), + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server: + testing_iiop_server_marshal(Obj, "string")), + ok. + +%%--------------- Testing Post- & Pre-cond ------------------- +precond(Module, Function, Args) -> + error_logger:info_msg("=============== pre-condition ============ +Module : ~p +Function : ~p +Arguments : ~p +==========================================~n", [Module, Function, Args]), + ok. + +postcond(Module, Function, Args, Result) -> + error_logger:info_msg("=============== post-condition =========== +Module : ~p +Function : ~p +Arguments : ~p +Result : ~p +==========================================~n", [Module, Function, Args, Result]), + ok. + +%%--------------- Testing Missing Module --------------------- +oe_get_interface() -> + non_existing_module:tc(foo). + +%%--------------- INTERCEPTOR FUNCTIONS ---------------------- +%%------------------------------------------------------------ +%% function : new_in_connection +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +new_in_connection(Arg, CHost, Port) -> + Host = node(), + [{SHost, SPort}] = orber:find_sockname_by_peername(CHost, Port), + Peers = orber:find_peername_by_sockname(SHost, SPort), + error_logger:info_msg("=============== new_in_connection ======== +Node : ~p +From Host : ~p +From Port : ~p +To Host : ~p +To Port : ~p +Peers : ~p +Arg : ~p +==========================================~n", + [Host, CHost, Port, SHost, SPort, Peers, Arg]), + {Host}. + +%%------------------------------------------------------------ +%% function : new_out_connection +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +new_out_connection(Arg, SHost, Port) -> + Host = node(), + error_logger:info_msg("=============== new_out_connection ======= +Node : ~p +To Host : ~p +To Port : ~p +Arg : ~p +==========================================~n", + [Host, SHost, Port, Arg]), + {Host}. + +%%------------------------------------------------------------ +%% function : closed_in_connection +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +closed_in_connection(Arg) -> + error_logger:info_msg("=============== closed_in_connection ===== +Node : ~p +Connection: ~p +==========================================~n", + [node(), Arg]), + Arg. + +%%------------------------------------------------------------ +%% function : closed_out_connection +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +closed_out_connection(Arg) -> + error_logger:info_msg("=============== closed_out_connection ==== +Node : ~p +Connection: ~p +==========================================~n", + [node(), Arg]), + Arg. + +%%------------------------------------------------------------ +%% function : in_request_encoded +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +in_request_encoded(Ref, _ObjKey, Ctx, Op, + <<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8,T/binary>>, _Args) -> + error_logger:info_msg("=============== in_request_encoded ======= +Connection: ~p +Operation : ~p +Body : ~p +Context : ~p +==========================================~n", + [Ref, Op, T, Ctx]), + {T, "NewArgs"}. + +%%------------------------------------------------------------ +%% function : in_reply_encoded +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +in_reply_encoded(Ref, _ObjKey, Ctx, Op, + <<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8,T/binary>>, + _Args) -> + error_logger:info_msg("============== in_reply_encoded ========== +Connection: ~p +Operation : ~p +Body : ~p +Context : ~p +==========================================~n", + [Ref, Op, T, Ctx]), + {T, "NewArgs"}. + +%%------------------------------------------------------------ +%% function : out_reply_encoded +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +out_reply_encoded(Ref, _ObjKey, Ctx, Op, List, _Args) -> + error_logger:info_msg("============== out_reply_encoded ========= +Connection: ~p +Operation : ~p +Body : ~p +Context : ~p +==========================================~n", + [Ref, Op, List, Ctx]), + {list_to_binary([<<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8>>|List]), "NewArgs"}. + +%%------------------------------------------------------------ +%% function : out_request_encoded +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +out_request_encoded(Ref, _ObjKey, Ctx, Op, List, _Args) -> + error_logger:info_msg("============== out_request_encoded ======= +Connection: ~p +Operation : ~p +Body : ~p +Context : ~p +==========================================~n", + [Ref, Op, List, Ctx]), + {list_to_binary([<<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8>>|List]), "NewArgs"}. + +%%------------------------------------------------------------ +%% function : in_request +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +in_request(Ref, _ObjKey, Ctx, Op, Params, _Args) -> + error_logger:info_msg("=============== in_request =============== +Connection: ~p +Operation : ~p +Parameters: ~p +Context : ~p +==========================================~n", + [Ref, Op, Params, Ctx]), + {Params, "NewArgs"}. + +%%------------------------------------------------------------ +%% function : in_reply +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +in_reply(Ref, _ObjKey, Ctx, Op, Reply, _Args) -> + error_logger:info_msg("=============== in_reply ================= +Connection: ~p +Operation : ~p +Reply : ~p +Context : ~p +==========================================~n", + [Ref, Op, Reply, Ctx]), + {Reply, "NewArgs"}. + +%%------------------------------------------------------------ +%% function : postinvoke +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +out_reply(Ref, _ObjKey, Ctx, Op, Reply, _Args) -> + error_logger:info_msg("=============== out_reply ================ +Connection: ~p +Operation : ~p +Reply : ~p +Context : ~p +==========================================~n", + [Ref, Op, Reply, Ctx]), + {Reply, "NewArgs"}. + +%%------------------------------------------------------------ +%% function : postinvoke +%% Arguments: +%% Returns : +%%------------------------------------------------------------ +out_request(Ref, _ObjKey, Ctx, Op, Params, _Args) -> + error_logger:info_msg("=============== out_request ============== +Connection: ~p +Operation : ~p +Parameters: ~p +Context : ~p +==========================================~n", + [Ref, Op, Params, Ctx]), + {Params, "NewArgs"}. + + +%%--------------- END OF MODULE ------------------------------ + + + diff --git a/lib/orber/test/orber_test_server.cfg b/lib/orber/test/orber_test_server.cfg new file mode 100644 index 0000000000..84c671f795 --- /dev/null +++ b/lib/orber/test/orber_test_server.cfg @@ -0,0 +1,27 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +{timeout, "orber_test::timeout_server"}. +{this, "orber_test::timeout_server"}. +{{handle_info, "orber_test::timeout_server"}, true}. +{this, "orber_test::server"}. +{{handle_info, "orber_test::server"}, true}. +{{postcond, "orber_test::server::testing_iiop_union_d"}, {orber_test_lib, postcond}}. +{{postcond, "orber_test::server::testing_iiop_array"}, {orber_test_lib, postcond}}. +{{precond, "orber_test::server::testing_iiop_array"}, {orber_test_lib, precond}}. +{{precond, "orber_test::server::testing_iiop_enum"}, {orber_test_lib, precond}}. diff --git a/lib/orber/test/orber_test_server.idl b/lib/orber/test/orber_test_server.idl new file mode 100644 index 0000000000..a88211c941 --- /dev/null +++ b/lib/orber/test/orber_test_server.idl @@ -0,0 +1,153 @@ +// +// %CopyrightBegin% +// +// Copyright Ericsson AB 1999-2010. All Rights Reserved. +// +// The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved online at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// %CopyrightEnd% +// + +#ifndef _ORBER_TEST_SERVER_IDL +#define _ORBER_TEST_SERVER_IDL +#pragma prefix "omg.org" + +module orber_parent { + interface inherrit { + void print(); + }; +}; + +module orber_test { + + // interface server + interface server : orber_parent::inherrit { + typedef string array[2]; + typedef sequence <long, 3> seq; + typedef wstring<6> WstrLength6; + typedef string<6> StrLength6; + + struct struc {long a; short b;}; + union uni switch(long) { + case 1: long a;}; + + union uni_d switch(long) { + case 1: long a; + default: boolean b; + }; + enum enumerant {one, two}; + + exception UserDefinedException {}; + + typedef sequence<struc> StrucSeq; + typedef sequence<uni> UniSeq; + exception ComplexUserDefinedException { StrucSeq strseq; }; + + // Testing fixed + const fixed val1 = 3.14D; + const fixed val2 = 003.14D; + const fixed val3 = 003.1400D; + const fixed val4 = 3.1400D; + const fixed val5 = .1400D; + const fixed val6 = 3.D; + const fixed val7 = -.1400D; + const fixed val8 = -3.D; + const fixed val9 = val4+val5; + const fixed val10 = val4*val5; + const fixed val11 = val4/val5; + const fixed val12 = 123.140001D; + const fixed val13 = 12314000.1D; + const fixed val14 = val12-val13; + const fixed val15 = val12+val13; + const fixed val16 = val12*val13; + const fixed val17 = 2.01D+2.01D; + const fixed val18 = 2.01D*2.01D; + const fixed val19 = 200D; + const fixed val20 = 9999999999999999999999999999999D+9999999999999999999999999999999D; + const fixed val21 = 9999999999999999999999999999999D-9999999999999999999999999999999D; + const fixed val22 = 9999999999999999999999999999999D*9999999999999999999999999999999D; + const fixed val23 = 9999999999999999999999999999999D/9999999999999999999999999999999D; + const fixed val24 = 9999D+9999D; + const fixed val25 = 400D/10D; + const fixed val26 = 9999999999999999999999999999999D; + + + typedef fixed<5,2> fixed52; + const fixed52 fixed52const1 = 123.45d; + const fixed52 fixed52const2 = 123.00d; + const fixed52 fixed52const3 = 023.00d; + const fixed52 fixed52negconst1 = -123.45d; + const fixed52 fixed52negconst2 = -123.00d; + const fixed52 fixed52negconst3 = -023.00d; + + void stop_normal(); + + void stop_brutal(); + + // Testing encode and decode + void testing_iiop_float(inout float Fl); + void testing_iiop_double(inout double Do); + void testing_iiop_short(inout short Sh); + void testing_iiop_ushort(inout unsigned short Us); + void testing_iiop_long(inout long Lo); + void testing_iiop_longlong(inout long long LLo); + void testing_iiop_ulong(inout unsigned long Ulo); + void testing_iiop_ulonglong(inout unsigned long long LLo); + void testing_iiop_char(inout char Ch); + void testing_iiop_wchar(inout wchar WCh); + void testing_iiop_bool(inout boolean Bool); + void testing_iiop_octet(inout octet Oct); + void testing_iiop_any(inout any AnyType); + void testing_iiop_obj(inout Object Obj); + void testing_iiop_string(inout StrLength6 Str); + void testing_iiop_wstring(inout WstrLength6 WStr); + void testing_iiop_struct(inout struc Stru); + void testing_iiop_union(inout uni Uni); + void testing_iiop_union_d(inout uni_d Uni); + void testing_iiop_enum(inout enumerant Enumerant); + void testing_iiop_seq(inout seq Seq); + void testing_iiop_uni_seq(inout UniSeq USeq); + void testing_iiop_struc_seq(inout StrucSeq SSeq); + void testing_iiop_array(inout array Arr); + void testing_iiop_fixed(inout fixed52 MyFixed); + void testing_iiop_void(); + void testing_iiop_context(); + void testing_iiop_server_marshal(inout StrLength6 Str); + + oneway void testing_iiop_oneway_delay(in long Time); + void testing_iiop_twoway_delay(in long Time); + + // Testing relay calls/casts to, for example, test that sending implicit + // Contexts works. + void relay_call(in Object Target); + oneway void relay_cast(in Object Target); + + // Testing pseudo calls/casts + void pseudo_call(); + oneway void pseudo_cast(); + void pseudo_call_delay(inout long Lo); + oneway void pseudo_cast_delay(in long Lo); + void pseudo_call_raise_exc(in long Lo); + void raise_local_exception() + raises(UserDefinedException); + void raise_complex_local_exception() + raises(ComplexUserDefinedException); + }; + + interface timeout_server { + oneway void oneway_function(in long time); + void twoway_function(in long time); + }; + +}; + +#endif diff --git a/lib/orber/test/orber_test_server_impl.erl b/lib/orber/test/orber_test_server_impl.erl new file mode 100644 index 0000000000..35296cb619 --- /dev/null +++ b/lib/orber/test/orber_test_server_impl.erl @@ -0,0 +1,262 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(orber_test_server_impl). +-include_lib("orber/include/corba.hrl"). +-include("idl_output/orber_test_server.hrl"). + +%%--------------- specified functions ------------------------ +-export([stop_normal/2, + stop_brutal/2, + print/2, + %% Testing code and decode arguments + testing_iiop_float/3, + testing_iiop_double/3, + testing_iiop_short/3, + testing_iiop_ushort/3, + testing_iiop_long/3, + testing_iiop_longlong/3, + testing_iiop_ulong/3, + testing_iiop_ulonglong/3, + testing_iiop_char/3, + testing_iiop_wchar/3, + testing_iiop_bool/3, + testing_iiop_octet/3, + testing_iiop_any/3, + testing_iiop_obj/3, + testing_iiop_string/3, + testing_iiop_wstring/3, + testing_iiop_struct/3, + testing_iiop_union/3, + testing_iiop_union_d/3, + testing_iiop_enum/3, + testing_iiop_seq/3, + testing_iiop_uni_seq/3, + testing_iiop_struc_seq/3, + testing_iiop_array/3, + testing_iiop_fixed/3, + testing_iiop_void/2, + testing_iiop_context/2, + testing_iiop_server_marshal/3, + relay_call/3, + relay_cast/3, + %% Testing pseudo calls. + pseudo_call/2, + pseudo_cast/2, + pseudo_call_delay/3, + pseudo_cast_delay/3, + pseudo_call_raise_exc/3, + %% Testing raise locally defined exception. + raise_local_exception/2, + raise_complex_local_exception/2, + %% Test timeout functionality + testing_iiop_oneway_delay/3, + testing_iiop_twoway_delay/3]). + + +%%--------------- gen_server specific ------------------------ +-export([init/1, terminate/2]). +-export([handle_call/3, handle_cast/2, handle_info/2, code_change/3]). + +%%--------------- LOCAL DATA --------------------------------- + +%%------------------------------------------------------------ +%% function : init, terminate +%%------------------------------------------------------------ +init(State) -> + process_flag(trap_exit,true), + {ok, State}. + +terminate(Reason, State) -> + io:format("orber_test_server:terminate(~p ~p)~n",[Reason, State]), + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. +handle_call(_,_, State) -> + {noreply, State}. +handle_cast(_, State) -> + {noreply, State}. +handle_info(_Info, State) -> + {noreply, State}. + +%%--------------- SERVER FUNCTIONS --------------------------- + +print(Self, State) -> + io:format("orber_test_server:print(~p ~p)~n",[Self, State]), + {reply, ok, State}. + +stop_normal(_Self, State) -> + {stop, normal, ok, State}. + +stop_brutal(_Self, _State) -> + exit("killed_brutal"). + + +%% Testing code and decode arguments +testing_iiop_float(_Self, State, Float) -> + {reply, {ok, Float}, State}. + +testing_iiop_double(_Self, State, Double) -> + {reply, {ok, Double}, State}. + +testing_iiop_short(_Self, State, Short) -> + {reply, {ok, Short}, State}. + +testing_iiop_ushort(_Self, State, Ushort) -> + {reply, {ok, Ushort}, State}. + +testing_iiop_long(_Self, State, Long) -> + {reply, {ok, Long}, State}. + +testing_iiop_longlong(_Self, State, LLong) -> + {reply, {ok, LLong}, State}. + +testing_iiop_ulong(_Self, State, Ulong) -> + {reply, {ok, Ulong}, State}. + +testing_iiop_ulonglong(_Self, State, ULlong) -> + {reply, {ok, ULlong}, State}. + +testing_iiop_char(_Self, State, Char) -> + {reply, {ok, Char}, State}. + +testing_iiop_wchar(_Self, State, WChar) -> + {reply, {ok, WChar}, State}. + +testing_iiop_bool(_Self, State, Boolean) -> + {reply, {ok, Boolean}, State}. + +testing_iiop_octet(_Self, State, Octet) -> + {reply, {ok, Octet}, State}. + +testing_iiop_any(_Self, State, Any) -> + {reply, {ok, Any}, State}. + +testing_iiop_obj(_Self, State, Obj) -> + {reply, {ok, Obj}, State}. + +testing_iiop_string(_Self, State, String) -> + {reply, {ok, String}, State}. + +testing_iiop_wstring(_Self, State, WString) -> + {reply, {ok, WString}, State}. + +testing_iiop_struct(_Self, State, Struct) -> + {reply, {ok, Struct}, State}. + +testing_iiop_union(_Self, State, Union) -> + {reply, {ok, Union}, State}. + +testing_iiop_union_d(_Self, State, Union) -> + {reply, {ok, Union}, State}. + +testing_iiop_enum(_Self, State, Enum) -> + {reply, {ok, Enum}, State}. + +testing_iiop_seq(_Self, State, Sequence) -> + {reply, {ok, Sequence}, State}. + +testing_iiop_uni_seq(_Self, State, Sequence) -> + {reply, {ok, Sequence}, State}. + +testing_iiop_struc_seq(_Self, State, Sequence) -> + {reply, {ok, Sequence}, State}. + +testing_iiop_array(_Self, State, Array) -> + {reply, {ok, Array}, State}. + +testing_iiop_fixed(_Self, State, Fixed) -> + {reply, {ok, Fixed}, State}. + +testing_iiop_void(_Self, State) -> + {reply, ok, State}. + +testing_iiop_context(_Self, State) -> + Ctx = get(oe_server_in_context), + io:format("orber_test_server:testing_iiop_context( ~p )~n", [Ctx]), + {reply, ok, State}. + +testing_iiop_server_marshal(_Self, State, _String) -> + {reply, {ok, false}, State}. + +testing_iiop_oneway_delay(_Self, State, Time) -> + timer:sleep(Time), + {noreply, State}. + +testing_iiop_twoway_delay(_Self, State, Time) -> + timer:sleep(Time), + {reply, ok, State}. + +raise_local_exception(_Self, State) -> + corba:raise(#'orber_test_server_UserDefinedException'{}), + {reply, ok, State}. + +raise_complex_local_exception(_Self, State) -> + corba:raise(#'orber_test_server_ComplexUserDefinedException'{strseq= + [#orber_test_server_struc{a=1, b=2}]}), + {reply, ok, State}. + +%% Testing relay calls/casts to, for example, test that sending implicit +%% Contexts works. +relay_call(_Self, State, Target) -> + io:format("orber_test_server:relay_call( ~p ) Pre~n", [get(oe_server_in_context)]), + orber_test_server:testing_iiop_context(Target), + io:format("orber_test_server:relay_call( ~p ) Post~n", [get(oe_server_in_context)]), + {reply, ok, State}. + +relay_cast(_Self, State, Target) -> + io:format("orber_test_server:relay_cast( ~p ) Pre~n", [get(oe_server_in_context)]), + orber_test_server:testing_iiop_context(Target), + io:format("orber_test_server:relay_cast( ~p ) Post~n", [get(oe_server_in_context)]), + {noreply, State}. + +%% Testing pseudo calls. +pseudo_call(_Self, State) -> + io:format("orber_test_server:pseudo_call( ~p )~n", [now()]), + {reply, ok, State}. + +pseudo_cast(_Self, State) -> + io:format("orber_test_server:pseudo_cast( ~p )~n", [now()]), + {noreply, State}. +pseudo_call_delay(_Self, State, Time) -> + io:format("orber_test_server:pseudo_call_delay( ~p )~n", [now()]), + timer:sleep(Time), + io:format("orber_test_server:pseudo_call_delay( ~p )~n", [now()]), + {reply, {ok, Time}, State}. + +pseudo_cast_delay(_Self, State, Time) -> + io:format("orber_test_server:pseudo_cast_delay( ~p )~n", [now()]), + timer:sleep(Time), + io:format("orber_test_server:pseudo_cast_delay( ~p )~n", [now()]), + {noreply, State}. + +pseudo_call_raise_exc(_Self, State, 1) -> + io:format("orber_test_server:pseudo_call_raise_exc( ~p )~n",[1]), + {reply, {'EXCEPTION', #'BAD_QOS'{completion_status=?COMPLETED_NO}}, State}; +pseudo_call_raise_exc(_Self, State, 2) -> + io:format("orber_test_server:pseudo_call_raise_exc( ~p )~n",[2]), + corba:raise(#'BAD_QOS'{completion_status=?COMPLETED_NO}), + {reply, ok, State}. + +%%--------------- LOCAL FUNCTIONS ---------------------------- + +%%--------------- END OF MODULE ------------------------------ + diff --git a/lib/orber/test/orber_test_timeout_server_impl.erl b/lib/orber/test/orber_test_timeout_server_impl.erl new file mode 100644 index 0000000000..138eb51d92 --- /dev/null +++ b/lib/orber/test/orber_test_timeout_server_impl.erl @@ -0,0 +1,65 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : orber_test_timeout_server_impl.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module(orber_test_timeout_server_impl). + +-export([oneway_function/3, twoway_function/3]). + + +%%--------------- gen_server specific ------------------------ +-export([init/1, terminate/2, code_change/3, handle_info/2]). + +%%------------------------------------------------------------ +%% function : server specific +%%------------------------------------------------------------ +init(State) -> + %% 'trap_exit' optional + process_flag(trap_exit,true), + {ok, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%% If use IC option {{handle_info, "Module::Interface"}, true} +handle_info(_Info, State) -> + %% Await the next invocation. + {noreply, State}. + +%%--- two-way ------------------------------------------------ +twoway_function(_OE_THIS, State, Time) -> + timer:sleep(Time), + {reply, ok, State}. + + +%%--- one-way ------------------------------------------------ +oneway_function(_OE_THIS, State, Time) -> + timer:sleep(Time), + {noreply, State}. + +%%--------------- END OF MODULE ------------------------------ + diff --git a/lib/orber/test/orber_web_SUITE.erl b/lib/orber/test/orber_web_SUITE.erl new file mode 100644 index 0000000000..ffa7468853 --- /dev/null +++ b/lib/orber/test/orber_web_SUITE.erl @@ -0,0 +1,443 @@ +%%----------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% File : orber_web_SUITE.erl +%% Purpose : +%%----------------------------------------------------------------- + +-module(orber_web_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS) + end + end()). + +-define(nomatch(Not, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + Not -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + ?line exit(AcTuAlReS); + _ -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS + end + end()). + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["This suite is for testing the Orber Web API"]; +all(suite) -> + [menu, configure, info, nameservice, ifr_select, ifr_data, + create, delete_ctx, add_ctx, delete_obj, server]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + Path = code:which(?MODULE), + code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), + orber:jump_start(2875), + oe_orber_test_server:oe_register(), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + oe_orber_test_server:oe_unregister(), + orber:jump_stop(), + Path = code:which(?MODULE), + code:del_path(filename:join(filename:dirname(Path), "idl_output")), + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case: menu +%% Description: +%%----------------------------------------------------------------- +menu(doc) -> [""]; +menu(suite) -> []; +menu(_) -> + Node = atom_to_list(node()), + OK = orber_web:menu(env, [{"node", Node}]), + ?match(OK, orber_web:menu(env, [])), + ?match(OK, orber_web:menu(env, [42, {"node", Node}, "wrong"])), + ?match({'EXIT', _E}, orber_web:menu(env, [{"node", localhost}])), + ok. + +%%----------------------------------------------------------------- +%% Test Case: configure +%% Description: +%%----------------------------------------------------------------- +configure(doc) -> [""]; +configure(suite) -> []; +configure(_) -> + Node = atom_to_list(node()), + ?match({'EXIT', _}, orber_web:configure(env, [])), + ?match({'EXIT', _}, orber_web:configure(env, [{"node", localhost}, + {"data", atom}])), + ?match([_H|_T], orber_web:configure(env, [{"node", Node}, {"data", ""}])), + ?match([_H|_T], orber_web:configure(env, [{"node", Node}, + {"data", "[{orber_debug_level, 9}]"}])), + ?match({ok, 9}, application:get_env(orber, orber_debug_level)), + ?match([_H|_T], orber_web:configure(env, [{"node", "bad_node"}, + {"data", "[{orber_debug_level, 9}]"}])), + ?match({error, _}, orber_web:configure(env, [{"node", Node}, + {"data", "{orber_debug_level 9}"}])), + ok. + +%%----------------------------------------------------------------- +%% Test Case: info +%% Description: +%%----------------------------------------------------------------- +info(doc) -> [""]; +info(suite) -> []; +info(_) -> + ?match({'EXIT', _}, orber_web:info(env, [])), + ?match({'EXIT', _}, orber_web:info(env, [{"node", localhost}])), + ?match([_H|_T], orber_web:info(env, [{"node", atom_to_list(node())}])), + ok. + +%%----------------------------------------------------------------- +%% Test Case: nameservice +%% Description: +%%----------------------------------------------------------------- +nameservice(doc) -> [""]; +nameservice(suite) -> []; +nameservice(_) -> + NodeStr = atom_to_list(node()), + ?match({'EXIT', _}, orber_web:nameservice(env, [{"node", localhost}, + {"context", "root"}])), + ?match({'EXIT', _}, orber_web:nameservice(env, [{"node", localhost}, + {"context", "id1"}])), + ?match([_H|_T], orber_web:nameservice(env, [{"node", "bad_node"}, + {"context", "root"}])), + ?match([_,_,_,NodeStr|_], orber_web:nameservice(env, [{"node", NodeStr}, + {"context", "root"}])), + ?match({ok,_}, orber_web:nameservice(env, [{"node", NodeStr}, + {"context", "id1"}])), + ?match([_H|_T], orber_web:add_ctx(env, [{"node", NodeStr}, + {"context", "root"}, + {"id", "id1"}])), + ?match([_H|_T], orber_web:add_ctx(env, [{"node", NodeStr}, + {"context", "id1"}, + {"id", "id2"}])), + [_,_,_,IOR] = + ?match([_,_,_,_], orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[{pseudo, true}]"}, + {"namestr", "id1/id2/id3"}, + {"bind", "rebind"}])), + ?match(#'IOP_IOR'{}, corba:string_to_object(IOR)), + + ?match([_,"id1"|_], orber_web:nameservice(env, [{"node", NodeStr}, + {"context", "id1"}])), + ?nomatch({error, _}, orber_web:nameservice(env, [{"node", NodeStr}, + {"context", "id1/id2"}, + {"object", "id3"}])), + + ok. + +%%----------------------------------------------------------------- +%% Test Case: ifr_select +%% Description: +%%----------------------------------------------------------------- +ifr_select(doc) -> [""]; +ifr_select(suite) -> []; +ifr_select(_) -> + ?match({'EXIT', _}, orber_web:ifr_select(env, [])), + ?match({'EXIT', _}, orber_web:ifr_select(env, [{"node", localhost}])), + ?match([_H|_T], orber_web:ifr_select(env, [{"node", "bad_node"}])), + ?match([_H|_T], orber_web:ifr_select(env, [{"node", atom_to_list(node())}])), + ok. + +%%----------------------------------------------------------------- +%% Test Case: ifr_data +%% Description: +%%----------------------------------------------------------------- +ifr_data(doc) -> [""]; +ifr_data(suite) -> []; +ifr_data(_) -> + ?match({'EXIT', _}, orber_web:ifr_data(env, [])), + ?match({'EXIT', _}, orber_web:ifr_data(env, [{"node", localhost}, + {"table", "ir_ModuleDef"}])), + ?match({error, _}, orber_web:ifr_data(env, [{"node", "bad_host"}, + {"table", "ir_ModuleDef"}])), + ?match({'EXIT', _}, orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "bad_table"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_ModuleDef"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_InterfaceDef"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_StructDef"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_ExceptionDef"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_ConstantDef"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_EnumDef"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_AliasDef"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_AttributeDef"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_OperationDef"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_Contained"}])), + ?match([_H|_T], orber_web:ifr_data(env, [{"node", atom_to_list(node())}, + {"table", "ir_TypedefDef"}])), + ok. + +%%----------------------------------------------------------------- +%% Test Case: create +%% Description: +%%----------------------------------------------------------------- +create(doc) -> [""]; +create(suite) -> []; +create(_) -> + NodeStr = atom_to_list(node()), + ?match({'EXIT', _}, orber_web:create(env, [])), + ?match({'EXIT', _}, orber_web:create(env, [{"node", localhost}])), + ?match({error, _}, orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[bad_option 42]"}, + {"namestr", "[]"}, + {"bind", "rebind"}])), + ?match({error, _}, orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[bad_argument 42]"}, + {"options", "[]"}, + {"namestr", "[]"}, + {"bind", "rebind"}])), + + ?match([_, NodeStr|_T], orber_web:create(env, [{"node", NodeStr}])), + + [_,IOR] = ?match([_,_], orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[]"}, + {"namestr", ""}, + {"bind", "rebind"}])), + ?match(#'IOP_IOR'{}, corba:string_to_object(IOR)), + + [_,_,_,_,_,IOR2] = + ?match([_,_,_,_,_,_], orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[]"}, + {"namestr", "id1"}, + {"bind", "rebind"}])), + ?match(#'IOP_IOR'{}, corba:string_to_object(IOR2)), + + [_,_,_,IOR3] = + ?match([_,_,_,_], orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[{pseudo, true}]"}, + {"namestr", "id2"}, + {"bind", "rebind"}])), + ?match(#'IOP_IOR'{}, corba:string_to_object(IOR3)), + + [_,IOR4] =?match([_,_], orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[{pseudo, true}]"}, + {"namestr", ""}, + {"bind", "rebind"}])), + ?match(#'IOP_IOR'{}, corba:string_to_object(IOR4)), + + ?match([_], orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[{unknown, option}]"}, + {"namestr", "id1"}, + {"bind", "rebind"}])), + + ?match([_, "id1"], orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[]"}, + {"namestr", "id1"}, + {"bind", "bind"}])), + + ?match([_, "id2"], orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[{pseudo, true}]"}, + {"namestr", "id2"}, + {"bind", "bind"}])), + ok. + +%%----------------------------------------------------------------- +%% Test Case: delete_ctx +%% Description: +%%----------------------------------------------------------------- +delete_ctx(doc) -> [""]; +delete_ctx(suite) -> []; +delete_ctx(_) -> + ?match({ok, _}, orber_web:delete_ctx(env, [{"node", atom_to_list(node())}, + {"context", "id1"}])), + ?match([_H|_T], orber_web:add_ctx(env, [{"node", atom_to_list(node())}, + {"context", "root"}, + {"id", "id1"}])), + ?match([_H|_T], orber_web:delete_ctx(env, [{"node", atom_to_list(node())}, + {"context", "id1"}])), + ok. + +%%----------------------------------------------------------------- +%% Test Case: add_ctx +%% Description: +%%----------------------------------------------------------------- +add_ctx(doc) -> [""]; +add_ctx(suite) -> []; +add_ctx(_) -> + ?match({error, _}, orber_web:add_ctx(env, [{"node", "bad_node"}, + {"context", "root"}, + {"id", "id1"}])), + ?match([_H|_T], orber_web:add_ctx(env, [{"node", atom_to_list(node())}, + {"context", "root"}, + {"id", ""}])), + ?match([_H|_T], orber_web:add_ctx(env, [{"node", atom_to_list(node())}, + {"context", "root"}, + {"id", "id1"}])), + ?match([_H|_T], orber_web:add_ctx(env, [{"node", atom_to_list(node())}, + {"context", "id1"}, + {"id", "id2"}])), + ok. + +%%----------------------------------------------------------------- +%% Test Case: delete_obj +%% Description: +%%----------------------------------------------------------------- +delete_obj(doc) -> [""]; +delete_obj(suite) -> []; +delete_obj(_) -> + NodeStr = atom_to_list(node()), + ?match({error, _}, orber_web:delete_obj(env, [{"node", "bad_node"}, + {"context", "id1"}, + {"action", "unbind"}])), + ?match({error, _}, orber_web:delete_obj(env, [{"node", "bad_node"}, + {"context", "id1"}, + {"action", "both"}])), + ?match({'EXIT', _}, orber_web:delete_obj(env, [{"node", bad_node}, + {"context", "id1"}, + {"action", "both"}])), + ?match({error, _}, orber_web:delete_obj(env, [{"node", NodeStr}, + {"context", "non/existing"}, + {"action", "unbind"}])), + [_,_,_,_,_,IOR2] = + ?match([_,_,_,_,_,_], orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[]"}, + {"namestr", "id1"}, + {"bind", "rebind"}])), + ?match(#'IOP_IOR'{}, corba:string_to_object(IOR2)), + + ?match({error, _}, orber_web:delete_obj(env, [{"node", NodeStr}, + {"context", "bad/INS./id"}, + {"action", "unbind"}])), + + [_,_,_,IOR3] = + ?match([_,_,_,_], orber_web:create(env, [{"node", NodeStr}, + {"module", "orber_test_server"}, + {"arguments", "[]"}, + {"options", "[{pseudo, true}]"}, + {"namestr", "id2"}, + {"bind", "rebind"}])), + ?match(#'IOP_IOR'{}, corba:string_to_object(IOR3)), + + ?match([_, "id1"|_], orber_web:delete_obj(env, [{"node", NodeStr}, + {"context", "id1"}, + {"action", "unbind"}])), + ?match([_, "id2"|_], orber_web:delete_obj(env, [{"node", NodeStr}, + {"context", "id2"}, + {"action", "unbind"}])), + + + ok. + +%%----------------------------------------------------------------- +%% Test Case: server +%% Description: +%%----------------------------------------------------------------- +server(doc) -> [""]; +server(suite) -> []; +server(_) -> + NodeStr = "node=" ++ atom_to_list(node()), + {ok, Pid} = ?match({ok,_}, orber_web_server:start()), + ?match({error,{already_started, Pid}}, orber_web_server:start_link()), + ?match({error,{already_started,Pid}}, orber_web_server:start()), + ?match({orber, _}, orber_web_server:config_data()), + ?match([_H|_T], orber_web_server:ifr_select(env, "node=badnode")), + ?match([_H|_T], orber_web_server:ifr_select(env, "node=" ++ NodeStr)), + ?match([_H|_T], orber_web_server:menu(env, NodeStr)), + ?match([_H|_T], orber_web_server:configure(env, NodeStr ++ "&data=[{orber_debug_level, 9}]")), + ?match([_H|_T], orber_web_server:nameservice(env, NodeStr ++ "&context=root")), + ?match([_H|_T], orber_web_server:info(env, NodeStr)), + ?match([_H|_T], orber_web_server:ifr_data(env, NodeStr ++ "&table=ir_ModuleDef")), + ?match([_H|_T], orber_web_server:create(env, NodeStr)), + ?match([_H|_T], orber_web_server:add_ctx(env, NodeStr ++ "&context=root&id=id1")), + ?match([_H|_T], orber_web_server:delete_ctx(env, NodeStr++"&context=id1")), + ?match([_H|_T], orber_web_server:delete_obj(env, NodeStr++"&context=id1&action=unbind")), + ?match([_H|_T], orber_web_server:default_selection(env, NodeStr)), + ?match(ok, orber_web_server:stop()), + ok. + + diff --git a/lib/orber/test/tc_SUITE.erl b/lib/orber/test/tc_SUITE.erl new file mode 100644 index 0000000000..807a663219 --- /dev/null +++ b/lib/orber/test/tc_SUITE.erl @@ -0,0 +1,661 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%----------------------------------------------------------------- +%% +%% Description: +%% Test suite for the basic typecode functions +%% +%%----------------------------------------------------------------- +-module(tc_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-define(default_timeout, ?t:minutes(3)). + +-define(match(Expr), + fun() -> + case (catch (Expr)) of + AcTuAlReS when is_binary(AcTuAlReS)-> + io:format("###### ERROR ERROR ######~nRESULT: ~p~n", + [AcTuAlReS]), + exit(AcTuAlReS); + _ -> + ok + end + end()). +-define(SUB_ELIST, [{"null", orber_tc:null()}, + {"void", orber_tc:void()}, + {"short", orber_tc:short()}, + {"unsigned_short", orber_tc:unsigned_short()}, + {"long", orber_tc:long()}, + {"unsigned_long", orber_tc:unsigned_long()}, + {"long_long", orber_tc:long_long()}, + {"unsigned_long_long", orber_tc:unsigned_long_long()}, + {"float", orber_tc:'float'()}, + {"double", orber_tc:double()}, + {"longdouble", orber_tc:longdouble()}, + {"boolean", orber_tc:boolean()}, + {"char", orber_tc:char()}, + {"wchar", orber_tc:wchar()}, + {"octet", orber_tc:octet()}, + {"any", orber_tc:any()}, + {"typecode", orber_tc:typecode()}, + {"principal", orber_tc:principal()}, + {"object_reference", orber_tc:object_reference("Id", "Name")}]). + +-define(ELIST, [{"null", orber_tc:null()}, + {"void", orber_tc:void()}, + {"short", orber_tc:short()}, + {"unsigned_short", orber_tc:unsigned_short()}, + {"long", orber_tc:long()}, + {"unsigned_long", orber_tc:unsigned_long()}, + {"long_long", orber_tc:long_long()}, + {"unsigned_long_long", orber_tc:unsigned_long_long()}, + {"float", orber_tc:'float'()}, + {"double", orber_tc:double()}, + {"longdouble", orber_tc:longdouble()}, + {"boolean", orber_tc:boolean()}, + {"char", orber_tc:char()}, + {"wchar", orber_tc:wchar()}, + {"octet", orber_tc:octet()}, + {"any", orber_tc:any()}, + {"typecode", orber_tc:typecode()}, + {"principal", orber_tc:principal()}, + {"object_reference", orber_tc:object_reference("Id", "Name")}, + {"struct", orber_tc:struct("Id", "Name", ?SUB_ELIST)}, + {"enum", orber_tc:enum("Id", "Name", ["E1", "E2"])}, + {"string", orber_tc:string(1)}, + {"wstring", orber_tc:wstring(0)}, + {"sequence", orber_tc:sequence(orber_tc:enum("Id", "Name", + ["E1", "E2"]), 0)}, + {"array", orber_tc:array(orber_tc:enum("Id", "Name", + ["E1", "E2"]), 2)}, + {"alias", orber_tc:alias("id", "name", + orber_tc:enum("Id", "Name", + ["E1", "E2"]))}, + {"exception", orber_tc:exception("Id", "Name", ?SUB_ELIST)}]). + +-define(VELIST, [{"null", orber_tc:null(), 42}, + {"void", orber_tc:void(), 42}, + {"short", orber_tc:short(), 42}, + {"unsigned_short", orber_tc:unsigned_short(), 42}, + {"long", orber_tc:long(), 42}, + {"unsigned_long", orber_tc:unsigned_long(), 42}, + {"long_long", orber_tc:long_long(), 42}, + {"unsigned_long_long", orber_tc:unsigned_long_long(), 42}, + {"float", orber_tc:'float'(), 42}, + {"double", orber_tc:double(), 42}, + {"longdouble", orber_tc:longdouble(), 42}, + {"boolean", orber_tc:boolean(), 42}, + {"char", orber_tc:char(), 42}, + {"wchar", orber_tc:wchar(), 42}, + {"octet", orber_tc:octet(), 42}, + {"any", orber_tc:any(), 42}, + {"typecode", orber_tc:typecode(), 42}, + {"principal", orber_tc:principal(), 42}, + {"object_reference", orber_tc:object_reference("Id", "Name"), 42}, + {"struct", orber_tc:struct("Id", "Name", ?SUB_ELIST), 42}, + {"enum", orber_tc:enum("Id", "Name", ["E1", "E2"]), 42}, + {"string", orber_tc:string(1), 42}, + {"wstring", orber_tc:wstring(0), 42}, + {"sequence", orber_tc:sequence(orber_tc:enum("Id", "Name", + ["E1", "E2"]), 0), 42}, + {"array", orber_tc:array(orber_tc:enum("Id", "Name", + ["E1", "E2"]), 2), 42}, + {"alias", orber_tc:alias("id", "name", + orber_tc:enum("Id", "Name", + ["E1", "E2"])), 42}, + {"exception", orber_tc:exception("Id", "Name", ?SUB_ELIST), 42}]). + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). +-compile(export_all). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> + [null, void, + short, ushort, + long, ulong, + longlong, ulonglong, + boolean, char, wchar, octet, + float, double, longdouble, + any, typecode, principal, object_reference, + struct, union, enum, string, wstring, sequence, array, + alias, exception, fixed, value, value_box, native, + abstract_interface, indirection, get_tc]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +%%----------------------------------------------------------------- +%% Test Case: null test +%% Description: +%%----------------------------------------------------------------- +null(doc) -> []; +null(suite) -> []; +null(_) -> + ?line true = orber_tc:check_tc(orber_tc:null()), + ?line code(orber_tc:null()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: void test +%% Description: +%%----------------------------------------------------------------- +void(doc) -> []; +void(suite) -> []; +void(_) -> + ?line true = orber_tc:check_tc(orber_tc:void()), + ?line code(orber_tc:void()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: short integer test +%% Description: +%%----------------------------------------------------------------- +short(doc) -> []; +short(suite) -> []; +short(_) -> + ?line true = orber_tc:check_tc(orber_tc:short()), + ?line code(orber_tc:short()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: unsigned short integer test +%% Description: +%%----------------------------------------------------------------- +ushort(doc) -> []; +ushort(suite) -> []; +ushort(_) -> + ?line true = orber_tc:check_tc(orber_tc:unsigned_short()), + ?line code(orber_tc:unsigned_short()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: long integer test +%% Description: +%%----------------------------------------------------------------- +long(doc) -> []; +long(suite) -> []; +long(_) -> + ?line true = orber_tc:check_tc(orber_tc:long()), + ?line code(orber_tc:long()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: unsigned long integer test +%% Description: +%%----------------------------------------------------------------- +ulong(doc) -> []; +ulong(suite) -> []; +ulong(_) -> + ?line true = orber_tc:check_tc(orber_tc:unsigned_long()), + ?line code(orber_tc:unsigned_long()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: long integer test +%% Description: +%%----------------------------------------------------------------- +longlong(doc) -> []; +longlong(suite) -> []; +longlong(_) -> + ?line true = orber_tc:check_tc(orber_tc:long_long()), + ?line code(orber_tc:long_long()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: unsigned long integer test +%% Description: +%%----------------------------------------------------------------- +ulonglong(doc) -> []; +ulonglong(suite) -> []; +ulonglong(_) -> + ?line true = orber_tc:check_tc(orber_tc:unsigned_long_long()), + ?line code(orber_tc:unsigned_long_long()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: float test +%% Description: +%%----------------------------------------------------------------- +float(doc) -> []; +float(suite) -> []; +float(_) -> + ?line true = orber_tc:check_tc(orber_tc:'float'()), + ?line code(orber_tc:'float'()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: double test +%% Description: +%%----------------------------------------------------------------- +double(doc) -> []; +double(suite) -> []; +double(_) -> + ?line true = orber_tc:check_tc(orber_tc:double()), + ?line code(orber_tc:double()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: longdouble test +%% Description: +%%----------------------------------------------------------------- +longdouble(doc) -> []; +longdouble(suite) -> []; +longdouble(_) -> + ?line true = orber_tc:check_tc(orber_tc:longdouble()), + ?line code(orber_tc:longdouble()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: boolean test +%% Description: +%%----------------------------------------------------------------- +boolean(doc) -> []; +boolean(suite) -> []; +boolean(_) -> + ?line true = orber_tc:check_tc(orber_tc:boolean()), + ?line code(orber_tc:boolean()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: character test +%% Description: +%%----------------------------------------------------------------- +char(doc) -> []; +char(suite) -> []; +char(_) -> + ?line true = orber_tc:check_tc(orber_tc:char()), + ?line code(orber_tc:char()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: character test +%% Description: +%%----------------------------------------------------------------- +wchar(doc) -> []; +wchar(suite) -> []; +wchar(_) -> + ?line true = orber_tc:check_tc(orber_tc:wchar()), + ?line code(orber_tc:wchar()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: octet test +%% Description: +%%----------------------------------------------------------------- +octet(doc) -> []; +octet(suite) -> []; +octet(_) -> + ?line true = orber_tc:check_tc(orber_tc:octet()), + ?line code(orber_tc:octet()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: any test +%% Description: +%%----------------------------------------------------------------- +any(doc) -> []; +any(suite) -> []; +any(_) -> + ?line true = orber_tc:check_tc(orber_tc:any()), + ?line code(orber_tc:any()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: typecode test +%% Description: +%%----------------------------------------------------------------- +typecode(doc) -> []; +typecode(suite) -> []; +typecode(_) -> + ?line true = orber_tc:check_tc(orber_tc:typecode()), + ?line code(orber_tc:typecode()), + ok. + +%%----------------------------------------------------------------- +%% Test Case: principal test +%% Description: +%%----------------------------------------------------------------- +principal(doc) -> []; +principal(suite) -> []; +principal(_) -> + ?line true = orber_tc:check_tc(orber_tc:principal()), + ?line code(orber_tc:principal()), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: object_reference test +%% Description: +%%----------------------------------------------------------------- +object_reference(doc) -> []; +object_reference(suite) -> []; +object_reference(_) -> + ?line true = orber_tc:check_tc(orber_tc:object_reference("Id", "Name")), + ?line false = orber_tc:check_tc(orber_tc:object_reference(42, "Name")), + ?line false = orber_tc:check_tc(orber_tc:object_reference("Id", 42)), + ?line code(orber_tc:object_reference("Id", "Name")), + ?line ?match(code(orber_tc:object_reference(42, "Name"))), + ?line ?match(code(orber_tc:object_reference("Id", 42))), + ok. + +%%----------------------------------------------------------------- +%% Test Case: struct +%% Description: +%%----------------------------------------------------------------- +struct(doc) -> []; +struct(suite) -> []; +struct(_) -> + ?line true = orber_tc:check_tc(orber_tc:struct("Id", "Name", ?ELIST)), + ?line false = orber_tc:check_tc(orber_tc:struct(42, "Name", ?ELIST)), + ?line false = orber_tc:check_tc(orber_tc:struct("Id", false, ?ELIST)), + ?line false = orber_tc:check_tc(orber_tc:struct("Id", "Name", ?VELIST)), + ?line false = orber_tc:check_tc(orber_tc:struct("Id", "Name", "wrong")), + ?line code(orber_tc:struct("Id", "Name", ?ELIST)), + ?line ?match(code(orber_tc:struct(42, "Name", ?ELIST))), + ?line ?match(code(orber_tc:struct("Id", false, ?ELIST))), + ?line ?match(code(orber_tc:struct("Id", "Name", ?VELIST))), + ?line ?match(code(orber_tc:struct("Id", "Name", "wrong"))), + ok. + +%%----------------------------------------------------------------- +%% Test Case: union +%% Description: +%%----------------------------------------------------------------- +union(doc) -> []; +union(suite) -> []; +union(_) -> + ?line true = orber_tc:check_tc(orber_tc:union("Id", "Name", orber_tc:long(), + -1, [{1, "long", orber_tc:long()}, + {2, "longlong", orber_tc:long()}])), + ?line false = orber_tc:check_tc(orber_tc:union("Id", "Name", orber_tc:long(), + -1, ?ELIST)), + ?line false = orber_tc:check_tc(orber_tc:union(42, "Name", orber_tc:long(), + -1, [{1, "long", orber_tc:long()}, + {2, "longlong", orber_tc:long()}])), + ?line false = orber_tc:check_tc(orber_tc:union("Id", false, orber_tc:long(), + -1, [{1, "long", orber_tc:long()}, + {2, "longlong", orber_tc:long()}])), + ?line false = orber_tc:check_tc(orber_tc:union("Id", "Name", bad_tc, + -1, [{1, "long", orber_tc:long()}, + {2, "longlong", orber_tc:long()}])), + ?line false = orber_tc:check_tc(orber_tc:union("Id", "Name", orber_tc:long(), + "wrong", [{1, "long", orber_tc:long()}, + {2, "longlong", orber_tc:long()}])), + + ?line code(orber_tc:union("Id", "Name", orber_tc:long(), + -1, [{1, "long", orber_tc:long()}, + {2, "longlong", orber_tc:long()}])), + ok. + + +%%----------------------------------------------------------------- +%% Test Case: enum test +%% Description: +%%----------------------------------------------------------------- +enum(doc) -> []; +enum(suite) -> []; +enum(_) -> + ?line true = orber_tc:check_tc(orber_tc:enum("Id", "Name", + ["E1", "E2", "E3"])), + ?line false = orber_tc:check_tc(orber_tc:enum(42, "Name", + ["E1", "E2", "E3"])), + ?line false = orber_tc:check_tc(orber_tc:enum("Id", false, + ["E1", "E2", "E3"])), + ?line false = orber_tc:check_tc(orber_tc:enum("Id", "Name", + ["E1", false, "E3"])), + ?line code(orber_tc:enum("Id", "Name", ["E1", "E2", "E3"])), + ?line ?match(code(orber_tc:enum(false, "Name", ["E1", "E2", "E3"]))), + ?line ?match(code(orber_tc:enum("Id", 42, ["E1", "E2", "E3"]))), + ?line ?match(code(orber_tc:enum("Id", "Name", ["E1", false, "E3"]))), + ok. + +%%----------------------------------------------------------------- +%% Test Case: string +%% Description: +%%----------------------------------------------------------------- +string(doc) -> []; +string(suite) -> []; +string(_) -> + ?line true = orber_tc:check_tc(orber_tc:string(0)), + ?line true = orber_tc:check_tc(orber_tc:string(1)), + ?line false = orber_tc:check_tc(orber_tc:string("wrong")), + ?line code(orber_tc:string(0)), + ?line code(orber_tc:string(1)), + ?line ?match(code(orber_tc:string(-1))), + ?line ?match(code(orber_tc:string(?ULONGMAX+1))), + ?line ?match(code(orber_tc:string("wrong"))), + ok. + +%%----------------------------------------------------------------- +%% Test Case: wstring +%% Description: +%%----------------------------------------------------------------- +wstring(doc) -> []; +wstring(suite) -> []; +wstring(_) -> + ?line true = orber_tc:check_tc(orber_tc:wstring(0)), + ?line true = orber_tc:check_tc(orber_tc:wstring(1)), + ?line false = orber_tc:check_tc(orber_tc:wstring("wrong")), + ?line code(orber_tc:wstring(0)), + ?line code(orber_tc:wstring(1)), + ?line ?match(code(orber_tc:wstring(-1))), + ?line ?match(code(orber_tc:wstring(?ULONGMAX+1))), + ?line ?match(code(orber_tc:wstring(false))), + ok. + +%%----------------------------------------------------------------- +%% Test Case: sequence +%% Description: +%%----------------------------------------------------------------- +sequence(doc) -> []; +sequence(suite) -> []; +sequence(_) -> + ?line true = orber_tc:check_tc(orber_tc:sequence(orber_tc:struct("Id", "Name", ?ELIST), 0)), + ?line code(orber_tc:sequence(orber_tc:struct("Id", "Name", ?ELIST), 0)), + ok. + +%%----------------------------------------------------------------- +%% Test Case: array +%% Description: +%%----------------------------------------------------------------- +array(doc) -> []; +array(suite) -> []; +array(_) -> + ?line true = orber_tc:check_tc(orber_tc:array(orber_tc:struct("Id", "Name", ?ELIST), 1)), + ?line code(orber_tc:array(orber_tc:struct("Id", "Name", ?ELIST), 1)), + ok. + +%%----------------------------------------------------------------- +%% Test Case: alias +%% Description: +%%----------------------------------------------------------------- +alias(doc) -> []; +alias(suite) -> []; +alias(_) -> + ?line true = orber_tc:check_tc(orber_tc:alias("Id", "Name", orber_tc:struct("Id", "Name", ?ELIST))), + ?line false = orber_tc:check_tc(orber_tc:alias(false, "Name", orber_tc:struct("Id", "Name", ?ELIST))), + ?line false = orber_tc:check_tc(orber_tc:alias("Id", 42, orber_tc:struct("Id", "Name", ?ELIST))), + ?line false = orber_tc:check_tc(orber_tc:alias("Id", "Name", "wrong")), + ?line code(orber_tc:alias("Id", "Name", orber_tc:struct("Id", "Name", ?ELIST))), + ?line ?match(code(orber_tc:alias("Id", "Name", orber_tc:struct("Id", "Name", ?VELIST)))), + ok. + +%%----------------------------------------------------------------- +%% Test Case: exception +%% Description: +%%----------------------------------------------------------------- +exception(doc) -> []; +exception(suite) -> []; +exception(_) -> + ?line true = orber_tc:check_tc(orber_tc:exception("Id", "Name", ?ELIST)), + ?line false = orber_tc:check_tc(orber_tc:exception(42, "Name", ?ELIST)), + ?line false = orber_tc:check_tc(orber_tc:exception("Id", false, ?ELIST)), + ?line false = orber_tc:check_tc(orber_tc:exception("Id", "Name", "wrong")), + ?line code(orber_tc:exception("Id", "Name", ?ELIST)), + ?line ?match(code(orber_tc:exception(42, "Name", ?ELIST))), + ?line ?match(code(orber_tc:exception("Id", false, ?ELIST))), + ?line ?match(code(orber_tc:exception("Id", "Name", "wrong"))), + + ok. + +%%----------------------------------------------------------------- +%% Test Case: fixed +%% Description: +%%----------------------------------------------------------------- +fixed(doc) -> []; +fixed(suite) -> []; +fixed(_) -> + ?line true = orber_tc:check_tc(orber_tc:fixed(25, 2)), + ?line code(orber_tc:fixed(25, 2)), + ok. + +%%----------------------------------------------------------------- +%% Test Case: value +%% Description: +%%----------------------------------------------------------------- +value(doc) -> []; +value(suite) -> []; +value(_) -> + ?line true = orber_tc:check_tc(orber_tc:value("Id", "Name", 42, + orber_tc:fixed(25, 2), ?VELIST)), + ?line false = orber_tc:check_tc(orber_tc:value(42, "Name", 42, + orber_tc:fixed(25, 2), ?VELIST)), + ?line false = orber_tc:check_tc(orber_tc:value("Id", 42, 42, + orber_tc:fixed(25, 2), ?VELIST)), + ?line false = orber_tc:check_tc(orber_tc:value("Id", "Name", "wrong", + orber_tc:fixed(25, 2), ?VELIST)), + ?line false = orber_tc:check_tc(orber_tc:value("Id", "Name", "42", + orber_tc:fixed(25, 2), ?VELIST)), + ?line false = orber_tc:check_tc(orber_tc:value("Id", "Name", "42", + ?VELIST, ?VELIST)), + ?line false = orber_tc:check_tc(orber_tc:value("Id", "Name", "42", + orber_tc:fixed(25, 2), false)), + + ?line code(orber_tc:value("Id", "Name", 42, orber_tc:long(), ?VELIST)), + ok. + +%%----------------------------------------------------------------- +%% Test Case: value_box +%% Description: +%%----------------------------------------------------------------- +value_box(doc) -> []; +value_box(suite) -> []; +value_box(_) -> + ?line true = orber_tc:check_tc(orber_tc:value_box("Id", "Name", + orber_tc:fixed(25, 2))), + ?line false = orber_tc:check_tc(orber_tc:value_box(42, "Name", + orber_tc:fixed(25, 2))), + ?line false = orber_tc:check_tc(orber_tc:value_box("Id", 42, + orber_tc:fixed(25, 2))), + ?line false = orber_tc:check_tc(orber_tc:value_box("Id", "Name", "wrong")), + ?line code(orber_tc:value_box("Id", "Name", orber_tc:long())), + ?line ?match(code(orber_tc:value_box(42, "Name", orber_tc:short()))), + ?line ?match(code(orber_tc:value_box("Id", 42, orber_tc:char()))), + ?line ?match(code(orber_tc:value_box("Id", "Name", false))), + ok. + +%%----------------------------------------------------------------- +%% Test Case: native +%% Description: +%%----------------------------------------------------------------- +native(doc) -> []; +native(suite) -> []; +native(_) -> + ?line true = orber_tc:check_tc(orber_tc:native("Id", "Name")), + ?line false = orber_tc:check_tc(orber_tc:native(42, "Name")), + ?line false = orber_tc:check_tc(orber_tc:native("Id", 42)), + ?line code(orber_tc:native("Id", "Name")), + ?line ?match(code(orber_tc:native(42, "Name"))), + ?line ?match(code(orber_tc:native("Id", 42))), + ok. + +%%----------------------------------------------------------------- +%% Test Case: abstract_interface +%% Description: +%%----------------------------------------------------------------- +abstract_interface(doc) -> []; +abstract_interface(suite) -> []; +abstract_interface(_) -> + ?line true = orber_tc:check_tc(orber_tc:abstract_interface("RepId", "Name")), + ?line false = orber_tc:check_tc(orber_tc:abstract_interface(false, "Name")), + ?line false = orber_tc:check_tc(orber_tc:abstract_interface("RepId", 42)), + ?line code(orber_tc:abstract_interface("RepId", "Name")), + ?line ?match(code(orber_tc:abstract_interface(42, "Name"))), + ?line ?match(code(orber_tc:abstract_interface("Id", 42))), + ok. + + + +%%----------------------------------------------------------------- +%% Test Case: indirection +%% Description: +%%----------------------------------------------------------------- +indirection(doc) -> []; +indirection(suite) -> []; +indirection(_) -> + ?line true = orber_tc:check_tc({'none', 42}), + ok. + +%%----------------------------------------------------------------- +%% Test Case: get_tc +%% Description: +%%----------------------------------------------------------------- +get_tc(doc) -> []; +get_tc(suite) -> []; +get_tc(_) -> + TC = 'CosNaming_Binding':tc(), + ?line TC = orber_tc:get_tc({'CosNaming_Binding', 42}), + ?line ?match(orber_tc:get_tc({'none', 42})), + ok. + +%%----------------------------------------------------------------- +%% MISC Operations +%%----------------------------------------------------------------- +code(Value) -> + cdr_encode:enc_type({1,2}, tk_TypeCode, Value). diff --git a/lib/os_mon/test/Makefile b/lib/os_mon/test/Makefile new file mode 100644 index 0000000000..c87285e38b --- /dev/null +++ b/lib/os_mon/test/Makefile @@ -0,0 +1,92 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1997-2010. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +include $(ERL_TOP)/make/target.mk + +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +MODULES= \ + os_mon_SUITE \ + disksup_SUITE \ + memsup_SUITE \ + cpu_sup_SUITE \ + os_mon_mib_SUITE \ + os_sup_SUITE \ + os_mon_conf + +EBIN = . + +HRL_FILES= + +ERL_FILES= $(MODULES:%=%.erl) + +TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + +SOURCE = $(ERL_FILES) $(HRL_FILES) + +EMAKEFILE=Emakefile + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/os_mon_test + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_MAKE_FLAGS += +ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \ + -I$(ERL_TOP)/lib/snmp/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +make_emakefile: + $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\ + > $(EMAKEFILE) + +tests debug opt: make_emakefile + erl $(ERL_MAKE_FLAGS) -make + +clean: + rm -f $(EMAKEFILE) + rm -f $(TARGET_FILES) + rm -f core *~ + +docs: + + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_tests_spec: make_emakefile + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) os_mon.spec $(EMAKEFILE) $(SOURCE) $(RELSYSDIR) + +## tar chf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + +release_docs_spec: diff --git a/lib/os_mon/test/cpu_sup_SUITE.erl b/lib/os_mon/test/cpu_sup_SUITE.erl new file mode 100644 index 0000000000..45f9d981d1 --- /dev/null +++ b/lib/os_mon/test/cpu_sup_SUITE.erl @@ -0,0 +1,282 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2002-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(cpu_sup_SUITE). +-include("test_server.hrl"). + +%% Test server specific exports +-export([all/1]). +-export([init_per_suite/1, end_per_suite/1]). +-export([init_per_testcase/2, end_per_testcase/2]). + +%% Test cases +-export([load_api/1]). +-export([util_api/1, util_values/1]). +-export([port/1]). +-export([terminate/1, unavailable/1, restart/1]). + +%% Default timetrap timeout (set in init_per_testcase) +-define(default_timeout, ?t:minutes(1)). + +init_per_suite(Config) when is_list(Config) -> + ?line ok = application:start(os_mon), + Config. + +end_per_suite(Config) when is_list(Config) -> + ?line ok = application:stop(os_mon), + Config. + +init_per_testcase(_Case, Config) -> + Dog = ?t:timetrap(?default_timeout), + [{watchdog, Dog} | Config]. + +end_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +all(suite) -> + case ?t:os_type() of + {unix, sunos} -> + [load_api, util_api, util_values, port, + {conf, terminate, [unavailable], restart}]; + {unix, linux} -> + [load_api, util_api, util_values, port, + {conf, terminate, [unavailable], restart}]; + {unix, _OSname} -> + [load_api]; + _OS -> + [unavailable] + end. + +load_api(suite) -> + []; +load_api(doc) -> + ["Test of load API functions"]; +load_api(Config) when is_list(Config) -> + + %% nprocs() + ?line N = cpu_sup:nprocs(), + ?line true = is_integer(N), + ?line true = N>0, + + %% avg1() + ?line Load1 = cpu_sup:avg1(), + ?line true = is_integer(Load1), + ?line true = Load1>0, + + %% avg5() + ?line Load5 = cpu_sup:avg5(), + ?line true = is_integer(Load5), + ?line true = Load5>0, + + %% avg15() + ?line Load15 = cpu_sup:avg15(), + ?line true = is_integer(Load15), + ?line true = Load15>0, + + ok. + +util_api(suite) -> + []; +util_api(doc) -> + ["Test of utilization API functions"]; +util_api(Config) when is_list(Config) -> + %% Some useful funs when testing util/1 + BusyP = fun({user, _Share}) -> true; + ({nice_user, _Share}) -> true; + ({kernel, _Share}) -> true; + ({hard_irq, _Share}) -> true; + ({soft_irq, _Share}) -> true; + (_) -> false + end, + NonBusyP = fun({wait, _Share}) -> true; + ({idle, _Share}) -> true; + ({steal, _Share}) -> true; + (_) -> false + end, + Sum = fun({_Tag, X}, Acc) -> Acc+X end, + + %% util() + ?line Util1 = cpu_sup:util(), + ?line true = is_number(Util1), + ?line true = Util1>0, + ?line Util2 = cpu_sup:util(), + ?line true = is_number(Util2), + ?line true = Util2>0, + + %% util([]) + ?line {all, Busy1, NonBusy1, []} = cpu_sup:util([]), + ?line 100.00 = Busy1 + NonBusy1, + + %% util([detailed]) + ?line {Cpus2, Busy2, NonBusy2, []} = cpu_sup:util([detailed]), + ?line true = lists:all(fun(X) -> is_integer(X) end, Cpus2), + ?line true = lists:all(BusyP, Busy2), + ?line true = lists:all(NonBusyP, NonBusy2), + ?line 100.00 = lists:foldl(Sum,0,Busy2)+lists:foldl(Sum,0,NonBusy2), + + %% util([per_cpu]) + ?line [{Cpu3, Busy3, NonBusy3, []}|_] = cpu_sup:util([per_cpu]), + ?line true = is_integer(Cpu3), + ?line 100.00 = Busy3 + NonBusy3, + + %% util([detailed, per_cpu]) + ?line [{Cpu4, Busy4, NonBusy4, []}|_] = + cpu_sup:util([detailed, per_cpu]), + ?line true = is_integer(Cpu4), + ?line true = lists:all(BusyP, Busy2), + ?line true = lists:all(NonBusyP, NonBusy2), + ?line 100.00 = lists:foldl(Sum,0,Busy4)+lists:foldl(Sum,0,NonBusy4), + + %% bad util/1 calls + ?line {'EXIT',{badarg,_}} = (catch cpu_sup:util(detailed)), + ?line {'EXIT',{badarg,_}} = (catch cpu_sup:util([detialed])), + + ok. + +-define(SPIN_TIME, 1000). + +util_values(suite) -> + []; +util_values(doc) -> + ["Test utilization values"]; +util_values(Config) when is_list(Config) -> + + Tester = self(), + Ref = make_ref(), + Loop = fun (L) -> L(L) end, + Spinner = fun () -> + Looper = spawn_link(fun () -> Loop(Loop) end), + receive after ?SPIN_TIME -> ok end, + unlink(Looper), + exit(Looper, kill), + Tester ! Ref + end, + + ?line cpu_sup:util(), + + ?line spawn_link(Spinner), + ?line receive Ref -> ok end, + ?line HighUtil1 = cpu_sup:util(), + + ?line receive after ?SPIN_TIME -> ok end, + ?line LowUtil1 = cpu_sup:util(), + + ?line spawn_link(Spinner), + ?line receive Ref -> ok end, + ?line HighUtil2 = cpu_sup:util(), + + ?line receive after ?SPIN_TIME -> ok end, + ?line LowUtil2 = cpu_sup:util(), + + Utils = [{high1,HighUtil1}, {low1,LowUtil1}, + {high2,HighUtil2}, {low2,LowUtil2}], + ?t:format("Utils: ~p~n", [Utils]), + + ?line false = LowUtil1 > HighUtil1, + ?line false = LowUtil1 > HighUtil2, + ?line false = LowUtil2 > HighUtil1, + ?line false = LowUtil2 > HighUtil2, + + ok. + + +% Outdated +% The portprogram is now restarted if killed, and not by os_mon... + +port(suite) -> + []; +port(doc) -> + ["Test that cpu_sup handles a terminating port program"]; +port(Config) when is_list(Config) -> + case cpu_sup_os_pid() of + {ok, PidStr} -> + %% Monitor cpu_sup + ?line MonRef = erlang:monitor(process, cpu_sup), + ?line N1 = cpu_sup:nprocs(), + ?line true = N1>0, + + %% Kill the port program + case os:cmd("kill -9 " ++ PidStr) of + [] -> + %% cpu_sup should not terminate + receive + {'DOWN', MonRef, _, _, Reason} -> + ?line ?t:fail({unexpected_exit_reason, Reason}) + after 3000 -> + ok + end, + + %% Give cpu_sup time to restart cpu_sup port + ?t:sleep(?t:seconds(3)), + ?line N2 = cpu_sup:nprocs(), + ?line true = N2>0, + + erlang:demonitor(MonRef), + ok; + + Line -> + erlang:demonitor(MonRef), + {skip, {not_killed, Line}} + end; + _ -> + {skip, os_pid_not_found } + end. + +terminate(suite) -> + []; +terminate(Config) when is_list(Config) -> + ?line ok = application:set_env(os_mon, start_cpu_sup, false), + ?line ok = supervisor:terminate_child(os_mon_sup, cpu_sup), + ok. + +unavailable(suite) -> + []; +unavailable(doc) -> + ["Test correct behaviour when service is unavailable"]; +unavailable(Config) when is_list(Config) -> + + %% Make sure all API functions return their dummy values + ?line 0 = cpu_sup:nprocs(), + ?line 0 = cpu_sup:avg1(), + ?line 0 = cpu_sup:avg5(), + ?line 0 = cpu_sup:avg15(), + ?line 0 = cpu_sup:util(), + ?line {all,0,0,[]} = cpu_sup:util([]), + ?line {all,0,0,[]} = cpu_sup:util([detailed]), + ?line {all,0,0,[]} = cpu_sup:util([per_cpu]), + ?line {all,0,0,[]} = cpu_sup:util([detailed,per_cpu]), + + ok. + +restart(suite) -> + []; +restart(Config) when is_list(Config) -> + ?line ok = application:set_env(os_mon, start_cpu_sup, true), + ?line {ok, _Pid} = supervisor:restart_child(os_mon_sup, cpu_sup), + ok. + +%% Aux + +cpu_sup_os_pid() -> + Str = os:cmd("ps -e | grep '[c]pu_sup'"), + case io_lib:fread("~s", Str) of + {ok, [Pid], _Rest} -> {ok, Pid}; + _ -> {error, pid_not_found} + end. diff --git a/lib/os_mon/test/disksup_SUITE.erl b/lib/os_mon/test/disksup_SUITE.erl new file mode 100644 index 0000000000..987d631c36 --- /dev/null +++ b/lib/os_mon/test/disksup_SUITE.erl @@ -0,0 +1,426 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(disksup_SUITE). +-include("test_server.hrl"). + +%% Test server specific exports +-export([all/1]). +-export([init_per_suite/1, end_per_suite/1]). +-export([init_per_testcase/2, end_per_testcase/2]). + +%% Test cases +-export([api/1, config/1, alarm/1]). +-export([port/1]). +-export([terminate/1, unavailable/1, restart/1]). +-export([otp_5910/1]). + +%% Default timetrap timeout (set in init_per_testcase) +-define(default_timeout, ?t:minutes(1)). + +init_per_suite(Config) when is_list(Config) -> + ?line ok = application:start(os_mon), + Config. + +end_per_suite(Config) when is_list(Config) -> + ?line ok = application:stop(os_mon), + Config. + +init_per_testcase(_Case, Config) -> + Dog = ?t:timetrap(?default_timeout), + [{watchdog,Dog} | Config]. + +end_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +all(suite) -> + Bugs = [otp_5910], + case ?t:os_type() of + {unix, sunos} -> + [api, config, alarm, port, + {conf, terminate, [unavailable], restart}] ++ Bugs; + {unix, _OSname} -> + [api, alarm] ++ Bugs; + {win32, _OSname} -> + [api, alarm] ++ Bugs; + _OS -> + [unavailable] + end. + +api(suite) -> + []; +api(doc) -> + ["Test of API functions"]; +api(Config) when is_list(Config) -> + + %% get_disk_data() + ?line [{Id, KByte, Capacity}|_] = disksup:get_disk_data(), + ?line true = io_lib:printable_list(Id), + ?line true = is_integer(KByte), + ?line true = is_integer(Capacity), + ?line true = KByte>0, + ?line true = Capacity>0, + + %% get_check_interval() + ?line 1800000 = disksup:get_check_interval(), + + %% set_check_interval(Minutes) + ?line ok = disksup:set_check_interval(20), + ?line 1200000 = disksup:get_check_interval(), + ?line {'EXIT',{badarg,_}} = (catch disksup:set_check_interval(0.5)), + ?line 1200000 = disksup:get_check_interval(), + ?line ok = disksup:set_check_interval(30), + + %% get_almost_full_threshold() + ?line 80 = disksup:get_almost_full_threshold(), + + %% set_almost_full_threshold(Float) + ?line ok = disksup:set_almost_full_threshold(0.90), + ?line 90 = disksup:get_almost_full_threshold(), + ?line {'EXIT',{badarg,_}} = + (catch disksup:set_almost_full_threshold(-0.5)), + ?line 90 = disksup:get_almost_full_threshold(), + ?line ok = disksup:set_almost_full_threshold(0.80), + + ok. + +config(suite) -> + []; +config(doc) -> + ["Test configuration"]; +config(Config) when is_list(Config) -> + + %% Change configuration parameters and make sure change is reflected + %% when disksup is restarted + ?line ok = + application:set_env(os_mon, disk_space_check_interval, 29), + ?line ok = + application:set_env(os_mon, disk_almost_full_threshold, 0.81), + + ?line ok = supervisor:terminate_child(os_mon_sup, disksup), + ?line {ok, _Child1} = supervisor:restart_child(os_mon_sup, disksup), + + ?line 1740000 = disksup:get_check_interval(), + ?line 81 = disksup:get_almost_full_threshold(), + + %% Also try this with bad parameter values, should be ignored + ?line ok = + application:set_env(os_mon, disk_space_check_interval, 0.5), + ?line ok = + application:set_env(os_mon, disk_almost_full_threshold, -0.81), + + ?line ok = supervisor:terminate_child(os_mon_sup, disksup), + ?line {ok, _Child2} = supervisor:restart_child(os_mon_sup, disksup), + + ?line 1800000 = disksup:get_check_interval(), + ?line 80 = disksup:get_almost_full_threshold(), + + %% Reset configuration parameters + ?line ok = + application:set_env(os_mon, disk_space_check_interval, 30), + ?line ok = + application:set_env(os_mon, disk_almost_full_threshold, 0.80), + + ok. + +%%---------------------------------------------------------------------- +%% NOTE: The test case is a bit weak as it will fail if the disk usage +%% changes too much during its course, or if there are timing problems +%% with the alarm_handler receiving the alarms too late +%%---------------------------------------------------------------------- +alarm(suite) -> + []; +alarm(doc) -> + ["Test that alarms are set and cleared"]; +alarm(Config) when is_list(Config) -> + + %% Find out how many disks exceed the threshold + %% and make sure the corresponding number of alarms is set + ?line Threshold1 = disksup:get_almost_full_threshold(), % 80 + ?line Data1 = disksup:get_disk_data(), + ?line Over1 = over_threshold(Data1, Threshold1), + ?line Alarms1 = get_alarms(), + if + Over1==length(Alarms1) -> + ?line true; + true -> + dump_info(), + ?line ?t:fail({bad_alarms, Threshold1, Data1, Alarms1}) + end, + + %% Try to find a disk with space usage below Threshold1, + %% lower the threshold accordingly and make sure new alarms are set + Fun1 = fun({_Id, _Kbyte, Capacity}) -> + if + Capacity>0, Capacity<Threshold1 -> true; + true -> false + end + end, + ?line case until(Fun1, Data1) of + {_, _, Cap1} -> + Threshold2 = Cap1-1, + ?line ok = + disksup:set_almost_full_threshold(Threshold2/100), + ?line disksup ! timeout, % force a disk check + ?line Data2 = disksup:get_disk_data(), + ?line Over2 = over_threshold(Data2, Threshold2), + ?line Alarms2 = get_alarms(), + if + Over2==length(Alarms2), Over2>Over1 -> + ?line true; + true -> + dump_info(), + ?line ?t:fail({bad_alarms, Threshold2, Data2, Alarms2}) + end; + false -> + ?line ignore + end, + + %% Find out the highest space usage among all disks + %% and try to raise the threshold above this value, + %% make sure all alarms are cleared + Fun2 = fun({_Id, _Kbyte, Capacity}, MaxAcc) -> + if + Capacity>MaxAcc -> Capacity; + true -> MaxAcc + end + end, + ?line case lists:foldl(Fun2, 0, Data1) of + Max when Max<100 -> + Threshold3 = Max+1, + ?line ok = + disksup:set_almost_full_threshold(Threshold3/100), + ?line disksup ! timeout, % force a disk check + ?line Data3 = disksup:get_disk_data(), + ?line Over3 = over_threshold(Data3, Threshold3), + ?line Alarms3 = get_alarms(), + if + Over3==0, length(Alarms3)==0 -> + ?line ok; + true -> + dump_info(), + ?line ?t:fail({bad_alarms, Threshold3, Data3, Alarms3}) + end; + 100 -> + ?line ignore + end, + + %% Reset threshold + ?line ok = disksup:set_almost_full_threshold(Threshold1/100), + + ok. + +over_threshold(Data, Threshold) -> + Data2 = remove_duplicated_disks(lists:keysort(1, Data)), + lists:foldl(fun({_Id, _Kbyte, Cap}, N) when Cap>=Threshold -> + N+1; + (_DiskData, N) -> + N + end, + 0, + Data2). + +%% On some platforms (for example MontaVista) data for one disk can be +%% "duplicated": +%% Linux ppb 2.4.20_mvl31-pcore680 #1 Sun Feb 1 23:12:56 PST 2004 ppc unknown +%% +%% MontaVista(R) Linux(R) Professional Edition 3.1 +%% +%% [ppb:~]> /bin/df -lk +%% Filesystem 1k-blocks Used Available Use% Mounted on +%% rootfs 8066141 3023763 4961717 38% / +%% /dev/root 8066141 3023763 4961717 38% / +%% tmpfs 192892 0 192892 0% /dev/shm +%% +%% disksup: +%% [{"/",8066141,38}, {"/",8066141,38}, {"/dev/shm",192892,0}] +%% +%% disksup will only set ONE alarm for "/". +%% Therefore the list of disk data must be sorted and duplicated disk +%% tuples removed before calculating how many alarms should be set, or +%% the testcase will fail erroneously. +remove_duplicated_disks([{Id, _, _}, {Id, Kbyte, Cap}|T]) -> + remove_duplicated_disks([{Id, Kbyte, Cap}|T]); +remove_duplicated_disks([H|T]) -> + [H|remove_duplicated_disks(T)]; +remove_duplicated_disks([]) -> + []. + +get_alarms() -> + lists:filter(fun({{disk_almost_full, _Disk},_}) -> true; + (_) -> false + end, + alarm_handler:get_alarms()). + +until(Fun, [H|T]) -> + case Fun(H) of + true -> H; + false -> + until(Fun, T) + end; +until(_Fun, []) -> + false. + +port(suite) -> + []; +port(doc) -> + ["Test that disksup handles a terminating port program"]; +port(Config) when is_list(Config) -> + ?line Str = os:cmd("ps -ef | grep '[d]isksup'"), + case io_lib:fread("~s ~s", Str) of + {ok, [_Uid,Pid], _Rest} -> + + %% Monitor disksup + ?line MonRef = erlang:monitor(process, disksup), + ?line [{_Disk1,Kbyte1,_Cap1}|_] = disksup:get_disk_data(), + ?line true = Kbyte1>0, + + %% Kill the port program + case os:cmd("kill -9 " ++ Pid) of + [] -> + + %% disksup should now terminate + receive + {'DOWN', MonRef, _, _, {port_died, _Reason}} -> + ok; + {'DOWN', MonRef, _, _, Reason} -> + ?line ?t:fail({unexpected_exit_reason, Reason}) + after + 3000 -> + ?line ?t:fail({still_alive, Str}) + end, + + %% Give os_mon_sup time to restart disksup + ?t:sleep(?t:seconds(3)), + ?line [{_Disk2,Kbyte2,_Cap2}|_] = + disksup:get_disk_data(), + ?line true = Kbyte2>0, + + ok; + + Line -> + erlang:demonitor(MonRef), + {skip, {not_killed, Line}} + end; + _ -> + {skip, {os_pid_not_found, Str}} + end. + +terminate(suite) -> + []; +terminate(Config) when is_list(Config) -> + ?line ok = application:set_env(os_mon, start_disksup, false), + ?line ok = supervisor:terminate_child(os_mon_sup, disksup), + ok. + +unavailable(suite) -> + []; +unavailable(doc) -> + ["Test correct behaviour when service is unavailable"]; +unavailable(Config) when is_list(Config) -> + + %% Make sure all API functions return their dummy values + ?line [{"none",0,0}] = disksup:get_disk_data(), + ?line 1800000 = disksup:get_check_interval(), + ?line ok = disksup:set_check_interval(5), + ?line 80 = disksup:get_almost_full_threshold(), + ?line ok = disksup:set_almost_full_threshold(0.9), + + ok. + +restart(suite) -> + []; +restart(Config) when is_list(Config) -> + ?line ok = application:set_env(os_mon, start_disksup, true), + ?line {ok, _Pid} = supervisor:restart_child(os_mon_sup, disksup), + ok. + +otp_5910(suite) -> + []; +otp_5910(doc) -> + ["Test that alarms are cleared if disksup crashes or " + "if OS_Mon is stopped"]; +otp_5910(Config) when is_list(Config) -> + + %% Make sure disksup sets at least one alarm + ?line Data = disksup:get_disk_data(), + ?line Threshold0 = disksup:get_almost_full_threshold(), + ?line Threshold = case over_threshold(Data, Threshold0) of + 0 -> + [{_Id,_Kbyte,Cap}|_] = Data, + ?line ok = disksup:set_almost_full_threshold((Cap-1)/100), + Cap-1; + _N -> + Threshold0 + end, + ?line ok = application:set_env(os_mon, + disk_almost_full_threshold, + Threshold/100), + ?line disksup ! timeout, % force a disk check + ?line Data2 = disksup:get_disk_data(), + ?line Over = over_threshold(Data2, Threshold), + ?line Alarms = get_alarms(), + if + Over==0 -> + ?line ?t:fail({threshold_too_low, Data2, Threshold}); + Over==length(Alarms) -> + ok; + true -> + dump_info(), + ?line ?t:fail({bad_alarms, Threshold, Data2, Alarms}) + end, + + %% Kill disksup + exit(whereis(disksup), faked_disksup_crash), + + %% Wait a little to make sure disksup has been restarted, + %% then make sure the alarms are set once, but not twice + ?t:sleep(?t:seconds(1)), + ?line Data3 = disksup:get_disk_data(), + ?line Alarms2 = get_alarms(), + if + length(Alarms2)==length(Alarms) -> + ok; + true -> + dump_info(), + ?line ?t:fail({bad_alarms, Threshold, Data3, Alarms,Alarms2}) + end, + + %% Stop OS_Mon and make sure all disksup alarms are cleared + ?line ok = application:stop(os_mon), + ?t:sleep(?t:seconds(1)), + ?line Alarms3 = get_alarms(), + if + length(Alarms3)==0 -> + ok; + true -> + ?line ?t:fail({alarms_not_cleared, Alarms3}) + end, + + %% Reset threshold and restart OS_Mon + ?line ok = application:set_env(os_mon, + disksup_almost_full_threshold, 0.8), + ?line ok = disksup:set_almost_full_threshold(0.8), + ?line ok = application:start(os_mon), + + ok. + +dump_info() -> + io:format("Status: ~p~n", [sys:get_status(disksup)]). diff --git a/lib/os_mon/test/memsup_SUITE.erl b/lib/os_mon/test/memsup_SUITE.erl new file mode 100644 index 0000000000..01a7f6c7f2 --- /dev/null +++ b/lib/os_mon/test/memsup_SUITE.erl @@ -0,0 +1,782 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(memsup_SUITE). +-include("test_server.hrl"). + +%% Test server specific exports +-export([all/1]). +-export([init_per_suite/1, end_per_suite/1]). +-export([init_per_testcase/2, end_per_testcase/2]). + +%% Test cases +-export([api/1, alarm1/1, alarm2/1, process/1]). +-export([config/1, timeout/1, unavailable/1, port/1]). +-export([otp_5910/1]). + +%% Default timetrap timeout (set in init_per_testcase) +-define(default_timeout, ?t:minutes(1)). + +init_per_suite(Config) when is_list(Config) -> + ?line ok = application:start(os_mon), + Config. + +end_per_suite(Config) when is_list(Config) -> + ?line ok = application:stop(os_mon), + Config. + +init_per_testcase(_Case, Config) -> + Dog = ?t:timetrap(?default_timeout), + [{watchdog,Dog} | Config]. + +end_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + Config. + +all(suite) -> + All = case ?t:os_type() of + {unix, sunos} -> + [api, alarm1, alarm2, process, + config, timeout, unavailable, port]; + {unix, linux} -> + [api, alarm1, alarm2, process, timeout]; + _OS -> + [api, alarm1, alarm2, process] + end, + Bugs = [otp_5910], + All ++ Bugs. + +api(suite) -> + []; +api(doc) -> + ["Test of API functions"]; +api(Config) when is_list(Config) -> + + %% get_memory_data() + ?line RegMemData = memsup:get_memory_data(), + case RegMemData of + {TotMem, AllBytes, {Pid, PidBytes}} when is_integer(TotMem), + is_integer(AllBytes), + is_pid(Pid), + is_integer(PidBytes) -> + ok; + {0, 0, _WorstPid} -> + ?line ?t:fail(first_data_collection_failed); + _ -> + ?line ?t:fail({bad_return, RegMemData}) + end, + + %% get_system_memory_data() + ?line ExtMemData = memsup:get_system_memory_data(), + Tags = [ total_memory, + free_memory, + system_total_memory, + largest_free, + number_of_free, + free_swap, + total_swap, + cached_memory, + buffered_memory, + shared_memory], + + ?line true = lists:all(fun({Tag,Value}) when is_atom(Tag), + is_integer(Value) -> + lists:member(Tag, Tags); + (_) -> + false + end, + ExtMemData), + + %% get_os_wordsize() + ?line ok = case memsup:get_os_wordsize() of + 32 -> ok; + 64 -> ok; + unsupported_os -> ok; + _ -> error + end, + + %% get_check_interval() + ?line 60000 = memsup:get_check_interval(), + + %% set_check_interval(Minutes) + ?line ok = memsup:set_check_interval(2), + ?line 120000 = memsup:get_check_interval(), + ?line {'EXIT',{badarg,_}} = + (catch memsup:set_check_interval(0.2)), + ?line 120000 = memsup:get_check_interval(), + ?line ok = memsup:set_check_interval(1), + + %% get_procmem_high_watermark() + ?line 5 = memsup:get_procmem_high_watermark(), + + %% set_procmem_high_watermark() + ?line ok = memsup:set_procmem_high_watermark(0.1), + ?line 10 = memsup:get_procmem_high_watermark(), + ?line {'EXIT',{badarg,_}} = + (catch memsup:set_procmem_high_watermark(-0.1)), + ?line 10 = memsup:get_procmem_high_watermark(), + ?line ok = memsup:set_procmem_high_watermark(0.05), + + %% get_sysmem_high_watermark() + ?line 80 = memsup:get_sysmem_high_watermark(), + + %% set_sysmem_high_watermark() + ?line ok = memsup:set_sysmem_high_watermark(0.9), + ?line 90 = memsup:get_sysmem_high_watermark(), + ?line {'EXIT',{badarg,_}} = + (catch memsup:set_sysmem_high_watermark(-0.9)), + ?line 90 = memsup:get_sysmem_high_watermark(), + ?line ok = memsup:set_sysmem_high_watermark(0.8), + + %% get|set_helper_timeout + ?line 30 = memsup:get_helper_timeout(), + ?line ok = memsup:set_helper_timeout(29), + ?line 29 = memsup:get_helper_timeout(), + ?line {'EXIT',{badarg,_}} = (catch memsup:set_helper_timeout(31.0)), + ?line 29 = memsup:get_helper_timeout(), + ok. + +%%---------------------------------------------------------------------- +%% NOTE: The test case is a bit weak as it will fail if the memory +%% usage changes too much during its course. +%%---------------------------------------------------------------------- +alarm1(suite) -> + []; +alarm1(doc) -> + ["Test alarms when memsup_system_only==false"]; +alarm1(Config) when is_list(Config) -> + + %% If system memory usage is too high, the testcase cannot + %% be run correctly + ?line {Total, Alloc, {_Pid,_PidAlloc}} = memsup:get_memory_data(), + io:format("alarm1: Total: ~p, Alloc: ~p~n", [Total, Alloc]), + ?line SysUsage = Alloc/Total, + if + SysUsage>0.99 -> + {skip, sys_mem_too_high}; + true -> + alarm1(Config, SysUsage) + end. + +alarm1(_Config, SysUsage) -> + %% Set a long memory check interval, we will force memory checks + %% instead + ?line ok = memsup:set_check_interval(60), + + %% Check thresholds + ?line SysThreshold = (memsup:get_sysmem_high_watermark()/100), + ?line ProcThreshold = (memsup:get_procmem_high_watermark()/100), + + %% Check if a system alarm already should be set or not + SysP = if + SysUsage>SysThreshold -> true; + SysUsage=<SysThreshold -> false + end, + + %% If system memory is higher than threshold, make sure the system + %% alarm is set. Otherwise, make sure it is not set + case alarm_set(system_memory_high_watermark) of + {true, []} when SysP -> + ok; + false when not SysP -> + ok; + _ -> + ?line ?t:fail({sys_alarm, SysUsage, SysThreshold}) + end, + + %% Lower/raise the threshold to clear/set the alarm + NewSysThreshold = if + SysP -> + Value = 1.1*SysUsage, + if + Value > 0.99 -> 0.99; + true -> Value + end; + not SysP -> 0.9*SysUsage + end, + + ?line ok = memsup:set_sysmem_high_watermark(NewSysThreshold), + + %% Initiate and wait for a new data collection + ?line ok = force_collection(), + + %% Make sure the alarm is cleared/set + ?t:sleep(?t:seconds(5)), + case alarm_set(system_memory_high_watermark) of + {true, []} when not SysP -> + ok; + false when SysP -> + ok; + _ -> + ?line ?t:fail({sys_alarm, SysUsage, NewSysThreshold}) + end, + + %% Reset the threshold to set/clear the alarm again + ?line ok = memsup:set_sysmem_high_watermark(SysThreshold), + ?line ok = force_collection(), + ?t:sleep(?t:seconds(1)), + case alarm_set(system_memory_high_watermark) of + {true, []} when SysP -> + ok; + false when not SysP -> + ok; + _ -> + ?line ?t:fail({sys_alarm, SysUsage, SysThreshold}) + end, + + %% Check memory usage + ?line {Total2, _, {WorstPid, PidAlloc}} = memsup:get_memory_data(), + + %% Check if a process alarm already should be set or not + PidUsage = PidAlloc/Total2, + ProcP = if + PidUsage>ProcThreshold -> true; + PidUsage=<ProcThreshold -> false + end, + + %% Make sure the process alarm is set/not set accordingly + case alarm_set(process_memory_high_watermark) of + {true, WorstPid} when ProcP -> + ok; + false when not ProcP -> + ok; + {true, BadPid1} when ProcP -> + ?line ?t:fail({proc_alarm, WorstPid, BadPid1}); + _ -> + ?line ?t:fail({proc_alarm, PidUsage, ProcThreshold}) + end, + + %% Lower/raise the threshold to clear/set the alarm + NewProcThreshold = if + ProcP -> 1.1*PidUsage; + not ProcP -> 0.9*PidUsage + end, + ?line ok = memsup:set_procmem_high_watermark(NewProcThreshold), + ?line ok = force_collection(), + ?t:sleep(?t:seconds(1)), + case alarm_set(process_memory_high_watermark) of + {true, WorstPid} when not ProcP -> + ok; + false when ProcP -> + ok; + {true, BadPid2} when not ProcP -> + ?line test_server:fail({proc_alarm, WorstPid, BadPid2}); + _ -> + ?line ?t:fail({proc_alarm, PidUsage, ProcThreshold}) + end, + + %% Reset the threshold to clear/set the alarm + ?line ok = memsup:set_procmem_high_watermark(ProcThreshold), + ?line ok = force_collection(), + ?t:sleep(?t:seconds(1)), + case alarm_set(process_memory_high_watermark) of + {true, WorstPid} when ProcP -> + ok; + false when not ProcP -> + ok; + {true, BadPid3} when ProcP -> + ?line test_server:fail({proc_alarm, WorstPid, BadPid3}); + _ -> + ?line ?t:fail({proc_alarm, PidUsage, ProcThreshold}) + end, + + %% Reset memory check interval + ?line ok = memsup:set_check_interval(1), + ok. + +alarm2(suite) -> + []; +alarm2(doc) -> + ["Test alarms when memsup_system_only==true"]; +alarm2(Config) when is_list(Config) -> + + %% If system memory usage is too high, the testcase cannot + %% be run correctly + ?line {Total, Alloc, {_Pid,_PidAlloc}} = memsup:get_memory_data(), + ?line SysUsage = Alloc/Total, + if + SysUsage>0.99 -> + {skip, sys_mem_too_high}; + true -> + alarm2(Config, SysUsage) + end. + +alarm2(_Config, _SysUsage) -> + + %% Change memsup_system_only and restart memsup + ?line ok = application:set_env(os_mon, memsup_system_only, true), + ?line ok = supervisor:terminate_child(os_mon_sup, memsup), + ?line {ok, _Memsup1} = supervisor:restart_child(os_mon_sup, memsup), + + %% Set a long memory check interval, we will force memory checks + %% instead + ?line ok = memsup:set_check_interval(60), + + %% Check data and thresholds + ?line {Total, Alloc, undefined} = memsup:get_memory_data(), + ?line SysThreshold = (memsup:get_sysmem_high_watermark()/100), + ?line true = is_integer(memsup:get_procmem_high_watermark()), + + %% Check if a system alarm already should be set or not + ?line SysUsage = Alloc/Total, + SysP = if + SysUsage>SysThreshold -> true; + SysUsage=<SysThreshold -> false + end, + + %% If system memory is higher than threshold, make sure the system + %% alarm is set. Otherwise, make sure it is not set + case alarm_set(system_memory_high_watermark) of + {true, []} when SysP -> + ok; + false when not SysP -> + ok; + _ -> + ?line ?t:fail({sys_alarm, SysUsage, SysThreshold}) + end, + + %% Lower/raise the threshold to clear/set the alarm + NewSysThreshold = if + SysP -> + Value = 1.1*SysUsage, + if + Value > 0.99 -> 0.99; + true -> Value + end; + not SysP -> 0.9*SysUsage + end, + + ?line ok = memsup:set_sysmem_high_watermark(NewSysThreshold), + + %% Initiate and wait for a new data collection + ?line ok = force_collection(), + + %% Make sure the alarm is cleared/set + ?t:sleep(?t:seconds(1)), + case alarm_set(system_memory_high_watermark) of + {true, []} when not SysP -> + ok; + false when SysP -> + ok; + _ -> + ?line ?t:fail({sys_alarm, SysUsage, NewSysThreshold}) + end, + + %% Reset the threshold to set/clear the alarm again + ?line ok = memsup:set_sysmem_high_watermark(SysThreshold), + ?line ok = force_collection(), + ?t:sleep(?t:seconds(1)), + case alarm_set(system_memory_high_watermark) of + {true, []} when SysP -> + ok; + false when not SysP -> + ok; + _ -> + ?line ?t:fail({sys_alarm, SysUsage, SysThreshold}) + end, + + %% Reset memsup_system_only and restart memsup + %% (memory check interval is then automatically reset) + ?line ok = application:set_env(os_mon, memsup_system_only, false), + ?line ok = supervisor:terminate_child(os_mon_sup, memsup), + ?line {ok, _Memsup2} = supervisor:restart_child(os_mon_sup, memsup), + + ok. + +alarm_set(Alarm) -> + alarm_set(Alarm, alarm_handler:get_alarms()). +alarm_set(Alarm, [{Alarm,Data}|_]) -> + {true,Data}; +alarm_set(Alarm, [_|T]) -> + alarm_set(Alarm, T); +alarm_set(_Alarm, []) -> + false. + +process(suite) -> + []; +process(doc) -> + ["Make sure memsup discovers a process grown very large"]; +process(Config) when is_list(Config) -> + + %% Set a long memory check interval, we will force memory checks + %% instead + ?line ok = memsup:set_check_interval(60), + + %% Collect data + MemData = memsup:get_memory_data(), + io:format("process: memsup:get_memory_data() = ~p~n", [MemData]), + ?line {_Total,_Free,{_,Bytes}} = MemData, + + %% Start a new process larger than Worst + ?line WorsePid = spawn(fun() -> new_hog(Bytes) end), + ?t:sleep(?t:seconds(1)), + + %% Initiate and wait for a new data collection + ?line ok = force_collection(), + + %% Check that get_memory_data() returns updated result + ?line case memsup:get_memory_data() of + {_, _, {WorsePid, _MoreBytes}} -> + ok; + {_, _, BadWorst} -> + ?line ?t:fail({worst_pid, BadWorst}) + end, + + %% Reset memory check interval + ?line exit(WorsePid, done), + ?line ok = memsup:set_check_interval(1), + ok. + +new_hog(Bytes) -> + WordSize = erlang:system_info(wordsize), + N = (Bytes+200) div WordSize div 2, + List = lists:duplicate(N, a), + new_hog_1(List). + +new_hog_1(List) -> + receive + _Any -> exit(List) + end. + +config(suite) -> + []; +config(doc) -> + ["Test configuration"]; +config(Config) when is_list(Config) -> + + %% Change configuration parameters and make sure change is reflected + %% when memsup is restarted + ?line ok = application:set_env(os_mon, memory_check_interval, 2), + ?line ok = + application:set_env(os_mon, system_memory_high_watermark, 0.9), + ?line ok = + application:set_env(os_mon, process_memory_high_watermark, 0.1), + ?line ok = application:set_env(os_mon, memsup_helper_timeout, 35), + ?line ok = application:set_env(os_mon, memsup_system_only, true), + + ?line ok = supervisor:terminate_child(os_mon_sup, memsup), + ?line {ok, _Child1} = supervisor:restart_child(os_mon_sup, memsup), + + ?line 120000 = memsup:get_check_interval(), + ?line 90 = memsup:get_sysmem_high_watermark(), + ?line 10 = memsup:get_procmem_high_watermark(), + ?line 35 = memsup:get_helper_timeout(), + + %% Also try this with bad parameter values, should be ignored + ?line ok = application:set_env(os_mon, memory_check_interval, 0.2), + ?line ok = + application:set_env(os_mon, system_memory_high_watermark, -0.9), + ?line ok = + application:set_env(os_mon, process_memory_high_watermark,-0.1), + ?line ok = application:set_env(os_mon, memsup_helper_timeout, 0.35), + ?line ok = application:set_env(os_mon, memsup_system_only, arne), + + ?line ok = supervisor:terminate_child(os_mon_sup, memsup), + ?line {ok, _Child2} = supervisor:restart_child(os_mon_sup, memsup), + + ?line 60000 = memsup:get_check_interval(), + ?line 80 = memsup:get_sysmem_high_watermark(), + ?line 5 = memsup:get_procmem_high_watermark(), + ?line 30 = memsup:get_helper_timeout(), + + %% Reset configuration parameters + ?line ok = application:set_env(os_mon, memory_check_interval, 1), + ?line ok = + application:set_env(os_mon, system_memory_high_watermark, 0.8), + ?line ok = + application:set_env(os_mon, process_memory_high_watermark,0.05), + ?line ok = application:set_env(os_mon, memsup_helper_timeout, 30), + ?line ok = application:set_env(os_mon, memsup_system_only, false), + + ok. + +unavailable(suite) -> + []; +unavailable(doc) -> + ["Test correct behaviour when service is unavailable"]; +unavailable(Config) when is_list(Config) -> + + %% Close memsup + ?line ok = application:set_env(os_mon, start_memsup, false), + ?line ok = supervisor:terminate_child(os_mon_sup, memsup), + + %% Make sure all API functions return their dummy values + ?line {0,0,{_Pid,0}} = memsup:get_memory_data(), + ?line ok = application:set_env(os_mon, memsup_system_only, true), + ?line {0,0,undefined} = memsup:get_memory_data(), + ?line ok = application:set_env(os_mon, memsup_system_only, false), + ?line [] = memsup:get_system_memory_data(), + ?line 0 = memsup:get_os_wordsize(), + ?line 60000 = memsup:get_check_interval(), + ?line ok = memsup:set_check_interval(2), + ?line 5 = memsup:get_procmem_high_watermark(), + ?line ok = memsup:set_procmem_high_watermark(0.10), + ?line 80 = memsup:get_sysmem_high_watermark(), + ?line ok = memsup:set_sysmem_high_watermark(0.90), + ?line 30 = memsup:get_helper_timeout(), + ?line ok = memsup:set_helper_timeout(35), + + %% Start memsup again, + ?line ok = application:set_env(os_mon, start_memsup, true), + ?line {ok, _Child} = supervisor:restart_child(os_mon_sup, memsup), + + ok. + +timeout(suite) -> + []; +timeout(doc) -> + ["Test stability of memsup when data collection times out"]; +timeout(Config) when is_list(Config) -> + + %% Set a long memory check interval and memsup_helper timeout, + %% we will force memory checks instead and fake timeouts + ?line ok = memsup:set_check_interval(60), + ?line ok = memsup:set_helper_timeout(3600), + + %% Provoke a timeout during memory collection + ?line memsup ! time_to_collect, + ?line memsup ! reg_collection_timeout, + + %% Not much we can check though, except that memsup is still running + ?line {_,_,_} = memsup:get_memory_data(), + + %% Provoke a timeout during extensive memory collection + %% We fake a gen_server:call/2 to be able to send a timeout message + %% while the request is being handled + + %% Linux should be handled the same way as solaris. + +% TimeoutMsg = case ?t:os_type() of +% {unix, sunos} -> ext_collection_timeout; +% {unix, linux} -> reg_collection_timeout +% end, + + TimeoutMsg = ext_collection_timeout, + + ?line Pid = whereis(memsup), + ?line Mref = erlang:monitor(process, Pid), + ?line Pid ! {'$gen_call', {self(), Mref}, get_system_memory_data}, + ?line Pid ! TimeoutMsg, + receive + {Mref, []} -> + erlang:demonitor(Mref), + ?line ok; + {Mref, Res} -> + erlang:demonitor(Mref), + ?line ?t:fail({unexpected_result, Res}); + {'DOWN', Mref, _, _, _} -> + ?line ?t:fail(no_result) + end, + + %% Reset memory check interval and memsup_helper timeout + ?line ok = memsup:set_check_interval(1), + ?line ok = memsup:set_helper_timeout(30), + ?line memsup ! time_to_collect, + + ?line [_|_] = memsup:get_system_memory_data(), + + ok. + +port(suite) -> + []; +port(doc) -> + ["Test that memsup handles a terminating port program"]; +port(Config) when is_list(Config) -> + ?line Str = os:cmd("ps -e | grep '[m]emsup'"), + case io_lib:fread("~s", Str) of + {ok, [Pid], _Rest} -> + + %% Monitor memsup + ?line MonRef = erlang:monitor(process, memsup), + ?line {Total1,_Alloc1,_Worst1} = memsup:get_memory_data(), + ?line true = Total1>0, + + %% Kill the port program + case os:cmd("kill -9 " ++ Pid) of + [] -> + + %% memsup should now terminate + receive + {'DOWN', MonRef, _, _, {port_died, _Reason}} -> + ok; + {'DOWN', MonRef, _, _, Reason} -> + ?line ?t:fail({unexpected_exit_reason, Reason}) + after + 3000 -> + ?line ?t:fail(still_alive) + end, + + %% Give os_mon_sup time to restart memsup + ?t:sleep(?t:seconds(3)), + ?line {Total2,_Alloc2,_Worst2} = + memsup:get_memory_data(), + ?line true = Total2>0, + + ok; + + Line -> + erlang:demonitor(MonRef), + {skip, {not_killed, Line}} + end; + _ -> + {skip, {os_pid_not_found, Str}} + end. + +otp_5910(suite) -> + []; +otp_5910(doc) -> + ["Test that alarms are cleared and not set twice"]; +otp_5910(Config) when is_list(Config) -> + Alarms = + [system_memory_high_watermark, process_memory_high_watermark], + + %% Make sure memsup sets both alarms + ?line ok = application:set_env(os_mon, memory_check_interval, 60), + ?line ok = memsup:set_check_interval(60), + ?line SysThreshold = (memsup:get_sysmem_high_watermark()/100), + ?line ProcThreshold = (memsup:get_procmem_high_watermark()/100), + + MemData = memsup:get_memory_data(), + + io:format("otp_5910: memsup:get_memory_data() = ~p~n", [MemData]), + ?line {Total, Alloc, {_Pid, _Bytes}} = MemData, + ?line Pid = spawn_opt(fun() -> + receive + die -> ok + end + end, [{min_heap_size, 1000}]), + %% Create a process guaranteed to live, be constant and + %% break memsup process limit + ?line {memory, Bytes} = erlang:process_info(Pid,memory), + ?line SysUsage = Alloc/Total, + ?line ProcUsage = Bytes/Total, + + if + SysUsage>SysThreshold -> + ok; + SysUsage=<SysThreshold -> + ?line ok = application:set_env(os_mon, + sys_mem_high_watermark, + 0.5 * SysUsage), + ?line ok = memsup:set_sysmem_high_watermark(0.5 * SysUsage) + end, + if + ProcUsage>ProcThreshold -> + ok; + ProcUsage=<ProcThreshold -> + ?line ok = application:set_env(os_mon, + proc_mem_high_watermark, + 0.5 * ProcUsage), + ?line ok = memsup:set_procmem_high_watermark(0.5 *ProcUsage) + end, + ?line ok = force_collection(), + ?t:sleep(?t:seconds(1)), + lists:foreach(fun(AlarmId) -> + case alarm_set(AlarmId) of + {true, _} -> ok; + false -> + ?line ?t:fail({alarm_not_set, + AlarmId}) + end + end, + Alarms), + + %% Kill guaranteed process... + Pid ! die, + %% Kill memsup + exit(whereis(memsup), faked_memsup_crash), + %% Wait a little to make sure memsup has been restarted, + %% then make sure the alarms are set once, but not twice + ?t:sleep(?t:seconds(1)), + ?line MemUsage = memsup:get_memory_data(), + SetAlarms = alarm_handler:get_alarms(), + case lists:foldl(fun(system_memory_high_watermark, {S, P}) -> + {S+1, P}; + (process_memory_high_watermark, {S, P}) -> + {S, P+1}; + (_AlarmId, Acc0) -> + Acc0 + end, + {0, 0}, + SetAlarms) of + {0, 0} -> + ok; + _ -> + ?line ?t:fail({bad_number_of_alarms, SetAlarms, MemUsage}) + end, + + %% Stop OS_Mon and make sure all memsup alarms are cleared + ?line ok = application:stop(os_mon), + ?t:sleep(?t:seconds(1)), + lists:foreach(fun(AlarmId) -> + case alarm_set(AlarmId) of + false -> ok; + {true, _} -> + ?line ?t:fail({alarm_is_set, AlarmId}) + end + end, + Alarms), + + %% Reset configuration and restart OS_Mon + ?line ok = application:set_env(os_mon,memory_check_interval,1), + ?line ok = application:set_env(os_mon,sys_mem_high_watermark,0.8), + ?line ok = application:set_env(os_mon,proc_mem_high_watermark,0.05), + ?line ok = application:start(os_mon), + + ok. + +%%---------------------------------------------------------------------- +%% Auxiliary +%%---------------------------------------------------------------------- + +force_collection() -> + erlang:trace(whereis(memsup), true, ['receive']), + memsup ! time_to_collect, + TimerRef = erlang:send_after(5000, self(), timeout), + force_collection(TimerRef). + +force_collection(TimerRef) -> + receive + {trace, _Pid, 'receive', {collected_sys, _Sys}} -> + erlang:cancel_timer(TimerRef), + erlang:trace(whereis(memsup), false, ['receive']), + flush(), + ok; + {trace, _Pid, 'receive', reg_collection_timeout} -> + erlang:cancel_timer(TimerRef), + erlang:trace(whereis(memsup), false, ['receive']), + flush(), + collection_timeout; + timout -> + erlang:trace(whereis(memsup), false, ['receive']), + flush(), + timeout; + _Msg -> + force_collection(TimerRef) + end. + +flush() -> + receive + {trace, _, _, _} -> + flush(); + timeout -> + flush() + after 0 -> + ok + end. diff --git a/lib/os_mon/test/os_mon.spec b/lib/os_mon/test/os_mon.spec new file mode 100644 index 0000000000..bdae523795 --- /dev/null +++ b/lib/os_mon/test/os_mon.spec @@ -0,0 +1 @@ +{topcase, {dir, "../os_mon_test"}}. diff --git a/lib/os_mon/test/os_mon_SUITE.erl b/lib/os_mon/test/os_mon_SUITE.erl new file mode 100644 index 0000000000..ce52271ff8 --- /dev/null +++ b/lib/os_mon/test/os_mon_SUITE.erl @@ -0,0 +1,89 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(os_mon_SUITE). +-include("test_server.hrl"). + +%% Test server specific exports +-export([all/1]). +-export([init_per_testcase/2, fin_per_testcase/2]). + +%% Test cases +-export([app_file/1, config/1]). + +%% Default timetrap timeout (set in init_per_testcase) +-define(default_timeout, ?t:minutes(1)). + +init_per_testcase(_Case, Config) -> + Dog = test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +all(suite) -> + case ?t:os_type() of + {unix, sunos} -> [app_file, config]; + _OS -> [app_file] + end. + +app_file(suite) -> + []; +app_file(doc) -> + ["Testing .app file"]; +app_file(Config) when is_list(Config) -> + ?line ok = test_server:app_test(os_mon), + ok. + +config(suite) -> + []; +config(doc) -> + ["Test OS_Mon configuration"]; +config(Config) when is_list(Config) -> + + IsReg = fun(Name) -> is_pid(whereis(Name)) end, + IsNotReg = fun(Name) -> undefined == whereis(Name) end, + + ?line ok = application:start(os_mon), + ?line true = lists:all(IsReg, [cpu_sup, disksup, memsup]), + ?line ok = application:stop(os_mon), + + ?line ok = application:set_env(os_mon, start_cpu_sup, false), + ?line ok = application:start(os_mon), + ?line true = lists:all(IsReg, [disksup, memsup]), + ?line true = IsNotReg(cpu_sup), + ?line ok = application:stop(os_mon), + ?line ok = application:set_env(os_mon, start_cpu_sup, true), + + ?line ok = application:set_env(os_mon, start_disksup, false), + ?line ok = application:start(os_mon), + ?line true = lists:all(IsReg, [cpu_sup, memsup]), + ?line true = IsNotReg(disksup), + ?line ok = application:stop(os_mon), + ?line ok = application:set_env(os_mon, start_disksup, true), + + ?line ok = application:set_env(os_mon, start_memsup, false), + ?line ok = application:start(os_mon), + ?line true = lists:all(IsReg, [cpu_sup, disksup]), + ?line true = IsNotReg(memsup), + ?line ok = application:stop(os_mon), + ?line ok = application:set_env(os_mon, start_memsup, true), + + ok. diff --git a/lib/os_mon/test/os_mon_conf.erl b/lib/os_mon/test/os_mon_conf.erl new file mode 100644 index 0000000000..5c1fa43047 --- /dev/null +++ b/lib/os_mon/test/os_mon_conf.erl @@ -0,0 +1,28 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(os_mon_conf). +-export([init/1,fin/1]). + +init(Conf) -> + RetVal = application:start(os_mon,temporary), + [{os_mon,RetVal}|Conf]. + +fin(Conf) -> + application:stop(os_mon), + lists:keydelete(os_mon,1,Conf). diff --git a/lib/os_mon/test/os_mon_mib_SUITE.erl b/lib/os_mon/test/os_mon_mib_SUITE.erl new file mode 100644 index 0000000000..a1d463030a --- /dev/null +++ b/lib/os_mon/test/os_mon_mib_SUITE.erl @@ -0,0 +1,746 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(os_mon_mib_SUITE). + +%-define(STANDALONE,1). + +-ifdef(STANDALONE). +-define(line,erlang:display({line,?LINE}),). +-define(config(A,B), config(A,B)). +-else. +-include("test_server.hrl"). +-include_lib("os_mon/include/OTP-OS-MON-MIB.hrl"). +-include_lib("snmp/include/snmp_types.hrl"). +-endif. + +% Test server specific exports +-export([all/1, init_per_suite/1, end_per_suite/1, + init_per_testcase/2, end_per_testcase/2]). + + +% Test cases must be exported. +-export([update_load_table/1]). + +-export([get_mem_sys_mark/1, get_mem_proc_mark/1, get_disk_threshold/1, + get_load_table/1, get_next_load_table/1, get_disk_table/1, + get_next_disk_table/1, real_snmp_request/1, load_unload/1]). + +-export([sys_tot_mem/1, sys_used_mem/1, large_erl_process/1, + large_erl_process_mem/1, cpu_load/1, cpu_load5/1, cpu_load15/1, + os_wordsize/1, sys_tot_mem64/1, sys_used_mem64/1, + large_erl_process_mem64/1, disk_descr/1, disk_kbytes/1, + disk_capacity/1]). + +-export([tickets/1]). +-export([otp_6351/1, otp_7441/1]). + +-define(TRAP_UDP, 5000). +-define(AGENT_UDP, 4000). +-define(CONF_FILE_VER, [v2]). +-define(SYS_NAME, "Test os_mon_mibs"). +-define(MAX_MSG_SIZE, 484). +-define(ENGINE_ID, "mgrEngine"). +-define(MGR_PORT, 5001). + +%%--------------------------------------------------------------------- +-ifdef(STANDALONE). +-export([run/0]). +run() -> + catch init_per_suite([]), + Ret = (catch update_load_table([])), + catch end_per_suite([]), + Ret. +-else. + +init_per_testcase(_Case, Config) when is_list(Config) -> + Dog = test_server:timetrap(test_server:minutes(6)), + [{watchdog, Dog}|Config]. + +end_per_testcase(_Case, Config) when is_list(Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + Config. + +all(doc) -> + ["Test os_mon mibs and provided instrumentation functions."]; + +all(suite) -> + [load_unload, get_mem_sys_mark, get_mem_proc_mark, + get_disk_threshold, get_load_table, get_next_load_table, + get_disk_table, get_next_disk_table, real_snmp_request, + update_load_table, tickets]. + +tickets(suite) -> + [otp_6351, otp_7441]. + +-endif. +%%--------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config) -> Config +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Initiation before the whole suite +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + ?line application:start(sasl), + ?line application:start(mnesia), + ?line application:start(os_mon), + + %% Create initial configuration data for the snmp application + ?line PrivDir = ?config(priv_dir, Config), + ?line ConfDir = filename:join(PrivDir, "conf"), + ?line DbDir = filename:join(PrivDir,"db"), + ?line MgrDir = filename:join(PrivDir,"mgr"), + + ?line file:make_dir(ConfDir), + ?line file:make_dir(DbDir), + ?line file:make_dir(MgrDir), + + {ok, HostName} = inet:gethostname(), + {ok, Addr} = inet:getaddr(HostName, inet), + + ?line snmp_config:write_agent_snmp_files(ConfDir, ?CONF_FILE_VER, + tuple_to_list(Addr), ?TRAP_UDP, + tuple_to_list(Addr), + ?AGENT_UDP, ?SYS_NAME), + + ?line snmp_config:write_manager_snmp_files(MgrDir, tuple_to_list(Addr), + ?MGR_PORT, ?MAX_MSG_SIZE, + ?ENGINE_ID, [], [], []), + + %% To make sure application:set_env is not overwritten by any + %% app-file settings. + ?line ok = application:load(snmp), + + ?line application:set_env(snmp, agent, [{db_dir, DbDir}, + {config, [{dir, ConfDir}]}, + {agent_type, master}, + {agent_verbosity, trace}, + {net_if, [{verbosity, trace}]}]), + ?line application:set_env(snmp, manager, [{config, [{dir, MgrDir}, + {db_dir, MgrDir}, + {verbosity, trace}]}, + {server, [{verbosity, trace}]}, + {net_if, [{verbosity, trace}]}, + {versions, [v1, v2, v3]}]), + application:start(snmp), + + %% Load the mibs that should be tested + otp_mib:load(snmp_master_agent), + os_mon_mib:load(snmp_master_agent), + + [{agent_ip, Addr}| Config]. +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config) -> _ +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after the whole suite +%%-------------------------------------------------------------------- +end_per_suite(Config) -> + PrivDir = ?config(priv_dir, Config), + ConfDir = filename:join(PrivDir,"conf"), + DbDir = filename:join(PrivDir,"db"), + MgrDir = filename:join(PrivDir, "mgr"), + + %% Uload mibs + snmpa:unload_mibs(snmp_master_agent,["OTP-OS-MON-MIB"]), + otp_mib:unload(snmp_master_agent), + + %% Clean up + application:stop(snmp), + application:stop(mnesia), + application:stop(os_mon), + + del_dir(ConfDir), + del_dir(DbDir), + (catch del_dir(MgrDir)), + ok. + +%%--------------------------------------------------------------------- +%% Test cases +%%--------------------------------------------------------------------- +load_unload(doc) -> + ["Test to unload and the reload the OTP.mib "]; +load_unload(suite) -> []; +load_unload(Config) when list(Config) -> + ?line os_mon_mib:unload(snmp_master_agent), + ?line os_mon_mib:load(snmp_master_agent), + ok. +%%--------------------------------------------------------------------- + +update_load_table(doc) -> + ["check os_mon_mib:update_load_table error handling"]; +update_load_table(suite) -> + []; +update_load_table(Config) when is_list(Config) -> + ?line Node = start_node(), + ?line ok = rpc:call(Node,application,start,[sasl]), + ?line ok = rpc:call(Node,application,start,[os_mon]), + ?line ok = os_mon_mib:update_load_table(), + ?line rpc:call(Node,application,stop,[os_mon]), + ?line ok = os_mon_mib:update_load_table(), + ?line stop_node(Node), + ok. + +otp_6351(doc) -> + ["like update_load_table, when memsup_system_only==true"]; +otp_6351(suite) -> + []; +otp_6351(Config) when is_list(Config) -> + ?line Node = start_node(), + ?line ok = rpc:call(Node,application,start,[sasl]), + ?line ok = rpc:call(Node,application,load,[os_mon]), + ?line ok = rpc:call(Node,application,set_env, + [os_mon,memsup_system_only,true]), + ?line ok = rpc:call(Node,application,start,[os_mon]), + ?line Res = rpc:call(Node,os_mon_mib,get_load,[Node]), + if + is_tuple(Res), element(1, Res)==loadTable -> + ?line ok; + true -> + ?line ?t:fail(Res) + end, + ?line rpc:call(Node,application,stop,[os_mon]), + ?line stop_node(Node), + ok. + + + + +%%--------------------------------------------------------------------- +get_mem_sys_mark(doc) -> + ["Simulates a get call to test the instrumentation function " + "for the loadMemorySystemWatermark variable."]; +get_mem_sys_mark(suite) -> + []; +get_mem_sys_mark(Config) when is_list(Config) -> + case os_mon_mib:mem_sys_mark(get) of + {value, SysMark} when is_integer(SysMark) -> + ok; + _ -> + ?line test_server:fail(sys_mark_value_not_integer) + end. +%%--------------------------------------------------------------------- +get_mem_proc_mark(doc) -> + ["Simulates a get call to test the instrumentation function " + "for the loadMemoryErlProcWatermark variable."]; +get_mem_proc_mark(suite) -> + []; +get_mem_proc_mark(Config) when is_list(Config) -> + case os_mon_mib:mem_proc_mark(get) of + {value, ProcMark} when is_integer(ProcMark) -> + ok; + _ -> + ?line test_server:fail(proc_mark_value_not_integer) + end. +%%--------------------------------------------------------------------- +get_disk_threshold(doc) -> + ["Simulates a get call to test the instrumentation function " + "for the diskAlmostFullThreshold variable."]; +get_disk_threshold(suite) -> + []; +get_disk_threshold(Config) when is_list(Config) -> + case os_mon_mib:disk_threshold(get) of + {value, ProcMark} when is_integer(ProcMark) -> + ok; + _ -> + ?line test_server:fail(disk_threshold_value_not_integer) + end. +%%--------------------------------------------------------------------- + +%%% Note that when we have a string key, as in loadTable, the +%%% instrumentation will deal with the [length(String), String]. We +%%% have to know about this, when short cutting SNMP and calling +%%% instrumentation functions directly as done in most test cases in +%%% this test suite + +get_load_table(doc) -> + ["Simulates get calls to test the instrumentation function " + "for the loadTable"]; +get_load_table(suite) -> + []; +get_load_table(Config) when is_list(Config) -> + + NodeStr = atom_to_list(node()), + NodeLen = length(NodeStr), + + {_, _, {Pid, _}} = memsup:get_memory_data(), + PidStr = lists:flatten(io_lib:format("~w", [Pid])), + ?line [{value, NodeStr},{value, PidStr}] = + os_mon_mib:load_table(get, [NodeLen | NodeStr], + [?loadErlNodeName, ?loadLargestErlProcess]), + + ?line Values = os_mon_mib:load_table(get, [NodeLen | NodeStr] , + [?loadSystemTotalMemory, + ?loadSystemUsedMemory, + ?loadLargestErlProcessUsedMemory, + ?loadCpuLoad, + ?loadCpuLoad5, + ?loadCpuLoad15, + ?loadOsWordsize, + ?loadSystemTotalMemory64, + ?loadSystemUsedMemory64, + ?loadLargestErlProcessUsedMemory64]), + + IsInt = fun({value, Val}) when is_integer(Val) -> + true; + (_) -> + false + end, + + NewValues = lists:filter(IsInt, Values), + + case length(NewValues) of + 10 -> + ok; + _ -> + ?line test_server:fail(value_not_integer) + end, + + ?line [{noValue,noSuchInstance}, {noValue,noSuchInstance}, + {noValue,noSuchInstance}, {noValue,noSuchInstance}, + {noValue,noSuchInstance}, {noValue,noSuchInstance}, + {noValue,noSuchInstance}, {noValue,noSuchInstance}, + {noValue,noSuchInstance}, {noValue,noSuchInstance}, + {noValue,noSuchInstance}, {noValue,noSuchInstance}] = + os_mon_mib:load_table(get, [3, 102, 111, 111], + [?loadErlNodeName, + ?loadSystemTotalMemory, + ?loadSystemUsedMemory, + ?loadLargestErlProcess, + ?loadLargestErlProcessUsedMemory, + ?loadCpuLoad, + ?loadCpuLoad5, + ?loadCpuLoad15, + ?loadOsWordsize, + ?loadSystemTotalMemory64, + ?loadSystemUsedMemory64, + ?loadLargestErlProcessUsedMemory64]), + + ok. +%%--------------------------------------------------------------------- +get_next_load_table(doc) -> + ["Simulates get_next calls to test the instrumentation function " + "for the loadTable"]; +get_next_load_table(suite) -> + [ sys_tot_mem, + sys_used_mem, + large_erl_process, + large_erl_process_mem, + cpu_load, + cpu_load5, + cpu_load15, + os_wordsize, + sys_tot_mem64, + sys_used_mem64, + large_erl_process_mem64]. + +sys_tot_mem(doc) -> + []; +sys_tot_mem(suite) -> + []; +sys_tot_mem(Config) when is_list(Config) -> + ?line [{[?loadSystemTotalMemory, Len | NodeStr], Mem}] = + os_mon_mib:load_table(get_next, [], [?loadSystemTotalMemory]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + + case Mem of + Mem when is_integer(Mem) -> + ok; + _ -> + ?line test_server:fail(sys_tot_mem_value_not_integer) + end. + +sys_used_mem(doc) -> + []; +sys_used_mem(suite) -> []; +sys_used_mem(Config) when is_list(Config) -> + ?line [{[?loadSystemUsedMemory, Len | NodeStr], Mem}] = + os_mon_mib:load_table(get_next,[], [?loadSystemUsedMemory]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + + case Mem of + Mem when is_integer(Mem) -> + ok; + _ -> + ?line test_server:fail(sys_used_mem_value_not_integer) + end. + +large_erl_process(doc) -> + []; +large_erl_process(suite) -> + []; +large_erl_process(Config) when is_list(Config) -> + {_, _, {Pid, _}} = memsup:get_memory_data(), + PidStr = lists:flatten(io_lib:format("~w", [Pid])), + ?line [{[?loadLargestErlProcess, Len | NodeStr], PidStr}] = + os_mon_mib:load_table(get_next,[], [?loadLargestErlProcess]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + ok. + +large_erl_process_mem(doc) -> + []; +large_erl_process_mem(suite) -> + []; +large_erl_process_mem(Config) when is_list(Config) -> + + ?line [{[?loadLargestErlProcessUsedMemory, Len | NodeStr], Mem}] = + os_mon_mib:load_table(get_next,[], + [?loadLargestErlProcessUsedMemory]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + + case Mem of + Mem when is_integer(Mem) -> + ok; + _ -> + ?line test_server:fail(erl_pid_mem_value_not_integer) + end. + +cpu_load(doc) -> + []; +cpu_load(suite) -> + []; +cpu_load(Config) when list(Config) -> + ?line [{[?loadCpuLoad, Len | NodeStr], Load}] = + os_mon_mib:load_table(get_next,[], [?loadCpuLoad]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + + case Load of + Load when is_integer(Load) -> + ok; + _ -> + ?line test_server:fail(cpu_load_value_not_integer) + end. + +cpu_load5(doc) -> + []; +cpu_load5(suite) -> + []; +cpu_load5(Config) when is_list(Config) -> + ?line [{[?loadCpuLoad5, Len | NodeStr], Load}] = + os_mon_mib:load_table(get_next,[], [?loadCpuLoad5]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + + case Load of + Load when is_integer(Load) -> + ok; + _ -> + ?line test_server:fail(cpu_load5_value_not_integer) + end. + +cpu_load15(doc) -> + []; +cpu_load15(suite) -> + []; +cpu_load15(Config) when is_list(Config) -> + ?line [{[?loadCpuLoad15, Len | NodeStr], Load}] = + os_mon_mib:load_table(get_next,[], [?loadCpuLoad15]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + + case Load of + Load when is_integer(Load) -> + ok; + _ -> + ?line test_server:fail(cpu_load15_value_not_integer) + end. + +os_wordsize(doc) -> + []; +os_wordsize(suite) -> + []; +os_wordsize(Config) when is_list(Config) -> + ?line [{[?loadOsWordsize, Len | NodeStr], Wordsize}] = + os_mon_mib:load_table(get_next,[], [?loadOsWordsize]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + + case Wordsize of + Wordsize when is_integer(Wordsize) -> + ok; + _ -> + ?line test_server:fail(os_wordsize_value_not_integer) + end. + +sys_tot_mem64(doc) -> + []; +sys_tot_mem64(suite) -> + []; +sys_tot_mem64(Config) when is_list(Config) -> + ?line [{[?loadSystemTotalMemory64, Len | NodeStr], Mem}] = + os_mon_mib:load_table(get_next, [], [?loadSystemTotalMemory64]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + + case Mem of + Mem when is_integer(Mem) -> + ok; + _ -> + ?line test_server:fail(sys_tot_mem_value_not_integer) + end. + +sys_used_mem64(doc) -> + []; +sys_used_mem64(suite) -> []; +sys_used_mem64(Config) when is_list(Config) -> + ?line [{[?loadSystemUsedMemory64, Len | NodeStr], Mem}] = + os_mon_mib:load_table(get_next,[], [?loadSystemUsedMemory64]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + + case Mem of + Mem when is_integer(Mem) -> + ok; + _ -> + ?line test_server:fail(sys_used_mem_value_not_integer) + end. + +large_erl_process_mem64(doc) -> + []; +large_erl_process_mem64(suite) -> + []; +large_erl_process_mem64(Config) when is_list(Config) -> + + ?line [{[?loadLargestErlProcessUsedMemory64, Len | NodeStr], Mem}] = + os_mon_mib:load_table(get_next,[], + [?loadLargestErlProcessUsedMemory64]), + ?line Len = length(NodeStr), + ?line true = lists:member(list_to_atom(NodeStr), [node() | nodes()]), + + case Mem of + Mem when is_integer(Mem) -> + ok; + _ -> + ?line test_server:fail(erl_pid_mem_value_not_integer) + end. +%%--------------------------------------------------------------------- +get_disk_table(doc) -> + ["Simulates get calls to test the instrumentation function " + "for the diskTable."]; +get_disk_table(suite) -> + []; +get_disk_table(Config) when is_list(Config) -> + + DiskData = disksup:get_disk_data(), + DiskDataLen = length(DiskData), + + if + DiskDataLen > 0 -> + ?line [{value, Value}] = + os_mon_mib:disk_table(get, [1,1], [?diskDescr]), + + case is_list(Value) of + true -> + ok; + false -> + ?line test_server:fail(value_not_a_string) + end, + + ?line Values = os_mon_mib:disk_table(get, [1,1], + [?diskId, + ?diskKBytes, + ?diskCapacity]), + + IsInt = fun({value, Val}) when is_integer(Val) -> + true; + (_) -> + false + end, + + NewValues = lists:filter(IsInt, Values), + + case length(NewValues) of + 3 -> + ok; + _ -> + ?line test_server:fail(value_not_integer) + end + end, + + ?line [{noValue,noSuchInstance}, {noValue,noSuchInstance}, + {noValue,noSuchInstance}, {noValue,noSuchInstance}] = + os_mon_mib:disk_table(get, [1, DiskDataLen + 1], [?diskId, + ?diskDescr, + ?diskKBytes, + ?diskCapacity]), + + ok. + +%%--------------------------------------------------------------------- +get_next_disk_table(doc) -> + ["Simulates get_next calls to test the instrumentation function " + "for the diskTable."]; +get_next_disk_table(suite) -> + [disk_descr, disk_kbytes, disk_capacity]. + +disk_descr(doc) -> + []; +disk_descr(suite) -> + []; +disk_descr(Config) when is_list(Config) -> + ?line [{[?diskDescr, 1,1], Descr}] = + os_mon_mib:disk_table(get_next, [], [?diskDescr]), + + case Descr of + Descr when is_list(Descr) -> + ok; + _ -> + ?line test_server:fail(disk_descr_value_not_a_string) + end. + +disk_kbytes(doc) -> + []; +disk_kbytes(suite) -> []; +disk_kbytes(Config) when is_list(Config) -> + ?line [{[?diskKBytes, 1,1], Kbytes}] = + os_mon_mib:disk_table(get_next,[], [?diskKBytes]), + + case Kbytes of + Kbytes when is_integer(Kbytes) -> + ok; + _ -> + ?line test_server:fail(disk_kbytes_value_not_integer) + end. + + +disk_capacity(doc) -> + []; +disk_capacity(suite) -> []; +disk_capacity(Config) when is_list(Config) -> + ?line [{[?diskCapacity, 1,1], Capacity}] = + os_mon_mib:disk_table(get_next,[], [?diskCapacity]), + + case Capacity of + Capacity when is_integer(Capacity) -> + ok; + _ -> + ?line test_server:fail(disk_capacity_value_not_integer) + end. + +%%--------------------------------------------------------------------- +real_snmp_request(doc) -> + ["Starts an snmp manager and sends a real snmp-reques. i.e. " + "sends a udp message on the correct format."]; +real_snmp_request(suite) -> []; +real_snmp_request(Config) when list(Config) -> + Agent_ip = ?config(agent_ip, Config), + + ?line ok = snmpm:register_user(os_mon_mib_test, snmpm_user_default, []), + ?line ok = snmpm:register_agent(os_mon_mib_test, Agent_ip, ?AGENT_UDP), + + NodStr = atom_to_list(node()), + Len = length(NodStr), + {_, _, {Pid, _}} = memsup:get_memory_data(), + PidStr = lists:flatten(io_lib:format("~w", [Pid])), + io:format("FOO: ~p~n", [PidStr]), + ?line ok = snmp_get(Agent_ip, + [?loadEntry ++ + [?loadLargestErlProcess, Len | NodStr]], + PidStr), + ?line ok = snmp_get_next(Agent_ip, + [?loadEntry ++ + [?loadSystemUsedMemory, Len | NodStr]], + ?loadEntry ++ [?loadSystemUsedMemory + 1, Len + | NodStr], PidStr), + ?line ok = snmp_set(Agent_ip, [?loadEntry ++ + [?loadLargestErlProcess, Len | NodStr]], + s, "<0.101.0>"), + ok. + +otp_7441(doc) -> + ["Starts an snmp manager and requests total memory. Was previously + integer32 which was errornous on 64 bit machines."]; +otp_7441(suite) -> + []; +otp_7441(Config) when is_list(Config) -> + Agent_ip = ?config(agent_ip, Config), + + + NodStr = atom_to_list(node()), + Len = length(NodStr), + Oids = [Oid|_] = [?loadEntry ++ [?loadSystemTotalMemory, Len | NodStr]], + ?line { ok, {noError,0,[#varbind{oid = Oid, variabletype = 'Unsigned32'}]}, _} = + snmpm:g(os_mon_mib_test, Agent_ip, ?AGENT_UDP, Oids), + + ok. + +%%--------------------------------------------------------------------- +%% Internal functions +%%--------------------------------------------------------------------- +-ifdef(STANDALONE). +config(priv_dir,_) -> + "/tmp". + +start_node() -> + Host = hd(tl(string:tokens(atom_to_list(node()),"@"))), + {ok,Node} = slave:start(Host,testnisse), + net_adm:ping(testnisse), + Node. + + +stop_node(Node) -> + rpc:call(Node,erlang,halt,[]). +-else. +start_node() -> + ?line Pa = filename:dirname(code:which(?MODULE)), + ?line {ok,Node} = test_server:start_node(testnisse, slave, + [{args, " -pa " ++ Pa}]), + Node. + +stop_node(Node) -> + test_server:stop_node(Node). + +-endif. + +del_dir(Dir) -> + io:format("Deleting: ~s~n",[Dir]), + {ok, Files} = file:list_dir(Dir), + FullPathFiles = lists:map(fun(File) -> filename:join(Dir, File) end, + Files), + lists:foreach({file, delete}, FullPathFiles), + file:del_dir(Dir). + +%%--------------------------------------------------------------------- +snmp_get(Agent_ip, Oids = [Oid |_], Result) -> + ?line {ok,{noError,0,[#varbind{oid = Oid, + variabletype = 'OCTET STRING', + value = Result}]}, _} = + snmpm:g(os_mon_mib_test, Agent_ip, ?AGENT_UDP, Oids), + ok. + +snmp_get_next(Agent_ip, Oids, NextOid, Result) -> + ?line {ok,{noError,0,[#varbind{oid = NextOid, + variabletype = 'OCTET STRING', + value = Result}]},_} = + snmpm:gn(os_mon_mib_test, Agent_ip, ?AGENT_UDP, Oids), + ok. + +snmp_set(Agent_ip, Oid, ValuType, Value) -> + ?line {ok, {notWritable, _, _}, _} = + snmpm:s(os_mon_mib_test,Agent_ip,?AGENT_UDP,[{Oid, ValuType, Value}]), + ok. diff --git a/lib/os_mon/test/os_sup_SUITE.erl b/lib/os_mon/test/os_sup_SUITE.erl new file mode 100644 index 0000000000..25041f968d --- /dev/null +++ b/lib/os_mon/test/os_sup_SUITE.erl @@ -0,0 +1,189 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2006-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(os_sup_SUITE). +-include("test_server.hrl"). + +%% Test server specific exports +-export([all/1]). +-export([init_per_suite/1, end_per_suite/1]). +-export([init_per_testcase/2, end_per_testcase/2]). + +%% Test cases +-export([message/1]). +-export([config/1, port/1]). + +%% Default timetrap timeout (set in init_per_testcase) +-define(default_timeout, ?t:minutes(1)). + +-define(TAG, test_tag). +-define(MFA, {?MODULE, test_mfa, [?TAG]}). + +-export([test_mfa/2]). + +init_per_suite(Config) when is_list(Config) -> + spawn(fun() -> message_receptor() end), + ?line application:load(os_mon), + ?line ok = application:set_env(os_mon, start_os_sup, true), + ?line ok = application:set_env(os_mon, os_sup_mfa, ?MFA), + ?line ok = application:set_env(os_mon, os_sup_enable, false), + ?line ok = application:start(os_mon), + Config. + +end_per_suite(Config) when is_list(Config) -> + ?line application:stop(os_mon), + ?line ok = application:set_env(os_mon, start_os_sup, false), + MFA = {os_sup, error_report, [std_error]}, + ?line ok = application:set_env(os_mon, os_sup_mfa, MFA), + ?line ok = application:set_env(os_mon, os_sup_enable, true), + ?line exit(whereis(message_receptor), done), + Config. + +init_per_testcase(_Case, Config) -> + Dog = ?t:timetrap(?default_timeout), + [{watchdog,Dog} | Config]. + +end_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +all(suite) -> + case ?t:os_type() of + {unix, sunos} -> + [message, config, port]; + {win32, _OSname} -> + [message]; + OS -> + Str = io_lib:format("os_sup not available for ~p", [OS]), + {skip, lists:flatten(Str)} + end. + +message(suite) -> + []; +message(doc) -> + ["Test OS message handling"]; +message(Config) when is_list(Config) -> + + %% Fake an OS message + Data = "10H11386278426HSystem4HTest5HError5HTesto", + ?line os_sup_server ! {faked_port, {data, Data}}, + + %% Check with message_receptor that it has been received + ?t:sleep(?t:seconds(1)), + Msg = + case ?t:os_type() of + {unix, sunos} -> + {?TAG, Data}; + {win32, _} -> + {?TAG,{{1138,627842,0},"System","Test","Error","Testo"}} + end, + ?line message_receptor ! {check, self(), Msg}, + receive + {result, true} -> + ok; + {result, Rec} -> + ?t:fail({no_message, Rec}) + end, + + ok. + +config(suite) -> + []; +config(doc) -> + ["Test configuration"]; +config(Config) when is_list(Config) -> + + %% os_sup_enable==true and os_sup_own/os_sup_syslogconf cannot + %% be tested as test_server is not running is root + + %% os_sup_mfa is already tested, sort of (in init_per_suite) + + %% os_sup_errortag should be tested, however + + ok. + +port(suite) -> + []; +port(doc) -> + ["Test that os_sup handles a terminating port program"]; +port(Config) when is_list(Config) -> + ?line Str = os:cmd("ps -e | grep '[f]errule'"), + case io_lib:fread("~s", Str) of + {ok, [Pid], _Rest} -> + + %% Monitor os_sup_server + ?line MonRef = erlang:monitor(process, os_sup_server), + + %% Kill the port program + case os:cmd("kill -9 " ++ Pid) of + [] -> + + %% os_sup_server should now terminate + receive + {'DOWN', MonRef, _, _, {port_died, _Reason}} -> + ok; + {'DOWN', MonRef, _, _, Reason} -> + ?line ?t:fail({unexpected_exit_reason, Reason}) + after + 3000 -> + ?line ?t:fail(still_alive) + end, + + %% Give os_mon_sup time to restart os_sup + ?t:sleep(?t:seconds(3)), + ?line true = is_pid(whereis(os_sup_server)), + + ok; + + Line -> + erlang:demonitor(MonRef), + {skip, {not_killed, Line}} + end; + _ -> + {skip, {os_pid_not_found}} + end. + +%%---------------------------------------------------------------------- +%% Auxiliary +%%---------------------------------------------------------------------- + +test_mfa(Message, Tag) -> + message_receptor ! {Tag, Message}. + +message_receptor() -> + register(message_receptor, self()), + message_receptor([]). + +message_receptor(Received) -> + receive + %% Check if a certain message has been received + {check, From, Msg} -> + case lists:member(Msg, Received) of + true -> + From ! {result, true}, + message_receptor(lists:delete(Msg, Received)); + false -> + From ! {result, Received}, + message_receptor(Received) + end; + + %% Save all other messages + Msg -> + message_receptor([Msg|Received]) + end. diff --git a/lib/runtime_tools/test/Makefile b/lib/runtime_tools/test/Makefile new file mode 100644 index 0000000000..873d395277 --- /dev/null +++ b/lib/runtime_tools/test/Makefile @@ -0,0 +1,65 @@ +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +MODULES = \ + runtime_tools_SUITE \ + inviso_testmodule1_foo \ + inviso_SUITE \ + dbg_SUITE \ + erts_alloc_config_SUITE + +ERL_FILES= $(MODULES:%=%.erl) + +TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) +INSTALL_PROGS= $(TARGET_FILES) + +EMAKEFILE=Emakefile + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/runtime_tools_test + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- + +ERL_MAKE_FLAGS += +ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include + +EBIN = . + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +make_emakefile: + $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\ + > $(EMAKEFILE) + +tests debug opt: make_emakefile + erl $(ERL_MAKE_FLAGS) -make + +clean: + rm -f $(EMAKEFILE) + rm -f $(TARGET_FILES) + rm -f core + +docs: + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + +release_tests_spec: make_emakefile + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) runtime_tools.spec $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(EMAKEFILE) runtime_tools.cover $(RELSYSDIR) + chmod -f -R u+w $(RELSYSDIR) + @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + +release_docs_spec: diff --git a/lib/runtime_tools/test/dbg_SUITE.erl b/lib/runtime_tools/test/dbg_SUITE.erl new file mode 100644 index 0000000000..ff96af5e86 --- /dev/null +++ b/lib/runtime_tools/test/dbg_SUITE.erl @@ -0,0 +1,901 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(dbg_SUITE). + +%% Test functions +-export([all/1, big/1, tiny/1, simple/1, message/1, distributed/1, + ip_port/1, file_port/1, file_port2/1, file_port_schedfix/1, + ip_port_busy/1, wrap_port/1, wrap_port_time/1, + with_seq_trace/1, dead_suspend/1, local_trace/1, + saved_patterns/1]). +-export([init_per_testcase/2, fin_per_testcase/2]). +-export([tracee1/1, tracee2/1]). +-export([dummy/0, exported/1]). + +-include("test_server.hrl"). +-define(default_timeout, ?t:minutes(1)). + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. +fin_per_testcase(_Case, Config) -> + Dog=?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +all(suite) -> [big, tiny, simple, message, distributed, + ip_port, file_port, file_port2, file_port_schedfix, + ip_port_busy, wrap_port, wrap_port_time, + with_seq_trace, dead_suspend, local_trace, saved_patterns]. + +big(suite) -> []; +big(doc) -> ["Rudimentary interface test"]; +big(Config) when is_list(Config) -> + ?line {ok,OldCurDir} = file:get_cwd(), + Datadir=?config(data_dir, Config), + Privdir=?config(priv_dir, Config), + ?line ok=file:set_cwd(Privdir), + try + %% make sure dbg is stopped (and returns correctly) + ?line ok = dbg:stop(), + + %% compile test module and make sure it is loaded. + ?line {ok,Mod} = compile:file(Datadir++"/dbg_test",[trace]), + ?line code:purge(dbg_test), + ?line {module, Mod}=code:load_file(dbg_test), + + %% run/debug a named test function. + ?line Pid = spawn_link(dbg_test, loop, [Config]), + ?line true = register(dbg_test_loop, Pid), + ?line {ok,_} = dbg:tracer(), + ?line {ok,[{matched, _node, 1}]} = dbg:p(dbg_test_loop, [m,p,c]), + ?line ok = dbg:c(dbg_test, test, [Config]), + ?line ok = dbg:i(), + ?line dbg_test_loop ! {dbg_test, stop}, + unregister(dbg_test_loop), + ?line ok = dbg:stop(), + + %% run/debug a Pid. + ?line Pid2=spawn_link(dbg_test,loop,[Config]), + ?line {ok,_} = dbg:tracer(), + ?line {ok,[{matched, _node, 1}]} = dbg:p(Pid2,[s,r,p]), + ?line ok = dbg:c(dbg_test, test, [Config]), + ?line ok = dbg:i(), + ?line Pid2 ! {dbg_test, stop}, + + ?line ok=file:set_cwd(OldCurDir) + after + ?line dbg:stop() + end, + ok. + + +tiny(suite) -> []; +tiny(doc) -> ["Rudimentary interface test"]; +tiny(Config) when is_list(Config) -> + ?line {ok,OldCurDir} = file:get_cwd(), + Datadir=?config(data_dir, Config), + Privdir=?config(priv_dir, Config), + ?line ok=file:set_cwd(Privdir), + try + %% compile test module and make sure it is loaded. + ?line {ok, Mod} = compile:file(Datadir++"/dbg_test",[trace]), + ?line code:purge(dbg_test), + ?line {module, Mod}=code:load_file(dbg_test), + + ?line Pid=spawn_link(dbg_test,loop,[Config]), + if + is_pid(Pid) -> + ?line dbg:tracer(), + ?line {ok,[{matched, _node, 1}]} = dbg:p(Pid,[s,r,m,p,c]), + ?line ok = dbg:c(dbg_test,test,[Config]), + ?line ok = dbg:i(), + ?line Pid ! {dbg_test, stop}; + true -> + ?line ok=file:set_cwd(OldCurDir), + ?t:fail("Could not spawn external test process.~n"), + failure + end + after + ?line ok = dbg:stop(), + ?line ok = file:set_cwd(OldCurDir) + end, + ok. + +simple(suite) -> + []; +simple(doc) -> + ["Simple interface test with own handler"]; +simple(Config) when is_list(Config) -> + try + ?line start(), + ?line dbg:p(self(),call), + ?line dbg:tp(dbg,ltp,[]), + ?line dbg:ltp(), + ?line stop(), + ?line S = self(), + ?line [{trace,S,call,{dbg,ltp,[]}}] = flush() + after + ?line dbg:stop() + end, + ok. + +message(suite) -> + []; +message(doc) -> + ["Simple interface test with pam code that appends a message"]; +message(Config) when is_list(Config) -> + ?line {ok, _} = start(), + try + ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call), + ?line {ok, X} = dbg:tp(dbg,ltp,[{'_',[],[{message, {self}}]}]), + ?line {value, {saved, Saved}} = lists:keysearch(saved, 1, X), + ?line {ok, Y} = dbg:tp(dbg,ln,Saved), + ?line {value, {saved, Saved}} = lists:keysearch(saved, 1, Y), + ?line ok = dbg:ltp(), + ?line ok = dbg:ln() + after + ?line stop() + end, + ?line S = self(), + ?line [{trace,S,call,{dbg,ltp,[]},S}, + {trace,S,call,{dbg,ln,[]},S}] = flush(), + ok. + +distributed(suite) -> + []; +distributed(doc) -> + ["Simple test of distributed tracing"]; +distributed(Config) when is_list(Config) -> + ?line {ok, _} = start(), + ?line Node = start_slave(), + try + ?line RexPid = rpc:call(Node, erlang, whereis, [rex]), + ?line RexPidList = pid_to_list(RexPid), + ?line {ok, Node} = dbg:n(Node), + ?line {ok, X} = dbg:p(all,call), + ?line {value, {matched, Node, _}} = lists:keysearch(Node, 2, X), + ?line {ok, Y} = dbg:p(RexPidList, s), + ?line {value, {matched, Node, 1}} = lists:keysearch(Node, 2, Y), + ?line {ok, Z} = dbg:tp(dbg,ltp,[]), + ?line {value, {matched, Node, 1}} = lists:keysearch(Node, 2, Z), + ?line dbg:cn(Node), + ?line dbg:tp(dbg,ln,[]), + ?line ok = rpc:call(Node, dbg, ltp, []), + ?line ok = rpc:call(Node, dbg, ln, []), + ?line ok = dbg:ln(), + ?line S = self(), + ?line {TraceSend, TraceCall} = + lists:partition(fun ({trace,RP,send,_,_}) when RP =:= RexPid -> true; + (_) -> false end, + flush()), + ?line [_|_] = TraceSend, + ?line [{trace,Pid,call,{dbg,ltp,[]}}, + {trace,S,call,{dbg,ln,[]}}] = TraceCall, + ?line Node = node(Pid), + %% + ?line stop() + after + ?line stop_slave(Node), + ?line stop() + end, + ok. + + +local_trace(suite) -> + []; +local_trace(doc) -> + ["Tests tracing of local function calls."]; +local_trace(Config) when is_list(Config) -> + ?line {ok, _} = start(), + try + ?line S = self(), + ?line %% Split "<X.Y.Z>" into {X, Y, Z} + ?line "<"++L1 = L = pid_to_list(S), + ?line NoDot = fun ($.) -> false; (_) -> true end, + ?line {LX,"."++L2} = lists:splitwith(NoDot, L1), + ?line {LY,"."++L3} = lists:splitwith(NoDot, L2), + ?line ">"++L4 = lists:reverse(L3), + ?line LZ = lists:reverse(L4), + ?line X = 0 = list_to_integer(LX), + ?line Y = list_to_integer(LY), + ?line Z = list_to_integer(LZ), + ?line XYZ = {X, Y, Z}, + ?line io:format("Self = ~w = ~w~n", [S,XYZ]), + ?line {ok, [{matched, _node, 1}]} = dbg:p(S,call), + ?line {ok, [{matched, _node, 1}]} = dbg:p(XYZ,call), + if Z =:= 0 -> + ?line {ok, [{matched, _node, 1}]} = dbg:p(Y,call); + true -> ok + end, + ?line {ok, [{matched, _node, 1}]} = dbg:p(L,call), + ?line {ok, _} = dbg:tpl(?MODULE,not_exported,[]), + ?line 4 = not_exported(2), + ?line [{trace,S,call,{?MODULE,not_exported,[2]}}] = flush(), + ?line {ok, _} = dbg:tp(?MODULE,exported,[]), + ?line 4 = ?MODULE:exported(2), + ?line [{trace,S,call,{?MODULE,exported,[2]}}, + {trace,S,call,{?MODULE,not_exported,[2]}}] = flush(), + ?line {ok, _} = dbg:ctpl(?MODULE), + ?line 4 = ?MODULE:exported(2), + ?line [{trace,S,call,{?MODULE,exported,[2]}}] = flush(), + ?line {ok, _} = dbg:tpl(?MODULE,not_exported,[]), + ?line {ok, _} = dbg:ctp(?MODULE), + ?line 4 = ?MODULE:exported(2), + ?line [] = flush(), + ?line {ok, _} = dbg:tpl(?MODULE,not_exported,x), + ?line catch ?MODULE:exported(x), + ?line [{trace,S,call,{dbg_SUITE,not_exported,[x]}}, + {trace,S,exception_from, + {dbg_SUITE,not_exported,1}, + {error,badarith}}] = flush() + after + ?line stop() + end, + ok. + +saved_patterns(suite) -> + []; +saved_patterns(doc) -> + ["Tests saving of match_spec's."]; +saved_patterns(Config) when is_list(Config) -> + ?line dbg:stop(), + ?line {ok,[{saved,1}]} = + dbg:tp(dbg,ctp,1,[{'_',[],[{message, blahonga}]}]), + ?line {ok,[{saved,2}]} = + dbg:tp(dbg,ctp,1,[{['_'],[],[{message, blahonga}]}]), + ?line Privdir=?config(priv_dir, Config), + ?line file:make_dir(Privdir), + ?line File = filename:join([Privdir, "blahonga.ms"]), + ?line dbg:wtp(File), + ?line dbg:stop(), + ?line dbg:ctp('_','_','_'), + ?line {ok, _} = start(), + try + ?line dbg:rtp(File), + ?line {ok,[{matched,_node,1},{saved,1}]} = dbg:tp(dbg,ltp,0,1), + ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call), + ?line dbg:ltp(), + ?line S = self(), + ?line [{trace,S,call,{dbg,ltp,[]},blahonga}] = flush() + after + ?line stop() + end, + ok. + + + +not_exported(N) -> + N * 2. + +exported(N) -> + not_exported(N). + +ip_port(suite) -> + []; +ip_port(doc) -> + ["Test tracing to IP port"]; +ip_port(Config) when is_list(Config) -> + ?line stop(), + ?line Port = dbg:trace_port(ip, 0), + ?line {ok, _} = dbg:tracer(port, Port), + try + ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call), + ?line {ok, X} = dbg:tp(dbg, ltp,[{'_',[],[{message, {self}}]}]), + ?line {value, {saved, _Saved}} = lists:keysearch(saved, 1, X), + ?line {ok, Y} = dbg:tp(dbg, ln, [{'_',[],[{message, hej}]}]), + ?line {value, {saved, _}} = lists:keysearch(saved, 1, Y), + ?line ok = dbg:ltp(), + ?line ok = dbg:ln(), + ?line {ok, IpPort} = dbg:trace_port_control(get_listen_port), + ?line io:format("IpPort = ~p~n", [IpPort]), + ?line dbg:trace_client(ip, IpPort, {fun myhandler/2, self()}), + ?line S = self(), + ?line [{trace,S,call,{dbg,ltp,[]},S}, + {trace,S,call,{dbg,ln,[]},hej}] = flush() + after + ?line stop() + end, + ok. + + + +ip_port_busy(suite) -> + []; +ip_port_busy(doc) -> + ["Test that the dbg server does not hang if the tracer don't start ", + "(OTP-3592)"]; +ip_port_busy(Config) when is_list(Config) -> + ?line stop(), + ?line Tracer = dbg:trace_port(ip, 4745), + ?line Port = Tracer(), + ?line {error, Reason} = dbg:tracer(port, Tracer), + try + ?line io:format("Error reason = ~p~n", [Reason]), + ?line true = port_close(Port) + after + ?line dbg:stop() + end, + ?line ok. + + + +file_port(suite) -> + []; +file_port(doc) -> + ["Test tracing to file port (simple)"]; +file_port(Config) when is_list(Config) -> + ?line stop(), + ?line {A,B,C} = erlang:now(), + ?line FTMP = atom_to_list(?MODULE) ++ integer_to_list(A) ++ "-" ++ + integer_to_list(B) ++ "-" ++ integer_to_list(C), + ?line FName = filename:join([?config(data_dir, Config), FTMP]), + ?line Port = dbg:trace_port(file, FName), + ?line {ok, _} = dbg:tracer(port, Port), + try + ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call), + ?line {ok, X} = dbg:tp(dbg, ltp,[{'_',[],[{message, {self}}]}]), + ?line {value, {saved, _Saved}} = lists:keysearch(saved, 1, X), + ?line {ok, Y} = dbg:tp(dbg, ln, [{'_',[],[{message, hej}]}]), + ?line {value, {saved, _}} = lists:keysearch(saved, 1, Y), + ?line ok = dbg:ltp(), + ?line ok = dbg:ln(), + ?line stop(), + ?line dbg:trace_client(file, FName, {fun myhandler/2, self()}), + ?line S = self(), + ?line [{trace,S,call,{dbg,ltp,[]},S}, + {trace,S,call,{dbg,ln,[]},hej}, + end_of_trace] = flush() + after + ?line stop(), + ?line file:delete(FName) + end, + ok. + +file_port2(suite) -> + []; +file_port2(doc) -> + ["Test tracing to file port with 'follow_file'"]; +file_port2(Config) when is_list(Config) -> + case os:type() of + vxworks -> + {skipped, "VxWorks NFS cache ruins it all."}; + _ -> + ?line stop(), + ?line {A,B,C} = erlang:now(), + ?line FTMP = atom_to_list(?MODULE) ++ integer_to_list(A) ++ + "-" ++ integer_to_list(B) ++ "-" ++ integer_to_list(C), + ?line FName = filename:join([?config(data_dir, Config), FTMP]), + %% Ok, lets try with flush and follow_file, not a chance on VxWorks + %% with NFS caching... + ?line Port2 = dbg:trace_port(file, FName), + ?line {ok, _} = dbg:tracer(port, Port2), + try + ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call), + ?line {ok, _} = dbg:tp(dbg, ltp,[{'_',[],[{message, {self}}]}]), + ?line {ok, _} = dbg:tp(dbg, ln, [{'_',[],[{message, hej}]}]), + ?line ok = dbg:ltp(), + ?line ok = dbg:flush_trace_port(), + ?line dbg:trace_client(follow_file, FName, + {fun myhandler/2, self()}), + ?line S = self(), + ?line [{trace,S,call,{dbg,ltp,[]},S}] = flush(), + ?line ok = dbg:ln(), + ?line ok = dbg:flush_trace_port(), + ?line receive after 1000 -> ok end, %% Polls every second... + ?line [{trace,S,call,{dbg,ln,[]},hej}] = flush(), + ?line stop(), + ?line [] = flush() + after + ?line stop(), + ?line file:delete(FName) + end, + ok + end. + +file_port_schedfix(suite) -> + []; +file_port_schedfix(doc) -> + ["Test that the scheduling timestamp fix for trace flag 'running' works."]; +file_port_schedfix(Config) when is_list(Config) -> + ?line case (catch erlang:system_info(smp_support)) of + true -> + {skip, "No schedule fix on SMP"}; + _ -> + try + file_port_schedfix1(Config) + after + dbg:stop() + end + end. +file_port_schedfix1(Config) when is_list(Config) -> + ?line stop(), + ?line {A,B,C} = erlang:now(), + ?line FTMP = atom_to_list(?MODULE) ++ integer_to_list(A) ++ + "-" ++ integer_to_list(B) ++ "-" ++ integer_to_list(C), + ?line FName = filename:join([?config(data_dir, Config), FTMP]), + %% + ?line Port = dbg:trace_port(file, {FName, wrap, ".wraplog", 8*1024, 4}), + ?line {ok, _} = dbg:tracer(port, Port), + ?line {ok,[{matched,_node,0}]} = dbg:p(new,[running,procs,send,timestamp]), + %% + %% Generate the trace data + %% + %% This starts 3 processes that sends a message to each other in a ring, + %% 4 laps. Prior to sending the message to the next in the ring, each + %% process send 8 messages to itself, just to generate some trace data, + %% and to lower the possibility that the trace log wraps just after + %% a schedule out message (which would not burden any process and hence + %% not show up in the result) + %% + %% The wrap file trace is used because it burns a lot of time when the + %% driver swaps files, a lot more than the regular file trace. The test + %% case is dimensioned so that the log fills two files and just starts + %% on the third (out of four wrap files). This gives two file swaps, + %% and there are three processes, so one process will NOT be burdened. + %% The criterion for trace success is then that the max process + %% execution time must not be more than twice the min process + %% execution time. Wallclock. A normal result is about 10 times more + %% without schedule in - schedule out compensation (OTP-3938). + %% + ?line ok = token_volleyball(3, 4, 8), + %% + ?line {ok,[{matched,_,_}]} = dbg:p(all, [clear]), + ?line stop(), + % Some debug code to run on all platforms, for finding the fault on genny + % Dont touch please /PaN + ?line io:format("Trace dump by PaN BEGIN~n"), + ?line dbg:trace_client(file,{FName, wrap, ".wraplog"},{fun(end_of_trace,Pid)-> Pid ! done; (Mesg,Pid) -> io:format("~w~n",[Mesg]),Pid end,self()}), + receive done -> ok end, + ?line io:format("Trace dump by PaN END~n"), + %% + %% Get the trace result + %% + ?line Tag = make_ref(), + ?line dbg:trace_client(file, {FName, wrap, ".wraplog"}, + {fun schedstat_handler/2, {self(), Tag, []}}), + ?line Result = + receive + {Tag, D} -> + lists:map( + fun({Pid, {A1, B1, C1}}) -> + {Pid, C1/1000000 + B1 + A1*1000000} + end, + D) + end, + ?line ok = io:format("Result=~p", [Result]), +% erlang:display({?MODULE, ?LINE, Result}), + %% + %% Analyze the result + %% + ?line {Min, Max} = + lists:foldl( + fun({_Pid, M}, {Mi, Ma}) -> + {if M < Mi -> M; true -> Mi end, + if M > Ma -> M; true -> Ma end} + end, + {void, 0}, + Result), + % More PaN debug + ?line io:format("Min = ~f, Max = ~f~n",[Min,Max]), + %% + %% Cleanup + %% + ?line ToBeDeleted = filelib:wildcard(FName++"*"++".wraplog"), + ?line lists:map({file, delete}, ToBeDeleted), +% io:format("ToBeDeleted=~p", [ToBeDeleted]), + %% + %% Present the result + %% + P = (Max / Min - 1) * 100, + BottomLine = lists:flatten(io_lib:format("~.2f %", [P])), + if P > 100 -> + Reason = {BottomLine, '>', "100%"}, + erlang:display({file_port_schedfix, fail, Reason}), + test_server:fail(Reason); + true -> + {comment, BottomLine} + end. + +wrap_port(suite) -> + []; +wrap_port(doc) -> + ["Test tracing to wrapping file port"]; +wrap_port(Config) when is_list(Config) -> + ?line Self = self(), + ?line stop(), + ?line {A,B,C} = erlang:now(), + ?line FTMP = atom_to_list(?MODULE) ++ integer_to_list(A) ++ "-" ++ + integer_to_list(B) ++ "-" ++ integer_to_list(C) ++ "-", + ?line FName = filename:join([?config(data_dir, Config), FTMP]), + ?line FNameWildcard = FName++"*"++".trace", + %% WrapSize=0 and WrapCnt=11 will force the trace to wrap after + %% every trace message, and to contain only the last 10 entries + %% after trace stop since the last file will be empty waiting + %% for its first trace message. + ?line WrapSize = 0, + ?line WrapCnt = 11, + ?line WrapFilesSpec = {FName, wrap, ".trace", WrapSize, WrapCnt}, + ?line wrap_port_init(WrapFilesSpec), + %% The number of iterations, N, is tested to place wrap the log, + %% giving a gap in the filename sequence at index 3. + %% This should be a difficult case for + %% the trace_client file sorting functionality. + N = 7, + ?line lists:foreach( + fun(Cnt) -> + ?MODULE:tracee1(Cnt), + ?MODULE:tracee2(Cnt) + end, + lists:seq(1, N)), + ?line stop(), + try + ?line Files1 = filelib:wildcard(FNameWildcard), + ?line io:format("~p~n", [Files1]), + ?line Tc1 = dbg:trace_client(file, WrapFilesSpec, + {fun myhandler/2, {wait_for_go,Self}}), + ?line Tref1 = erlang:monitor(process, Tc1), + Tc1 ! {go,Self}, + ?line [{'DOWN',Tref1,_,_,normal}, + end_of_trace + |Result] = lists:reverse(flush()), + ?line M = N - (WrapCnt-1) div 2, + ?line M = wrap_port_result(Result, Self, N), + %% + %% Start a new wrap log with the same name to verify that + %% all files are cleared at wrap log start. Only produce + %% two trace messages to also place the gap at index 3, + %% so the trace log will be misinterpreted. + %% + ?line wrap_port_init(WrapFilesSpec), + ?line Files2 = filelib:wildcard(FNameWildcard), + ?line io:format("~p~n", [Files2]), + ?line -1 = ?MODULE:tracee1(-1), + ?line -1 = ?MODULE:tracee2(-1), + ?line stop(), + ?line Files = filelib:wildcard(FNameWildcard), + ?line io:format("~p~n", [Files]), + ?line Tc2 = dbg:trace_client(file, WrapFilesSpec, + {fun myhandler/2, {wait_for_go,Self}}), + ?line Tref2 = erlang:monitor(process, Tc2), + Tc2 ! {go,Self}, + ?line [{trace,Self,call,{?MODULE,tracee1,[-1]},Self}, + {trace,Self,call,{?MODULE,tracee2,[-1]},hej}, + end_of_trace, + {'DOWN',Tref2,_,_,normal}] = flush(), + %% + ?line lists:map(fun(F) -> file:delete(F) end, Files) + after + ?line stop() + end, + ok. + +wrap_port_init(WrapFilesSpec) -> + ?line Port = dbg:trace_port(file, WrapFilesSpec), + ?line {ok, _} = dbg:tracer(port, Port), + ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call), + ?line {ok, X} = dbg:tp(?MODULE, tracee1,[{'_',[],[{message, {self}}]}]), + ?line {value, {saved, _Saved}} = lists:keysearch(saved, 1, X), + ?line {ok, Y} = dbg:tp(?MODULE, tracee2, [{'_',[],[{message, hej}]}]), + ?line {value, {saved, _}} = lists:keysearch(saved, 1, Y), + ok. + +tracee1(X) -> + X. + +tracee2(X) -> + X. + +wrap_port_result([], _S, M) -> + M; +wrap_port_result([{trace, S, call, {?MODULE, tracee2, [M]}, hej}, + {trace, S, call, {?MODULE, tracee1, [M]}, S} | Tail], + S, + M) -> + wrap_port_result(Tail, S, M-1). + + +wrap_port_time(suite) -> + []; +wrap_port_time(doc) -> + ["Test tracing to time limited wrapping file port"]; +wrap_port_time(Config) when is_list(Config) -> + ?line stop(), + ?line {A,B,C} = erlang:now(), + ?line FTMP = atom_to_list(?MODULE) ++ integer_to_list(A) ++ "-" ++ + integer_to_list(B) ++ "-" ++ integer_to_list(C) ++ "-", + ?line FName = filename:join([?config(data_dir, Config), FTMP]), + %% WrapTime=2 and WrapCnt=4 will force the trace to wrap after + %% every 2 seconds, and to contain between 3*2 and 4*2 seconds + %% of trace entries. + ?line WrapFilesSpec = {FName, wrap, ".trace", {time, 2000}, 4}, + ?line Port = dbg:trace_port(file, WrapFilesSpec), + ?line {ok, _} = dbg:tracer(port, Port), + try + ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call), + ?line {ok, X} = dbg:tp(?MODULE, tracee1,[{'_',[],[{message, {self}}]}]), + ?line {value, {saved, _Saved1}} = lists:keysearch(saved, 1, X), + ?line {ok, Y} = dbg:tp(?MODULE, tracee2, [{'_',[],[{message, hej}]}]), + ?line {value, {saved, _Saved2}} = lists:keysearch(saved, 1, Y), + %% The delays in the iterations places two trace messages in each + %% trace file, but the last which is empty waiting for its first + %% trace message. The number of iterations is chosen so that + %% one trace file has been wasted, and therefore the first pair + %% of trace messages. + ?line lists:foreach( + fun(Cnt) -> + receive after 1000 -> ok end, + ?MODULE:tracee1(Cnt), + ?MODULE:tracee2(Cnt), + receive after 1100 -> ok end + end, + lists:seq(1, 4)), + ?line stop(), + ?line Files = filelib:wildcard(FName ++ "*" ++ ".trace"), + ?line io:format("~p~n", [Files]), + ?line dbg:trace_client(file, WrapFilesSpec, {fun myhandler/2, self()}), + ?line S = self(), + ?line [{trace, S, call, {?MODULE, tracee1, [2]}, S}, + {trace, S, call, {?MODULE, tracee2, [2]}, hej}, + {trace, S, call, {?MODULE, tracee1, [3]}, S}, + {trace, S, call, {?MODULE, tracee2, [3]}, hej}, + {trace, S, call, {?MODULE, tracee1, [4]}, S}, + {trace, S, call, {?MODULE, tracee2, [4]}, hej}, + end_of_trace] = flush(), + ?line lists:map(fun(F) -> file:delete(F) end, Files) + after + ?line stop() + end, + ok. + +with_seq_trace(suite) -> + []; +with_seq_trace(doc) -> + ["Test ordinary tracing combined with seq_trace"]; +with_seq_trace(Config) when is_list(Config) -> + try + ?line {ok, Server} = start(), + ?line {ok, Tracer} = dbg:get_tracer(), + ?line {ok, X} = dbg:tp(dbg, get_tracer, [{[],[], + [{set_seq_token, send, true}]}]), + ?line {value, {saved, _}} = lists:keysearch(saved, 1, X), + ?line {ok, [{matched, _node, 1}]} = dbg:p(self(),call), + ?line seq_trace:set_system_tracer(Tracer), + ?line dbg:get_tracer(), + receive + after 1 -> + ok + end, + ?line S = self(), + ?line ThisNode = node(), + ?line [{trace,S,call,{dbg,get_tracer,[]}}, + {seq_trace,0,{send,_,S,Server,{S,{get_tracer,ThisNode}}}}, + {seq_trace,0,{send,_,Server,S,{dbg,{ok,Tracer}}}}] = + flush() + after + ?line stop() + end, + ok. + +dead_suspend(suite) -> + []; +dead_suspend(doc) -> + ["Test that trace messages concerning a now dead process does " + "not crash dbg."]; + +dead_suspend(Config) when is_list(Config) -> + ?line start(), + try + survived = run_dead_suspend() + after + ?line stop() + end. + +run_dead_suspend() -> + dbg:p(new, call), + dbg:tp(?MODULE, dummy, []), + spawn(?MODULE, dummy, []), + spawn(?MODULE, dummy, []), + spawn(?MODULE, dummy, []), + spawn(?MODULE, dummy, []), + spawn(?MODULE, dummy, []), + receive after 1000 -> ok end, + case whereis(dbg) of + undefined -> + died; + _ -> + survived + end. + +dummy() -> + ok. + + +%% +%% Support functions +%% + +start_slave() -> + {A, B, C} = now(), + Name = "asdkxlkmd" ++ integer_to_list(A+B+C), + {ok, Node} = test_server:start_node(Name,slave,[]), + ok = wait_node(Node, 15), + Node. + +stop_slave(Node) -> + test_server:stop_node(Node). + +wait_node(_,0) -> + no; +wait_node(Node, N) -> + case net_adm:ping(Node) of + pong -> + ok; + pang -> + receive + after 1000 -> + ok + end, + wait_node(Node, N - 1) + end. + +myhandler(Message, {wait_for_go,Pid}) -> + receive + {go,Pid} -> + myhandler(Message, Pid) + end; +myhandler(Message, Relay) -> + Relay ! Message, + case Message of + end_of_trace -> + ok; + _ -> + Relay + end. + +flush() -> + flush([]). +flush(Acc) -> + receive + X -> + flush(Acc ++ [X]) + after 1000 -> + Acc + end. + +start() -> + stop(), + dbg:tracer(process, {fun myhandler/2, self()}). + +stop() -> + dbg:stop(). + + + +schedstat_handler(TraceMsg, {Parent, Tag, Data} = State) -> + case TraceMsg of + {trace_ts, Pid, in, _, Ts} -> + NewData = + case lists:keysearch(Pid, 1, Data) of + {value, {Pid, Acc}} -> + [{Pid, Acc, Ts} | lists:keydelete(Pid, 1, Data)]; + false -> + [{Pid, {0, 0, 0}, Ts} | Data]; + Other -> + exit(Parent, {?MODULE, ?LINE, Other}), + erlang:display({?MODULE, ?LINE, Other}), + Data + end, + {Parent, Tag, NewData}; + {trace_ts, Pid, out, _, {A3, B3, C3}} -> + NewData = + case lists:keysearch(Pid, 1, Data) of + {value, {Pid, {A1, B1, C1}, {A2, B2, C2}}} -> + [{Pid, {A3-A2+A1, B3-B2+B1, C3-C2+C1}} | + lists:keydelete(Pid, 1, Data)]; + Other -> + exit(Parent, {?MODULE, ?LINE, Other}), + erlang:display({?MODULE, ?LINE, Other}), + Data + end, + {Parent, Tag, NewData}; + {trace_ts, Pid, exit, normal, {A3, B3, C3}} -> + NewData = + case lists:keysearch(Pid, 1, Data) of + {value, {Pid, {A1, B1, C1}, {A2, B2, C2}}} -> + [{Pid, {A3-A2+A1, B3-B2+B1, C3-C2+C1}} | + lists:keydelete(Pid, 1, Data)]; + {value, {Pid, _Acc}} -> + Data; + false -> + [{Pid, {0, 0, 0}} | Data]; + Other -> + exit(Parent, {?MODULE, ?LINE, Other}), + erlang:display({?MODULE, ?LINE, Other}), + Data + end, + {Parent, Tag, NewData}; + {trace_ts, _Pid, send, _Msg, _OtherPid, _Ts} -> + State; + end_of_trace -> + Parent ! {Tag, Data}, + State + end. + + + +pass_token(Token, Next, Loops) -> + receive + {Token, 1} = Msg -> + sendloop(Loops), + Next ! Msg; + {Token, _Cnt} = Msg-> + sendloop(Loops), + Next ! Msg, + pass_token(Token, Next, Loops) + end. + +pass_token(Token, Final, Cnt, Loops) -> + receive + {Token, start, Next} -> + sendloop(Loops), + Msg = {Token, Cnt}, + Next ! Msg, + pass_token(Token, Final, Next, Cnt, Loops) + end. + +pass_token(Token, Final, Next, Cnt, Loops) -> + receive + {Token, 1} -> + sendloop(Loops), + Msg = {Token, done}, + Final ! Msg; + {Token, Cnt} -> + sendloop(Loops), + NextCnt = Cnt-1, + Msg = {Token, NextCnt}, + Next ! Msg, + pass_token(Token, Final, Next, NextCnt, Loops) + end. + +sendloop(Loops) -> + sendloop(make_ref(), Loops). + +sendloop(_Tag, 0) -> + ok; +sendloop(Tag, Loops) -> + self() ! {Tag, Loops}, + receive {Tag, Loops} -> ok end, + sendloop(Tag, Loops-1). + +token_volleyball(N, Cnt, Loops) + when is_integer(N), N >= 1, is_integer(Cnt), Cnt >= 1, + is_integer(Loops), Loops >= 0 -> + Self = self(), + Token = make_ref(), + Last = spawn_link(fun() -> pass_token(Token, Self, Cnt, Loops) end), + First = token_volleyball(Token, Last, N-1, Loops), + Last ! {Token, start, First}, + receive {Token, done} -> ok end. + +token_volleyball(Token, Next, 1, Loops) -> + spawn_link(fun() -> pass_token(Token, Next, Loops) end); +token_volleyball(Token, Next, N, Loops) -> + Pid = spawn_link(fun() -> pass_token(Token, Next, Loops) end), + token_volleyball(Token, Pid, N-1, Loops). diff --git a/lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl b/lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl new file mode 100644 index 0000000000..2edbf6f99a --- /dev/null +++ b/lib/runtime_tools/test/dbg_SUITE_data/dbg_test.erl @@ -0,0 +1,87 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%%%---------------------------------------------------------------------- +%%% Purpose : A priority queue. +%%%---------------------------------------------------------------------- +%%% This module implements a priority queue as defined in +%%% "Priority Queues and the STL" by Mark Nelson in Dr.Dobb's Journal, Jan 1996 +%%% see http://web2.airmail.net/markn/articles/pq_stl/priority.htm for more +%%% information. (A heap implementation is planned aswell) +%%%---------------------------------------------------------------------- +%%% The items of the queue is kept priority sorted, and because of that, +%%% a push() operation costs more than a pop() operation (wich only +%%% needs to return the top item of the queue(read: list)). +%%%---------------------------------------------------------------------- +%%% The priority queue can be deceptively nice to use when creating for +%%% example a Huffman coding tree. +%%% See http://web2.airmail.net/markn/articles/pq_stl/priority.htm or +%%% Dr.Dobb's Journal Jan, 96 for more information on this. +%%%---------------------------------------------------------------------- + +%%% Used here strictly as something for dbg_SUITE to run. + +-module(dbg_test). +-export([test/1, loop/1]). +-export([new/0, push/3, pop/1]). + +loop(Config) -> + test(Config), + receive + {dbg_test, stop} -> + ok; + Other -> + loop(Config) + end, + ok. + +test(Config) -> + Q1=new(), + Q2=push(Q1, "monkey", 3), + Q3=push(Q2, "banana", 4), + Q4=push(Q3, "jungle", 2), + Q5=push(Q4, "world", 5), + Q6=push(Q5, "universe",6), + Q7=push(Q6, "peanut", 1), +% io:format("~p~n",[Q7]), + {Itm, Q8}=pop(Q7), + ok. + +%% Returns a new priority queue. +new() -> + []. + +%% Pushes a new item with a set priority into the queue. +push(Queue, Itm, Pri) -> + insert(Queue, Itm, Pri, []). + +%% Pops the item with the highest priority out of the queue. +pop([{Itm, Pri}|Queue]) -> + {Itm, Queue}. + +%% --- -- - +%% Support functions. +insert([], Itm, Pri, NewQ) -> + lists:flatten([lists:reverse(NewQ)|[{Itm, Pri}]]); +% Itm>QItm>NewQ>Queue +insert([{QItm,QPri}|Queue], Itm, Pri, NewQ) when Pri>QPri-> + A = [{Itm, Pri}|[{QItm, QPri}]], + lists:flatten([[A|NewQ]|Queue]); +insert([QItm|Rest], Itm, Pri, NewQ) -> + insert(Rest, Itm, Pri, [QItm|NewQ]). +%% --- -- - diff --git a/lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl b/lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl new file mode 100644 index 0000000000..85faf620aa --- /dev/null +++ b/lib/runtime_tools/test/dbg_SUITE_data/exref_td.erl @@ -0,0 +1,50 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(exref_td). + +-export([a/1,b/1,c/1,d/1,e/1,my_analyse/1]). + +a("edcba") -> + true; +a(_) -> + lists:reverse("abcde"). + +b(_) -> + a(nil). + +c(_) -> + nonexistentmodule:f(). + +d(_) -> + lists:nonexistentfunction(). + +e(_) -> + [a(x),b(x),c(x)]. + +localfuncnotcalled() -> + true. + +localfunccalledbyf(A) -> + A. + +f() -> + lists:filter(fun localfunccalledbyf/1,"aaabba"), + F = fun localfuncnotcalled/0. + +my_analyse(Graph) -> ok. diff --git a/lib/runtime_tools/test/erts_alloc_config_SUITE.erl b/lib/runtime_tools/test/erts_alloc_config_SUITE.erl new file mode 100644 index 0000000000..32483dbe73 --- /dev/null +++ b/lib/runtime_tools/test/erts_alloc_config_SUITE.erl @@ -0,0 +1,206 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(erts_alloc_config_SUITE). + +%-define(line_trace, 1). + +-include("test_server.hrl"). + +%-compile(export_all). +-export([all/1, init_per_testcase/2, fin_per_testcase/2]). + +%% Testcases +-export([basic/1]). + +%% internal export +-export([make_basic_config/1]). + +-define(DEFAULT_TIMEOUT, ?t:minutes(2)). + +all(doc) -> []; +all(suite) -> [basic]. + +init_per_testcase(Case, Config) when is_list(Config) -> + [{testcase, Case}, + {watchdog, ?t:timetrap(?DEFAULT_TIMEOUT)}, + {erl_flags_env, save_env()} | Config]. + +fin_per_testcase(_Case, Config) when is_list(Config) -> + ?t:timetrap_cancel(?config(watchdog, Config)), + restore_env(?config(erl_flags_env, Config)), + ok. + +%%% +%%% The test cases ------------------------------------------------------------ +%%% + +basic(doc) -> []; +basic(suite) -> []; +basic(Config) when is_list(Config) -> + ?line ErtsAllocConfig = privfile("generated", Config), + + SbctMod = " +MBsbct 1024 +MHsbct 4096", + + %% Make sure we have enabled allocators + ZFlgs = case os:getenv("ERL_ZFLAGS") of + FlgString when is_list(FlgString) -> + FlgString; + _ -> + "" + end ++ " +Mea max +Mea config", + + ?line os:putenv("ERL_ZFLAGS", ZFlgs ++ SbctMod), + + ?line {ok, Node1} = start_node(Config), + ?line ok = rpc:call(Node1, ?MODULE, make_basic_config, [ErtsAllocConfig]), + ?line stop_node(Node1), + + ?line display_file(ErtsAllocConfig), + + ?line ManualConfig = privfile("manual", Config), + ?line {ok, IOD} = file:open(ManualConfig, [write]), + ?line io:format(IOD, "~s", ["+MBsbct 2048"]), + ?line file:close(IOD), + ?line display_file(ManualConfig), + + ?line os:putenv("ERL_ZFLAGS", ZFlgs), + + ?line {ok, Node2} = start_node(Config, + "-args_file " ++ ErtsAllocConfig + ++ " -args_file " ++ ManualConfig), + + ?line {_, _, _, Cfg} = rpc:call(Node2, erlang, system_info, [allocator]), + + ?line stop_node(Node2), + + ?line {value,{binary_alloc, BCfg}} = lists:keysearch(binary_alloc, 1, Cfg), + ?line {value,{sbct, 2097152}} = lists:keysearch(sbct, 1, BCfg), + ?line {value,{eheap_alloc, HCfg}} = lists:keysearch(eheap_alloc, 1, Cfg), + ?line {value,{sbct, 4194304}} = lists:keysearch(sbct, 1, HCfg), + + ?line ok. + +make_basic_config(ErtsAllocConfig) -> + %% Save some different scenarios + Tester = self(), + SSBegun = make_ref(), + SSDone = make_ref(), + SSFun = fun (F) -> + receive + SSDone -> + ok = erts_alloc_config:save_scenario(), + Tester ! SSDone + after 500 -> + ok = erts_alloc_config:save_scenario(), + F(F) + end + end, + SS = spawn_link(fun () -> + ok = erts_alloc_config:save_scenario(), + Tester ! SSBegun, + SSFun(SSFun) + end), + receive SSBegun -> ok end, + Ref = make_ref(), + Tab = ets:new(?MODULE, [bag, public]), + Ps = lists:map( + fun (_) -> + spawn_link( + fun () -> + ets:insert(Tab, + {self(), + lists:seq(1, 1000)}), + receive after 1000 -> ok end, + Tester ! {Ref, self()} + end) + end, + lists:seq(1, 10000)), + lists:foreach(fun (P) -> receive {Ref, P} -> ok end end, Ps), + ets:delete(Tab), + SS ! SSDone, + receive SSDone -> ok end, + + ok = erts_alloc_config:make_config(ErtsAllocConfig). + + + +%% +%% Utils ---------------------------------------------------------------------- +%% + +display_file(FileName) -> + ?t:format("filename: ~s~n", [FileName]), + {ok, Bin} = file:read_file(FileName), + io:format("~s", [binary_to_list(Bin)]), + ?t:format("eof: ~s~n", [FileName]), + ok. + +mk_name(Config) when is_list(Config) -> + {A, B, C} = now(), + list_to_atom(atom_to_list(?MODULE) + ++ "-" ++ atom_to_list(?config(testcase, Config)) + ++ "-" ++ integer_to_list(A) + ++ "-" ++ integer_to_list(B) + ++ "-" ++ integer_to_list(C)). + +start_node(Config) -> + start_node(Config, ""). + +start_node(Config, Args) -> + ?line Pa = filename:dirname(code:which(?MODULE)), + ?line ?t:start_node(mk_name(Config), + slave, + [{args, "-pa " ++ Pa ++ " " ++ Args}]). + +stop_node(Node) -> + ?line true = ?t:stop_node(Node). + +privfile(Name, Config) -> + filename:join([?config(priv_dir, Config), + atom_to_list(?config(testcase, Config)) ++ "." ++ Name]). + +save_env() -> + {erl_flags, + os:getenv("ERL_AFLAGS"), + os:getenv("ERL_FLAGS"), + os:getenv("ERL_"++erlang:system_info(otp_release)++"_FLAGS"), + os:getenv("ERL_ZFLAGS")}. + +restore_env(EVar, false) when is_list(EVar) -> + restore_env(EVar, ""); +restore_env(EVar, "") when is_list(EVar) -> + case os:getenv(EVar) of + false -> ok; + "" -> ok; + " " -> ok; + _ -> os:putenv(EVar, " ") + end; +restore_env(EVar, Value) when is_list(EVar), is_list(Value) -> + case os:getenv(EVar) of + Value -> ok; + _ -> os:putenv(EVar, Value) + end. + +restore_env({erl_flags, AFlgs, Flgs, RFlgs, ZFlgs}) -> + restore_env("ERL_AFLAGS", AFlgs), + restore_env("ERL_FLAGS", Flgs), + restore_env("ERL_"++erlang:system_info(otp_release)++"_FLAGS", RFlgs), + restore_env("ERL_ZFLAGS", ZFlgs), + ok. diff --git a/lib/runtime_tools/test/inviso_SUITE.erl b/lib/runtime_tools/test/inviso_SUITE.erl new file mode 100644 index 0000000000..1c5c887b62 --- /dev/null +++ b/lib/runtime_tools/test/inviso_SUITE.erl @@ -0,0 +1,2840 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% Description: +%% Test suite for inviso (basic parts, i.e not inviso tools). Note that +%% inviso basic parts have modules in both the runtime_tools and +%% inviso applications. +%% +%% Authors: +%% Ann-Marie L�f, [email protected] +%% Lennart �hman, [email protected] +%% ----------------------------------------------------------------------------- + +-module(inviso_SUITE). +-compile(export_all). + +-include("test_server.hrl"). +-include_lib("kernel/include/file.hrl"). + +-define(l,?line). + +all(suite) -> + [ + basic_dist_trace_1, + basic_dist_trace_2, + basic_dist_trace_3, + basic_dist_trace_ti_1, + basic_dist_trace_ti_2, + basic_dist_trace_ti_3, + suspend_dist_trace_ti_1, + suspend_dist_trace_ti_2, + meta_cleanfunc_dist_1, + basic_handlerfun_dist_1, + delete_log_dist_1, + autostart_dist_1, + autostart_dist_2, + autostart_dist_3, + running_alone_dist_1, + running_alone_dist_2, + running_alone_dist_3, + running_alone_dist_4, + running_alone_dist_5, + overload_dist_1, + overload_dist_2, + overload_dist_3, + overload_dist_4, + overload_dist_5, + subscribe_dist_1, + lfm_trace_dist_1, + lfm_trace_ti_dist_2, + handle_logfile_sort_wrapset, + fetch_log_dist_trace_1, + fetch_log_dist_trace_2, + fetch_log_dist_trace_3, + fetch_log_dist_error_1, + fetch_log_dist_error_2, + expand_regexp_dist_1, + only_loaded_dist_1 + ]. + + +init_per_suite(Config) -> + %% No never know who skrewed up this node before this suite! :-) + erlang:trace_pattern({'_','_','_'},[],[local]), + erlang:trace_pattern({'_','_','_'},[],[global]), + erlang:trace(all,false,[all]), + + ?l ok=application:start(runtime_tools), + Config. + +end_per_suite(_Config) -> + ?l ok=application:stop(runtime_tools). + + +%% For each distributed testcase, we need two other distributed nodes to run the +%% runtime components on. Since they are freshly started every time there is no +%% need to clean them up first. +init_per_testcase(_Case,Config) -> + ?l TH=test_server:timetrap(100000), + ?l {ok,Node1}=test_server:start_node(inviso1,peer,[]), + ?l {ok,Node2}=test_server:start_node(inviso2,peer,[]), + ?l SuiteDir=filename:dirname(code:which(?MODULE)), + + %% Otherwise peer nodes will not find this module! + ?l true=rpc:call(Node1,code,add_patha,[SuiteDir]), + ?l true=rpc:call(Node2,code,add_patha,[SuiteDir]), + + ?l start_side_effect_logger(node()), + ?l start_side_effect_logger(Node1), + ?l start_side_effect_logger(Node2), + + + %% SPECIAL FOR MY PRIVATE TEST ENVIROMENT +% ?l rpc:call(Node1,code,add_patha,["/clearcase/otp/tools/runtime_tools/ebin"]), +% ?l rpc:call(Node1,code,add_patha,["/clearcase/otp/tools/inviso/ebin"]), +% ?l rpc:call(Node2,code,add_patha,["/clearcase/otp/tools/runtime_tools/ebin"]), +% ?l rpc:call(Node2,code,add_patha,["/clearcase/otp/tools/inviso/ebin"]), + +% %% SPECIAL FOR MY PRIVATE TEST ENVIROMENT, windows. +% ?l rpc:call(Node1,code,add_patha,["Z:/DATA/PROJECTS/inviso_project/runtime_tools/ebin"]), +% ?l rpc:call(Node1,code,add_patha,["Z:/DATA/PROJECTS/inviso_project/inviso/ebin"]), +% ?l rpc:call(Node2,code,add_patha,["Z:/DATA/PROJECTS/inviso_project/runtime_tools/ebin"]), +% ?l rpc:call(Node2,code,add_patha,["Z:/DATA/PROJECTS/inviso_project/inviso/ebin"]), + + ?l ok=rpc:call(Node1,application,start,[runtime_tools]), + ?l ok=rpc:call(Node2,application,start,[runtime_tools]), + ?l timer:sleep(100), % Problem with autostarted runtime. + %% The following is a test that the inviso_rt processes which are autostarted + %% are now gone. + + ?l ok=poll(rpc,call,[Node1,erlang,whereis,[inviso_rt]],undefined,20), + ?l ok=poll(rpc,call,[Node2,erlang,whereis,[inviso_rt]],undefined,20), + +% ?l ok=poll(rpc,call,[Node1,supervisor,which_children,[runtime_tools_sup]],[],20), +% ?l ok=poll(rpc,call,[Node2,supervisor,which_children,[runtime_tools_sup]],[],20), + NewConfig1=insert_remotenode_config(inviso1,Node1,Config), + NewConfig2=insert_remotenode_config(inviso2,Node2,NewConfig1), + insert_timetraphandle_config(TH,NewConfig2). +%% ----------------------------------------------------------------------------- + +fin_per_testcase(Case,Config) -> + ?l test_server:stop_node(get_remotenode_config(inviso1,Config)), + ?l test_server:stop_node(get_remotenode_config(inviso2,Config)), + + case whereis(inviso_c) of + undefined -> % Should not exist. + true; + Pid when is_pid(Pid) -> % But if it exists... + exit(Pid,kill), % Remove it! + io:format("Had to kill the control component in fin_per_testcase,~p.~n",[Case]) + end, + case whereis(inviso_rt) of + undefined -> % Should not exist. + true; + Pid2 when is_pid(Pid2) -> % But if it exists... + exit(Pid2,kill), % Remove it! + io:format("Had to kill local runtime component in fin_per_testcase,~p.~n",[Case]) + end, + ?l process_killer([inviso_test_proc, + inviso_tab_proc, + inviso_collector_proc, + global_inviso_test_proc]), + ?l test_server:timetrap_cancel(get_timetraphandle_config(Config)), + + NewConfig1=remove_remotenode_config(inviso1,Config), + NewConfig2=remove_remotenode_config(inviso2,NewConfig1), + remove_timetraphandle_config(NewConfig2). +%% ----------------------------------------------------------------------------- + +%% ============================================================================== +%% Testcases. +%% ============================================================================== + +%% TEST CASE: Basic, distributed, trace only. +basic_dist_trace_1(suite) -> []; +basic_dist_trace_1(doc) -> + ["Basic case, start of distributed tracing, using only trac."]; +basic_dist_trace_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList=lists:map(fun(N)->{N,{file,filename:join([PrivDir, + "tf1_"++ + atom_to_list(N) + ])}} end, + Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}), + activate_local_tracing(Nodes), + deactivate_local_tracing(Nodes), + stop_tracing(Nodes), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + + +%% TEST CASE: Basic, distributed, activate global tracing for functions in modules +%% pointed out using a regexp. No tracing will be done. +basic_dist_trace_2(suite) -> []; +basic_dist_trace_2(doc) -> + [""]; +basic_dist_trace_2(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList=lists:map(fun(N)->{N,{file,filename:join([PrivDir, + "tf1a_"++ + atom_to_list(N) + ])}} end, + Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}), + Funcs1=activate_global_tracing_regexp(Nodes), + deactivate_global_tracing_regexp(Nodes,Funcs1), + stop_tracing(Nodes), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Basic, distributed, activate global tracing for functions in modules +%% pointed out using a dir-regexp. No tracing will be done. +basic_dist_trace_3(suite) -> []; +basic_dist_trace_3(doc) -> + [""]; +basic_dist_trace_3(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList=lists:map(fun(N)->{N,{file,filename:join([PrivDir, + "tf1b_"++ + atom_to_list(N) + ])}} end, + Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}), + Funcs1=activate_global_tracing_regexp_dir(Nodes), + deactivate_global_tracing_regexp_dir(Nodes,Funcs1), + stop_tracing(Nodes), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Basic, distributed, trace and ti. +basic_dist_trace_ti_1(suite) -> []; +basic_dist_trace_ti_1(doc) -> + [""]; +basic_dist_trace_ti_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataFun= + fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf2_"++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir,"tf2_"++atom_to_list(N)++".ti"])}}]} + end, + TracerDataList=lists:map(TracerDataFun,Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}), + activate_local_tracing(Nodes), + activate_meta_tracing(Nodes), + ?l true=(is_pid(whereis(inviso_rt))), + ?l true=(is_pid(whereis(inviso_rt_meta))), + deactivate_meta_tracing(Nodes), + deactivate_local_tracing(Nodes), + stop_tracing(Nodes), + ?l true=(is_pid(whereis(inviso_rt))), % Shall still be running. + ?l ok=poll(erlang,whereis,[inviso_rt_meta],undefined,3), + stop(Nodes), + timer:sleep(200), % Give it time to terminate. + ?l ok=poll(erlang,whereis,[inviso_rt],undefined,3),% Shall be gone now. + ?l undefined=whereis(inviso_rt_meta), % Still gone. + ok. +%% ----------------------------------------------------------------------------- + +%% Test CASE: Testing that the tpm_tracer functionality works. That is appending +%% {tracer,Tracer} to a meta match spec. +basic_dist_trace_ti_2(suite) -> []; +basic_dist_trace_ti_2(doc) -> + [""]; +basic_dist_trace_ti_2(Config) when is_list(Config) -> + case erlang:system_info(version) of + "5.4"++_ -> % Perhaps not perfect, but work now :-) + {skip,"Old emulator"}; + _ -> + basic_dist_trace_ti_2_do(Config) + end. + +basic_dist_trace_ti_2_do(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataFun= + fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf3_"++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir,"tf3_"++atom_to_list(N)++".ti"])}}]} + end, + TracerDataList=lists:map(TracerDataFun,Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}), + activate_deactivate_meta_tracing_tracer(Nodes), + stop_tracing(Nodes), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Basic, distributed, trace and ti, where we try to use ctp_all to +%% check that all global and local patterns are removed but that meta patterns +%% remain. +%% This test also checks that if the meta tracer is terminated an error value +%% is generated when trying to do meta tracing at that node. +basic_dist_trace_ti_3(suite) -> []; +basic_dist_trace_ti_3(doc) -> + [""]; +basic_dist_trace_ti_3(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataFun= + fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf4_"++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir,"tf4_"++atom_to_list(N)++".ti"])}}]} + end, + TracerDataList=lists:map(TracerDataFun,Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}), + activate_local_tracing(Nodes), + activate_global_tracing(Nodes), + activate_meta_tracing(Nodes), + ?l true=(is_pid(whereis(inviso_rt))), + ?l true=(is_pid(whereis(inviso_rt_meta))), + ?l {ok,NodeResults1}=inviso:ctp_all(Nodes), % Removes local and global patterns. + ?l true=check_noderesults(Nodes,ok,NodeResults1), + ?l true=check_on_nodes(Nodes,erlang,trace_info,[{code,which,1},traced],{traced,false}), + ?l true=check_on_nodes(Nodes,erlang,trace_info,[{code,get_path,0},traced],{traced,false}), + %% But meta patters shall remain. + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{lists,module_info,0},meta_match_spec], + fun({meta_match_spec,L})when length(L)>0 ->true end), + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{lists,module_info,0},meta], + fun({meta,P})when is_pid(P) -> + P=rpc:call(node(P),erlang,whereis,[inviso_rt_meta]), + true + end), + %% Now kill the meta tracer somewhere and try to activate meta tracing. + ?l [ANode|_]=Nodes, + ?l AMetaPid=rpc:call(ANode,erlang,whereis,[inviso_rt_meta]), + ?l rpc:call(ANode,erlang,exit,[AMetaPid,kill]), + ?l {ok,NodeResults2}=inviso:tpm(Nodes,math,pi,0,[],void), + ?l {value,{ANode,{error,_}}}=lists:keysearch(ANode,1,NodeResults2), + + ?l stop_tracing(Nodes), + ?l stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% ----------------------------------------------------------------------------- +%% Test cases for SUSPEND +%% ----------------------------------------------------------------------------- + +%% TEST CASE: In this test case a trace with ti is started. Trace flags are set, +%% trace patterns are set and meta trace patterns. We then check that the trace +%% flags and the meta patterns are removed when tracing suspended. +%% The suspension is cancelled and we check that it is possible to reactivate +%% tracing by setting the process flags and meta patterns again. +suspend_dist_trace_ti_1(suite) -> []; +suspend_dist_trace_ti_1(doc) -> + [""]; +suspend_dist_trace_ti_1(Config) when is_list(Config) -> + ?l RemoteNodes=get_remotenodes_config(Config), + ?l Nodes=[node()|RemoteNodes], + ?l PrivDir=filename:join(?config(priv_dir,Config),""), + ?l TracerDataFun= + fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf_suspend1_"++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir,"tf_suspend1_"++atom_to_list(N)++".ti"])}}]} + end, + ?l TracerDataList=lists:map(TracerDataFun,Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}), + activate_local_tracing(Nodes), + activate_meta_tracing(Nodes), + ?l true=(is_pid(whereis(inviso_rt))), + ?l true=(is_pid(whereis(inviso_rt_meta))), + %% Set some trace flags on some newly started test procs. + activate_traceflags(Nodes), + + %% Now suspend the tracing on all nodes. That shall result in the removal + %% of trace flags and meta trace patterns, but not local trace patterns. + ?l {ok,NodeResults1}=inviso:suspend(Nodes,test), + ?l true=check_noderesults(Nodes,ok,NodeResults1), + %% Trace flags gone? + ?l TestProcs=lists:map(fun(N)->rpc:call(N,erlang,whereis,[inviso_test_proc]) end,Nodes), + ?l lists:foreach(fun(P)-> + {flags,[]}= + rpc:call(node(P),erlang,trace_info,[P,flags]) + end, + TestProcs), + %% Meta patterns shall be gone too, but local functions still there. + ?l lists:foreach(fun(N)-> + {meta,false}= + rpc:call(N, + erlang, + trace_info, + [{math,module_info,1},meta]), + {traced,local}= + rpc:call(N, + erlang, + trace_info, + [{code,which,1},traced]) + end, + Nodes), + + %% Try to activate trace flags, trace patterns and meta tracing while + %% suspended. Should not succeed of course! + ?l ThisNode=node(), + ?l {ok,[{ThisNode,{error,suspended}}]}= + inviso:tf([ThisNode],inviso_test_proc,[call]), + ?l {ok,[{ThisNode,{error,suspended}}]}= + inviso:tpl([ThisNode],math,module_info,1,[]), + ?l {ok,[{ThisNode,{error,suspended}}]}= + inviso:init_tpm([ThisNode], + math, + module_info, + 1, + {?MODULE,tpm_init_func2}, % Does not exist on purpose. + {?MODULE,tpm_call_func2}, % Does not exist on purpose. + {?MODULE,tpm_return_func2}, % Does not exist on purpose. + {?MODULE,tpm_remove_func2}), % Does not exist on purpose. + + %% Now we want to cancel suspension and see that we can reactivate tracing. + ?l {ok,NodeResults2}=inviso:cancel_suspension(Nodes), + ?l true=check_noderesults(Nodes,ok,NodeResults2), + + ?l {ok,NodeResults3}= + inviso:init_tpm(math, + module_info, + 1, + {?MODULE,tpm_init_func2}, % Does not exist on purpose. + {?MODULE,tpm_call_func2}, % Does not exist on purpose. + {?MODULE,tpm_return_func2}, % Does not exist on purpose. + {?MODULE,tpm_remove_func2}), % Does not exist on purpose. + ?l true=check_noderesults(Nodes,ok,NodeResults3), + ?l {ok,NodeResults5}= + inviso:tpm_ms(math,module_info,1,ms1,[{'_',[],[{return_trace}]}]), + ?l true=check_noderesults(Nodes,{ok,1},NodeResults5), + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{math,module_info,1},meta_match_spec], + {meta_match_spec,[{'_',[],[{return_trace}]}]}), + ?l {ok,NodeResults6}=inviso:tf(Nodes,inviso_test_proc,[call]), + ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults6), + + %deactivate_meta_tracing(Nodes), + %deactivate_local_tracing(Nodes), + stop_tracing(Nodes), + ?l true=(is_pid(whereis(inviso_rt))), % Shall still be running. + ?l ok=poll(erlang,whereis,[inviso_rt_meta],undefined,3), + stop(Nodes), + ?l timer:sleep(200), % Give it time to terminate. + ?l ok=poll(erlang,whereis,[inviso_rt],undefined,3),% Shall be gone now. + ?l undefined=whereis(inviso_rt_meta), % Still gone. + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: In this test case a trace with ti is started. Trace flags are set, +%% trace patterns are set and meta trace patterns. We then suspend tracing at +%% all nodes, then stop tracing which shall be allowed. We then try to initiate +%% tracing again which shall not be possible. +suspend_dist_trace_ti_2(suite) -> []; +suspend_dist_trace_ti_2(doc) -> + [""]; +suspend_dist_trace_ti_2(Config) when is_list(Config) -> + ?l RemoteNodes=get_remotenodes_config(Config), + ?l Nodes=[node()|RemoteNodes], + ?l PrivDir=filename:join(?config(priv_dir,Config),""), + ?l TracerDataFun= + fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf_suspend2_"++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir,"tf_suspend2_"++atom_to_list(N)++".ti"])}}]} + end, + ?l TracerDataList=lists:map(TracerDataFun,Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}), + activate_local_tracing(Nodes), + activate_meta_tracing(Nodes), + ?l true=(is_pid(whereis(inviso_rt))), + ?l true=(is_pid(whereis(inviso_rt_meta))), + %% Set some trace flags on some newly started test procs. + activate_traceflags(Nodes), + + %% Now suspend the tracing on all nodes. That shall result in the removal + %% of trace flags and meta trace patterns, but not local trace patterns. + ?l {ok,NodeResults1}=inviso:suspend(Nodes,test), + ?l true=check_noderesults(Nodes,ok,NodeResults1), + + %% Now stop tracing. + ?l {ok,NodeResults3}=inviso:stop_tracing(Nodes), + ?l true=check_noderesults(Nodes,{ok,idle},NodeResults3), + %% Now try to initiate tracing again. + ThisNode=node(), + ?l {ok,[{ThisNode,{error,suspended}}]}= + inviso:init_tracing([ThisNode], + [{trace,{file,filename:join([PrivDir,"tf_suspend3_"++ + atom_to_list(ThisNode)])}}, + {ti,{file,{filename:join([PrivDir,"tf_suspend3_"++ + atom_to_list(ThisNode)])}}}]), + + %% Cancel the suspension and initiate tracing again. + ?l {ok,NodeResults2}=inviso:cancel_suspension(Nodes), + ?l true=check_noderesults(Nodes,ok,NodeResults2), + ?l TracerDataFun2= + fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf_suspend4_"++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir,"tf_suspend4_"++atom_to_list(N)++".ti"])}}]} + end, + ?l TracerDataList2=lists:map(TracerDataFun2,Nodes), + ?l {ok,NodeResults4}=inviso:init_tracing(TracerDataList2), + ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok},{ti_log,ok}]},NodeResults4), + stop_tracing(Nodes), + ?l true=(is_pid(whereis(inviso_rt))), % Shall still be running. + stop(Nodes), + ?l timer:sleep(200), % Give it time to terminate. + ?l ok=poll(erlang,whereis,[inviso_rt],undefined,3),% Shall be gone now. + ok. +%% ----------------------------------------------------------------------------- + + + +%% TEST CASE: This test case tests that the clean function removes (prosumed) +%% expired data from the internal public-loopdata structure in the inviso_rt_meta +%% process. +meta_cleanfunc_dist_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataFun= + fun(N)->{N,[{trace,{file,filename:join([PrivDir,"mcf1_"++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir,"mcf1_"++atom_to_list(N)++".ti"])}}]} + end, + TracerDataList=lists:map(TracerDataFun,Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}), + %% Now initialize meta tracing, but the call_func is a bit "fixed". + ?l {ok,NodeResults1}= + inviso:tpm(Nodes,math,module_info,1,[], + {?MODULE,meta_cleanfunc_initfunc_1}, + {?MODULE,meta_cleanfunc_callfunc_1}, + void,void), + ?l true=check_noderesults(Nodes,{ok,1},NodeResults1), + %% Nothing in the "our" part of the public loop data. + ?l true=check_on_nodes(Nodes, + inviso_rt_meta,get_state,[inviso_rt_meta], + fun({ok,_LD,{{_,[]},_}})->true end), + ?l lists:foreach(fun(N)->rpc:call(N,math,module_info,[exports]) end,Nodes), + %% Check that it has been added to the public loopdata structure. + ?l true=check_on_nodes(Nodes, + ?MODULE,poll,[inviso_rt_meta, + get_state, + [inviso_rt_meta], + fun({ok,_LD,{{_,[{meta_cleanfunc_test1,_Now}]},_}})-> + true; + (_)->false + end, + 20], + ok), + %% While we wait for 60 seconds to pass, we test a few other things. + ?l {ok,NodeResults2}= + inviso:tpm(Nodes,?MODULE,slowfunction2,0,[{'_',[],[{return_trace}]}], + {?MODULE,meta_cleanfunc_initfunc_2}, + {?MODULE,meta_cleanfunc_callfunc_2}, + {?MODULE,meta_cleanfunc_returnfunc_2}, + void), + ?l true=check_noderesults(Nodes,{ok,1},NodeResults2), + ?l lists:foreach(fun(N)->rpc:call(N,?MODULE,slowfunction,[]) end,Nodes), + %% Believe it or not but slowfunction is still running, in its own process, + %% we are therefore free now to examine the meta tracer. + ?l true=check_on_nodes(Nodes, + ?MODULE,poll,[inviso_rt_meta, + get_state, + [inviso_rt_meta], + fun({ok,_LD,{{[],Tuples},_}})-> + {value,_}= + lists:keysearch(meta_cleanfunc_test2, + 1, + Tuples), + {value,_}= + lists:keysearch(meta_cleanfunc_test1, + 1, + Tuples), + true; + (_)-> + false + end, + 20], + ok), + %% Now we wait for slowfunction to return and that the meta_cleanfunc_test2 + %% to be removed from public loopdata strucuture. + ?l timer:sleep(10000), + %% The only thing remaining should be the meta_cleanfunc_test1 which will not + %% go away for less than that the clean functionality removes it. + ?l true=check_on_nodes(Nodes, + ?MODULE,poll,[inviso_rt_meta, + get_state, + [inviso_rt_meta], + fun({ok,_LD,{{_,[{meta_cleanfunc_test1,_Now}]},_}})-> + true; + (_)-> + false + end, + 20], + ok), + %% Wait for the clean function to clean meta_cleanfunc_test1 away. + ?l timer:sleep(51000), % Shall be gone after 5 seconds. + ?l true=check_on_nodes(Nodes, + ?MODULE,poll,[inviso_rt_meta, + get_state, + [inviso_rt_meta], + fun({ok,_LD,{{_,[]},_}})->true; + (_)->false + end, + 20], + ok), + stop_tracing(Nodes), + stop(Nodes), + ok. + +%% This function acts as tpm initialization function when we are going to test +%% that the clean function works. Note that we here assume standard public loop +%% datastructure. +meta_cleanfunc_initfunc_1(_M,_F,_Arity,{E1,_E2}) -> + {ok,{E1,[]},void}. +%% Function that is supposed to be called when the meta traced function is +%% called. +meta_cleanfunc_callfunc_1(_Pid,_Args,{{E1,E2},Global}) -> + {ok,{{E1,[{meta_cleanfunc_test1,now()}|E2]},Global},void}. + +meta_cleanfunc_initfunc_2(_M,_F,_Arity,PublLD) -> + {ok,PublLD,void}. +meta_cleanfunc_callfunc_2(_Pid,_Args,{{E1,E2},Global}) -> + {ok,{{E1,[{meta_cleanfunc_test2,now()}|E2]},Global},void}. +meta_cleanfunc_returnfunc_2(_Pid,_,{{E1,E2},Global}) -> + {value,_}=lists:keysearch(meta_cleanfunc_test2,1,E2), + {ok,{{E1,lists:keydelete(meta_cleanfunc_test2,1,E2)},Global},void}. + +slowfunction() -> + spawn(?MODULE,slowfunction1,[]). +slowfunction1() -> + slowfunction2(). % Meta trace on this function call. +slowfunction2() -> + timer:sleep(2000), + true. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Testing that a runtime component can be started instructing it +%% to use a handler fun. Checks that the handler fun is called if a trace +%% message comes in. +basic_handlerfun_dist_1(suite) -> []; +basic_handlerfun_dist_1(doc) -> + [""]; +basic_handlerfun_dist_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + ?l lists:foreach(fun(N)->rpc:call(N,ets,insert,[inviso_sideeffect_tab,{bhf1,0}]) end, + Nodes), + TracerDataFun= + fun(N)->{N,{fun basic_handlerfun_dist_1_fun/2,inviso_sideeffect_tab}} end, + TracerDataList=lists:map(TracerDataFun,Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}), + activate_local_tracing(Nodes), + activate_traceflags(Nodes), + ?l lists:foreach(fun(N)->[{bhf1,0}]= + rpc:call(N,ets,lookup,[inviso_sideeffect_tab,bhf1]) + end, + Nodes), + ?l inviso_test_proc ! {apply,code,which,[lists]}, + ok=poll(ets,lookup,[inviso_sideeffect_tab,bhf1],[{bhf1,1}],20), + deactivate_traceflags(Nodes), + deactivate_local_tracing(Nodes), + stop_tracing(Nodes), + timer:sleep(100), + ?l [{bhf1,1}]=ets:lookup(inviso_sideeffect_tab,bhf1), + stop(Nodes), + ok. + +%% Function used as handler fun for testcase above. +basic_handlerfun_dist_1_fun(_Msg,TId) -> + ets:update_counter(TId,bhf1,1), + TId. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Here we test that delete_log removes the files at the involved +%% runtime nodes. In this case we test that we remove logs according to last +%% used tracer data. +delete_log_dist_1(suite) -> []; +delete_log_dist_1(doc) -> [""]; +delete_log_dist_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataFun= + fun(N)->{N,[{trace,{file,filename:join([PrivDir,"dl1_"++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir,"dl1_"++atom_to_list(N)++".ti"])}}]} + end, + TracerDataList=lists:map(TracerDataFun,Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}), + ?l Files=lists:map(fun({N,TD})-> + ?l {value,{_,{_,TraceFile}}}=lists:keysearch(trace,1,TD), + ?l {value,{_,{_,TiFile}}}=lists:keysearch(ti,1,TD), + ?l {N,{TraceFile,TiFile}} + end, + TracerDataList), + io:format("The Files is:~w~n",[Files]), + ?l {ok,NodeResults1}=inviso:delete_log(Nodes), % Should not work! + ?l true=check_noderesults(Nodes,{error,tracing},NodeResults1), + stop_tracing(Nodes), + %% Files still here. + ?l lists:foreach(fun({N,{F1,F2}})-> + ?l {ok,_}=rpc:call(N,file,read_file_info,[F1]), + ?l {ok,_}=rpc:call(N,file,read_file_info,[F2]) + end, + Files), + ?l {ok,NodeResults2}=inviso:delete_log(Nodes), + ?l true=check_noderesults(Nodes, + fun({_N,{ok,LogInfos}})-> + ?l {value,{_,[{ok,_FName1}]}}= + lists:keysearch(trace_log,1,LogInfos), + ?l {value,{_,[{ok,_FName2}]}}= + lists:keysearch(ti_log,1,LogInfos), + true + end, + NodeResults2), + %% The files shall be gone now. + ?l lists:foreach(fun({N,{F1,F2}})-> + ?l {error,enoent}=rpc:call(N,file,read_file_info,[F1]), + ?l {error,enoent}=rpc:call(N,file,read_file_info,[F2]) + end, + Files), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + + +%% TEST CASE: Test of the autostart behaviour of the runtime component. +%% Here we test that a runtime component is started according to the autostart.conf +%% file. Note that the repeat parameter is set to 2. +autostart_dist_1(suite) -> []; +autostart_dist_1(doc) -> + [""]; +autostart_dist_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + PrivDir=filename:join(?config(priv_dir,Config),""), + AutoConfFile=filename:join(PrivDir,"autostart1.conf"), + [RNode|_]=RemoteNodes, + ?l ok=rpc:call(RNode,application,stop,[runtime_tools]), + ?l ok=rpc:call(RNode,application,set_env,[runtime_tools, + inviso_autostart_conf, + AutoConfFile]), + ?l {ok,FD}=file:open(AutoConfFile,[write]), + ?l ok=io:format(FD,"~w.~n~w.~n",[{repeat,2},{tag,c_ref}]), + ?l file:close(FD), + ?l ok=rpc:call(RNode,application,start,[runtime_tools]), + timer:sleep(1000), + ?l P1=rpc:call(RNode,erlang,whereis,[inviso_rt]), + ?l true=is_pid(P1), + ?l rpc:call(RNode,erlang,exit,[P1,kill]), + ?l ok=rpc:call(RNode,application,stop,[runtime_tools]), + ?l ok=rpc:call(RNode,application,start,[runtime_tools]), + timer:sleep(1000), + ?l P2=rpc:call(RNode,erlang,whereis,[inviso_rt]), + ?l true=is_pid(P2), + ?l rpc:call(RNode,erlang,exit,[P2,kill]), + ?l ok=rpc:call(RNode,application,stop,[runtime_tools]), + ?l ok=rpc:call(RNode,application,start,[runtime_tools]), + timer:sleep(1000), + ?l undefined=rpc:call(RNode,erlang,whereis,[inviso_rt]), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Test of autostart. Here we focus on that an autostarted +%% runtime component actually follows the trace case command file and +%% initiates tracing. +autostart_dist_2(suite) -> []; +autostart_dist_2(doc) -> + [""]; +autostart_dist_2(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + PrivDir=filename:join(?config(priv_dir,Config),""), + AutoConfFile=filename:join(PrivDir,"autostart2.conf"), + [RNode|_]=RemoteNodes, + ?l ok=rpc:call(RNode,application,stop,[runtime_tools]), + ?l ok=rpc:call(RNode,application,set_env,[runtime_tools, + inviso_autostart_conf, + AutoConfFile]), + ?l CmdFileName=filename:join(PrivDir,"autostart_cmd_as1"), + ?l {ok,FD}=file:open(CmdFileName,[write]), + ?l ok=io:format(FD, + "inviso:tpl(Nodes,M,F,Arity,[]).~n" + "inviso:tf(Nodes,inviso_test_proc,[call]).~n", + []), + ?l file:close(FD), + ?l TraceFileName=filename:join([PrivDir,"as1_"++atom_to_list(RNode)]), + ?l TiFileName=filename:join([PrivDir,"as1_"++atom_to_list(RNode)++".ti"]), + ?l inviso_as_lib:setup_autostart(RNode, + 2, + [], + [{trace,{file,TraceFileName}}, + {ti,{file,TiFileName}}], + [[CmdFileName]], + [{'M',code},{'F',which},{'Arity',1}], + [{{inviso,tpl,5},{inviso_rt,tpl,{erlang,tl}}}, + {{inviso,tf,3},{inviso_rt,tf,{erlang,tl}}}]), + ?l TestP=spawn(RNode,?MODULE,test_proc_init,[]), + ?l ok=rpc:call(RNode,application,start,[runtime_tools]), + ?l timer:sleep(1000), + ?l {ok,_}=file:read_file_info(TraceFileName), + ?l {ok,_}=file:read_file_info(TiFileName), + ?l true=is_pid(P=rpc:call(RNode,erlang,whereis,[inviso_rt])), + ?l ok=poll(rpc,call,[RNode,erlang,trace_info,[{code,which,1},traced]],{traced,local},10), + ?l {flags,[call]}=rpc:call(RNode,erlang,trace_info,[TestP,flags]), + ?l rpc:call(RNode,erlang,exit,[P,kill]), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Here we test that an autostarted runtime component with a dependency +%% to a specific control component tries to connect to that control component +%% during its start-up. +autostart_dist_3(suite) -> []; +autostart_dist_3(doc) -> + [""]; +autostart_dist_3(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + PrivDir=filename:join(?config(priv_dir,Config),""), + AutoConfFile=filename:join(PrivDir,"autostart3.conf"), + [RNode|_]=RemoteNodes, + ?l ok=rpc:call(RNode,application,stop,[runtime_tools]), + ?l ok=rpc:call(RNode,application,set_env,[runtime_tools, + inviso_autostart_conf, + AutoConfFile]), + ?l {ok,FD}=file:open(AutoConfFile,[write]), + ?l ok=io:format(FD,"~w.~n~w.~n~w.~n", + [{options,[{dependency,{infinity,node()}}]},{repeat,2},{tag,c_ref}]), + ?l file:close(FD), + %% Now start inviso at this node here for the runtime to connect. + ?l {ok,_Pid}=inviso:start(), + ?l ok=poll(erlang,whereis,[inviso_c],fun(P) when is_pid(P)->true;(_)->false end,10), + %% Make the runtime component start. + ?l ok=rpc:call(RNode,application,start,[runtime_tools]), + ?l ok=poll(rpc,call,[RNode,erlang,whereis,[inviso_rt]], + fun(P) when is_pid(P)->true;(_)->false end,10), + %% Check that the runtime component started. + ?l ok=poll(inviso,get_status,[[RNode]],{ok,[{RNode,{ok,{new,running}}}]},20), +% ?l {ok,[{RNode,{ok,{new,running}}}]}=inviso:get_status([RNode]), + stop([RNode]), + ok. +%% ----------------------------------------------------------------------------- + + + +%% TEST CASE: Test of the dependency mechanism in the runtime component. +%% Default behaviour is dependency=infinity, i.e the runtime components remains. +%% We also test here that we can reconnect to the runtime. +running_alone_dist_1(suite) -> []; +running_alone_dist_1(doc) -> + [""]; +running_alone_dist_1(Config) when is_list(Config) -> + ?l {ok,_Pid1}=inviso:start(), % Start a control component. + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,[]), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + ?l shutdown=inviso:stop(), % Stop the control component! + ?l undefined=whereis(inviso_c), + timer:sleep(3000), % How long shall we wait? :-) + ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end, + Nodes), + ?l {ok,_Pid2}=inviso:start(), + ?l {ok,NodeResults2}=inviso:add_nodes(Nodes,b_ref,[]), + ?l true=check_noderesults(Nodes,{ok,{adopted,new,running,a_ref}},NodeResults2), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Test of the dependency mechanism in the runtime component. +%% Test that the runtime components terminates after the specified 5000 ms. +running_alone_dist_2(suite) -> []; +running_alone_dist_2(doc) -> + [""]; +running_alone_dist_2(Config) when is_list(Config) -> + ?l {ok,_Pid1}=inviso:start(), % Start a control component. + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,[{dependency,5000}]), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + ?l shutdown=inviso:stop(), % Stop the control component! + ?l undefined=whereis(inviso_c), + timer:sleep(2000), + ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end, + Nodes), + timer:sleep(4000), % Now they shall be dead! + ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt]) end, + Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Test of the dependency mechanism in the runtime component. +%% Test that the runtime components terminates after the specified 5000 ms. +running_alone_dist_3(suite) -> []; +running_alone_dist_3(doc) -> + [""]; +running_alone_dist_3(Config) when is_list(Config) -> + ?l {ok,_Pid1}=inviso:start(), % Start a control component. + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,[{dependency,1000}]), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + ?l {ok,NodeResults2}=inviso:change_options(Nodes,[{dependency,5000}]), + ?l true=check_noderesults(Nodes,ok,NodeResults2), + ?l shutdown=inviso:stop(), % Stop the control component! + ?l undefined=whereis(inviso_c), + timer:sleep(3000), + ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end, + Nodes), + timer:sleep(3000), % Now they shall be dead! + ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt]) end, + Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Test of the dependency mechanism in the runtime component. +%% Test that the runtime components terminates after the specified 5000 ms, +%% like we did in running_alone_dist_2. But now we also start tracing and checks +%% that all inviso processes actually disappears when the time-out is reached. +running_alone_dist_4(suite) -> []; +running_alone_dist_4(doc) -> + [""]; +running_alone_dist_4(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + %% Start some tracing! + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataFun= + fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf_ra4"++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir,"tf_ra4_"++atom_to_list(N)++".ti"])}}]} + end, + TracerDataList=lists:map(TracerDataFun,Nodes), + start_and_init_tracing2(Nodes, + [{dependency,5000}], + TracerDataList, + {ok,[{trace_log,ok},{ti_log,ok}]}), + + ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end, + Nodes), + ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt_meta])) end, + Nodes), + %% Stop control component and wait for the runtimes to terminate after + %% running alone timer has expired. + ?l shutdown=inviso:stop(), % Stop the control component! + ?l undefined=whereis(inviso_c), + timer:sleep(2000), + ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end, + Nodes), + ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt_meta])) end, + Nodes), + timer:sleep(4000), % Now they shall be dead! + ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt]) end, + Nodes), + ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt_meta]) end, + Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Test of the dependency mechanism in the runtime component. +%% Test that the runtime components terminates imeediately when the control +%% component is stopped. Check that all processes are gone. +running_alone_dist_5(suite) -> []; +running_alone_dist_5(doc) -> + [""]; +running_alone_dist_5(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + %% Start some tracing! + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataFun= + fun(N)->{N,[{trace,{file,filename:join([PrivDir,"tf_ra5"++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir,"tf_ra5_"++atom_to_list(N)++".ti"])}}]} + end, + TracerDataList=lists:map(TracerDataFun,Nodes), + start_and_init_tracing2(Nodes, + [{dependency,0}], + TracerDataList, + {ok,[{trace_log,ok},{ti_log,ok}]}), + + ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt])) end, + Nodes), + ?l lists:foreach(fun(N)->true=is_pid(rpc:call(N,erlang,whereis,[inviso_rt_meta])) end, + Nodes), + %% Stop control component and check that all runtime component processes have + %% terminate more or less immediately afterwards, since dependency==0. + ?l shutdown=inviso:stop(), % Stop the control component! + timer:sleep(100), + ?l undefined=whereis(inviso_c), + timer:sleep(500), + ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt]) end, + Nodes), + ?l lists:foreach(fun(N)->undefined=rpc:call(N,erlang,whereis,[inviso_rt_meta]) end, + Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Test of the overload protection mechanism. The mechanism checks +%% for overload using the callback approximately at the interval specified. +%% Check that it does not start protection until start of tracing. +overload_dist_1(suite) -> []; +overload_dist_1(doc) -> + [""]; +overload_dist_1(Config) when is_list(Config) -> + ?l {ok,_Pid1}=inviso:start(), % Start a control component. + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + ?l lists:foreach(fun(N)->true=rpc:call(N,ets,insert,[inviso_sideeffect_tab,{ovl1,0}]) end, + Nodes), % Initiate the counter. + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes, + a_ref, + [{overload,{{?MODULE,overload1},500}}]), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + timer:sleep(1000), % Give the loadcheck time to perform. + ?l [{_,0}]=ets:lookup(inviso_sideeffect_tab,ovl1), % Nothing should have happened. + + %% Overload check shall not start until we start tracing. + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList=lists:map(fun(N)->{N,[{trace, + {file,filename:join([PrivDir, + "tf_ovl1."++atom_to_list(N) + ])}}]} + end, + Nodes), + ?l {ok,NodeResults2}=inviso:init_tracing(TracerDataList), + ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok}]},NodeResults2), + timer:sleep(1500), % Give the loadcheck time to perform. + ?l [{_,N}]=ets:lookup(inviso_sideeffect_tab,ovl1), + ?l true=(N>=2), % After 1,5 seconds, at least 2 checks. + + %% Now change options and remove overload checking! + ?l {ok,NodeResults3}=inviso:change_options(Nodes,[overload]), + ?l true=check_noderesults(Nodes,ok,NodeResults3), + ?l [{_,N2}]=ets:lookup(inviso_sideeffect_tab,ovl1), + timer:sleep(1000), + ?l [{_,N2}]=ets:lookup(inviso_sideeffect_tab,ovl1), % No more loadchecks! + + stop_tracing(Nodes), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Test of the overload protection mechanism. In this case we focus +%% in that the init and remove functions are carried out at change_options and +%% when starting and stoping the runtime component. +overload_dist_2(suite) -> []; +overload_dist_2(doc) -> + [""]; +overload_dist_2(Config) when is_list(Config) -> + ?l {ok,_Pid1}=inviso:start(), % Start a control component. + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes, + a_ref, + [{overload,{{?MODULE,overload2}, + 500, + {?MODULE,overload2i,[]}, + {?MODULE,overload2r,[]}}}]), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + ?l [{_,0}]=ets:lookup(inviso_sideeffect_tab,ovl2), + + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList=lists:map(fun(N)->{N,[{trace, + {file,filename:join([PrivDir, + "tf_ovl2."++atom_to_list(N) + ])}}]} + end, + Nodes), + ?l {ok,NodeResults2}=inviso:init_tracing(TracerDataList), + ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok}]},NodeResults2), + timer:sleep(1500), % Give the loadcheck time to perform. + ?l [{_,N}]=ets:lookup(inviso_sideeffect_tab,ovl2), + io:format("� is:~p~n",[N]), + ?l true=(N>=2), % After 1,5 seconds, at least 2 checks. + ?l {ok,NodeResults3}=inviso:change_options(Nodes,[{overload,{{?MODULE,overload3}, + 500, + {?MODULE,overload3i,[]}, + {?MODULE,overload3r,[]}}}]), + ?l true=check_noderesults(Nodes,ok,NodeResults3), + ?l []=ets:lookup(inviso_sideeffect_tab,ovl2), + timer:sleep(1500), + ?l [{_,N2}]=ets:lookup(inviso_sideeffect_tab,ovl3), + ?l true=(N2>=2), % After 1,5 seconds, at least 2 checks. + stop_tracing(Nodes), + ?l []=ets:lookup(inviso_sideeffect_tab,ovl3r), % Remove function shall not be called. + ?l [{_,N3}]=ets:lookup(inviso_sideeffect_tab,ovl3), + timer:sleep(1000), % Check that overloadchecking has stopped. + ?l [{_,N3}]=ets:lookup(inviso_sideeffect_tab,ovl3), + stop(Nodes), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,ovl3r],[{ovl3r,done}],20), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Test of the overload protections mechanism. Here we focus on testing +%% that if overload is reached tracing is really suspended. +overload_dist_3(suite) -> []; +overload_dist_3(doc) -> + [""]; +overload_dist_3(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList= + lists:map(fun(N)->{N,[{trace,{file,filename:join([PrivDir, + "tf_ovl3."++atom_to_list(N)])}}, + {ti,{file,filename:join([PrivDir, + "tf_ovl3_ti."++atom_to_list(N)])}}]} + end, + Nodes), + ?l lists:foreach(fun(N)-> + true=rpc:call(N,ets,insert,[inviso_sideeffect_tab,{ovl4,0}]) + end, + Nodes), + start_and_init_tracing2(Nodes, + [{overload,{{?MODULE,overload4},500}}], + TracerDataList, + {ok,[{trace_log,ok},{ti_log,ok}]}), + activate_local_tracing(Nodes), + activate_meta_tracing(Nodes), + activate_traceflags(Nodes), + timer:sleep(600), + ?l [{_,N1}]=ets:lookup(inviso_sideeffect_tab,ovl4), + ?l true=(N1>=1), % Overload check has been done! + ?l Node=node(), + ?l {ok,[{Node,{ok,{tracing,running}}}]}=inviso:get_status([node()]), + ?l true=ets:insert(inviso_sideeffect_tab,{ovl4_suspend,true}), + timer:sleep(600), + ?l {ok,[{Node,{ok,{tracing,{suspended,test}}}}]}=inviso:get_status([node()]), + ?l [{_,N2}]=ets:lookup(inviso_sideeffect_tab,ovl4), + ?l {flags,[]}=erlang:trace_info(whereis(inviso_test_proc),flags), + ?l {meta,false}=erlang:trace_info({lists,module_info,0},meta), + ?l {traced,local}=erlang:trace_info({code,which,1},traced), + ?l true=(is_pid(whereis(inviso_rt_meta))), + ?l true=ets:delete(inviso_sideeffect_tab,ovl4_suspend), + timer:sleep(600), + ?l [{_,N2}]=ets:lookup(inviso_sideeffect_tab,ovl4), % No checking while suspended! + ?l {ok,[{Node,ok}]}=inviso:cancel_suspension([node()]), + ?l {ok,NodeResults1}=inviso:get_status(Nodes), + ?l true=check_noderesults(Nodes,{ok,{tracing,running}},NodeResults1), + timer:sleep(600), + ?l [{_,N3}]=ets:lookup(inviso_sideeffect_tab,ovl4), + ?l true=(N3>N2), + ?l deactivate_local_tracing(Nodes), + ?l stop_tracing(Nodes), + ?l stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE. Test that the overload mechanism is triggered by to the runtime +%% component incomming messages, and nothing else. +overload_dist_4(suite) -> []; +overload_dist_4(doc) -> + [""]; +overload_dist_4(Config) when is_list(Config) -> + ?l {ok,_Pid1}=inviso:start(), % Start a control component. + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes, + a_ref, + [{overload,{{?MODULE,overload5}, + infinity, + {?MODULE,overload5i,[]}, + {?MODULE,overload5r,[]}}}]), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + ?l [{_,0}]=ets:lookup(inviso_sideeffect_tab,ovl5), + + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList=lists:map(fun(N)->{N,[{trace, + {file,filename:join([PrivDir, + "tf_ovl4."++atom_to_list(N) + ])}}]} + end, + Nodes), + ?l {ok,NodeResults2}=inviso:init_tracing(TracerDataList), + ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok}]},NodeResults2), + timer:sleep(2000), % Give the loadcheck time to perform. + ?l [{_,N}]=ets:lookup(inviso_sideeffect_tab,ovl5), + ?l true=(N==0), % And nothing shall have happend! + %% Now we send a message to the inviso_rt, then the load check function + %% shall be called. + ?l whereis(inviso_rt) ! test_of_loadcheck, + timer:sleep(200), % Make sure the inviso_rt gets scheduled. + ?l [{_,1}]=ets:lookup(inviso_sideeffect_tab,ovl5), + stop_tracing(Nodes), + ?l []=ets:lookup(inviso_sideeffect_tab,ovl5r), % Remove function shall not be called. + ?l [{_,N3}]=ets:lookup(inviso_sideeffect_tab,ovl5), + ?l whereis(inviso_rt) ! test_of_loadcheck, + timer:sleep(1000), % Check that overloadchecking has stopped. + ?l [{_,N3}]=ets:lookup(inviso_sideeffect_tab,ovl5), + stop(Nodes), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,ovl5r],[{ovl5r,done}],20), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE. Test that the overload mechanism correctly calculates remaining time +%% to next load check if a message comes into the runtime component "interupting" +%% the waiting for loadcheck timeout. (Loadcheck timeout is implemented as an after +%% in the receive). +overload_dist_5(suite) -> []; +overload_dist_5(doc) -> + [""]; +overload_dist_5(Config) when is_list(Config) -> + ?l {ok,_Pid1}=inviso:start(), % Start a control component. + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + ?l lists:foreach(fun(N)->true=rpc:call(N,ets,insert,[inviso_sideeffect_tab,{ovl6,0}]) end, + Nodes), % Initiate the counter. + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes, + a_ref, + [{overload,{{?MODULE,overload6},1000}}]), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + %% Overload check shall not start until we start tracing. + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList=lists:map(fun(N)->{N,[{trace, + {file,filename:join([PrivDir, + "tf_ovl5."++atom_to_list(N) + ])}}]} + end, + Nodes), + ?l {ok,NodeResults2}=inviso:init_tracing(TracerDataList), + ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok}]},NodeResults2), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,ovl6],[{ovl6,2}],25), + %% Now we know that exactly 2 checks have been made. Try to Distract the runtime :-) + ?l inviso_rt:state(whereis(inviso_rt)), % Make it have to receive a message. + timer:sleep(500), + ?l [{_,2}]=ets:lookup(inviso_sideeffect_tab,ovl6), % Should still be 2. + timer:sleep(600), + ?l [{_,3}]=ets:lookup(inviso_sideeffect_tab,ovl6), % We expect yet one check. + timer:sleep(1100), + ?l [{_,4}]=ets:lookup(inviso_sideeffect_tab,ovl6), + + stop_tracing(Nodes), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + + +%% TEST CASE: Test of the subscription mechanism. +subscribe_dist_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + Pid=spawn(?MODULE,inviso_msg_collector,[]), + CtrlPid=whereis(inviso_c), + + ?l {ok,_Pid}=inviso:start(), % Start a control component. + ?l ok=inviso:subscribe(Pid), + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,[]), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + ?l {ok,NodeResults2}=inviso:get_status(Nodes), + ?l true=check_noderesults(Nodes,{ok,{new,running}},NodeResults2), + check_msg_collector(Nodes, + fun({inviso_event,CP,_,{connected,N,{_Tag,{idle,running}}}}) + when CP==CtrlPid -> + {true,N}; + (_) -> + false + end, + 13), + TracerDataList=lists:map(fun(N)->{N,{file, + filename:join([PrivDir, + "tf_sub1"++atom_to_list(N)])}} + end, + Nodes), + ?l {ok,NodeResults3}=inviso:init_tracing(TracerDataList), + ?l true=check_noderesults(Nodes,{ok,[{trace_log,ok}]},NodeResults3), + check_msg_collector(Nodes, + fun({inviso_event,CP,_,{state_change,N,{tracing,running}}}) + when CP==CtrlPid -> + {true,N}; + (_) -> + false + end, + 13), + ?l {ok,NodeResults4}=inviso:suspend(Nodes,test), + ?l true=check_noderesults(Nodes,ok,NodeResults4), + check_msg_collector(Nodes, + fun({inviso_event,CP,_,{state_change,N,{tracing,{suspended,test}}}}) + when CP==CtrlPid -> + {true,N}; + (_) -> + false + end, + 13), + ?l [RNode|_]=RemoteNodes, + ?l RInvisoPid=rpc:call(RNode,erlang,whereis,[inviso_rt]), + ?l rpc:call(RNode,erlang,exit,[RInvisoPid,kill]), + check_msg_collector([RNode], + fun({inviso_event,CP,_,{disconnected,N,_Info}}) + when CP==CtrlPid -> + {true,N}; + (_) -> + false + end, + 11), + + ?l {ok,_NodeResults5}=inviso:stop_tracing(Nodes), + ?l {ok,_NodeResults6}=inviso:stop_nodes(Nodes), + ?l shutdown=inviso:stop(), + ok. +%% ----------------------------------------------------------------------------- + + +%% TEST CASE: fetch_log test of single straight trace_log file in distributed +%% environment. +fetch_log_dist_trace_1(suite) -> []; +fetch_log_dist_trace_1(doc) -> + ["fetch_log test of single straight trace_log file in distributed" + "environment."]; +fetch_log_dist_trace_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList=lists:map(fun(N)->{N,[{trace,{file,filename:join([PrivDir, + "testfile1."++ + atom_to_list(N) + ])}}]} end, + Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}), + + %% Put some output in the logs. + ?l inviso:tp(Nodes,math,module_info,0,[]), + ?l inviso:tf(Nodes,all,[call]), + ?l lists:foreach(fun(N)->rpc:call(N,math,module_info,[]) end,Nodes), + + stop_tracing(Nodes), + {H,M,S}=time(), + FetchToDir=filename:join([PrivDir, + "fetch_log_test1_"++integer_to_list(H)++"_"++ + integer_to_list(M)++"_"++integer_to_list(S)]), + ?l ok=file:make_dir(FetchToDir), + ?l {ok,NodeResults}=inviso:fetch_log(RemoteNodes,FetchToDir,"p1"), + io:format("~p~n",[NodeResults]), + ?l true=check_noderesults(RemoteNodes, + fun({N,{complete,[{trace_log,[{ok,File}]},{ti_log,[]}]}}) -> + ?l File="p1testfile1."++atom_to_list(N), + true; + (_)-> + false + end, + NodeResults), + ?l ON=filename:join(PrivDir,"testfile1."), + ?l FN=filename:join(FetchToDir,"p1testfile1."), + ?l lists:foreach(fun(N)-> + {ok,#file_info{size=Size}}= + file:read_file_info(ON++atom_to_list(N)), + {ok,#file_info{size=Size}}= + file:read_file_info(FN++atom_to_list(N)) + end, + RemoteNodes), + %% Now we wish to see that we get an incomplete if we try to fetch to a + %% directory that does not exist. + ?l FetchToErrorDir=filename:join([PrivDir,nonexistingingdir]), + ?l {ok,NodeResults2}=inviso:fetch_log(RemoteNodes,FetchToErrorDir,"p1"), + ?l io:format("NodeResults2:~w~n",[NodeResults2]), + ?l true=check_noderesults(RemoteNodes, + fun({_,{incomplete,_}}) -> + true; + (_)-> + false + end, + NodeResults2), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +fetch_log_dist_trace_2(suite) -> []; +fetch_log_dist_trace_2(doc) -> + [""]; +fetch_log_dist_trace_2(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + + {H,M,S}=time(), + ?l Name="wrap"++integer_to_list(H)++"_"++integer_to_list(M)++"_"++integer_to_list(S), + ?l BaseName=filename:join(PrivDir,Name), + Fun=fun(N)->{N,[{trace,{file,{BaseName++atom_to_list(N),wrap,".log",512,2}}}, + {ti,{file,BaseName++"_ti_"++atom_to_list(N)++".ti"}}]} + end, + ?l TracerDataList=lists:map(Fun,Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}), + fill_and_reach_two_wrapfiles(PrivDir,"^"++Name,Nodes), + + stop_tracing(Nodes), + FetchToDir=filename:join([PrivDir, + "fetch_log_test2_"++integer_to_list(H)++"_"++ + integer_to_list(M)++"_"++integer_to_list(S)]), + ?l ok=file:make_dir(FetchToDir), + ?l {ok,NodeResults}=inviso:fetch_log(RemoteNodes,FetchToDir,"p1"), + io:format("~p~n",[NodeResults]), + CheckFun=fun({N,{complete,[{trace_log,FileResults1},{ti_log,[{ok,TiFile}]}]}}) -> + Fun2=fun({ok,File}) -> + {match,1,_}= + regexp:first_match(File, + "^"++"p1"++Name++atom_to_list(N)), + true; + (_) -> + false + end, + ?l true=lists:all(Fun2,FileResults1), + ?l TiFile="p1"++Name++"_ti_"++atom_to_list(N)++".ti", + true; + (_)-> + false + end, + ?l true=check_noderesults(RemoteNodes,CheckFun,NodeResults), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +fetch_log_dist_trace_3(suite) -> []; +fetch_log_dist_trace_3(doc) -> + [""]; +fetch_log_dist_trace_3(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + + {H,M,S}=time(), + ?l Name="wrap2_"++integer_to_list(H)++"_"++integer_to_list(M)++"_"++integer_to_list(S), + ?l BaseName=filename:join(PrivDir,Name), + Fun=fun(N)->{N,[{trace,{file,{BaseName++atom_to_list(N),wrap,".log",512,2}}}, + {ti,{file,BaseName++"_ti_"++atom_to_list(N)++".ti"}}]} + end, + ?l TracerDataList=lists:map(Fun,Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}), + fill_and_reach_two_wrapfiles(PrivDir,"^"++Name,Nodes), + + stop_tracing(Nodes), + FetchToDir=filename:join([PrivDir, + "fetch_log_test3_"++integer_to_list(H)++"_"++ + integer_to_list(M)++"_"++integer_to_list(S)]), + ?l ok=file:make_dir(FetchToDir), + ?l {ok,NodeResults1}=inviso:list_logs(Nodes), + CheckFun=fun({N,{ok,[{trace_log,PrivDir2,[F1,F2]},{ti_log,PrivDir2,[F3]}]}})-> + PrivDir2=PrivDir, + RegExp="^"++Name++atom_to_list(N)++"[0-9]+"++"\.log", + {match,1,_}=regexp:first_match(F1,RegExp), + {match,1,_}=regexp:first_match(F2,RegExp), + F3=Name++"_ti_"++atom_to_list(N)++".ti", + true; + (_) -> + false + end, + ?l true=check_noderesults(Nodes,CheckFun,NodeResults1), + ?l NodeFileSpecList=lists:map(fun({N,{ok,L}})->{N,L} end, + lists:keydelete(node(),1,NodeResults1)), + ?l {ok,NodeResults2}=inviso:fetch_log(NodeFileSpecList,FetchToDir,"p1"), +io:format("~p~n",[NodeResults2]), + CheckFun2=fun({N,{complete,[{trace_log,FileResults1},{ti_log,[{ok,TiFile}]}]}}) -> + Fun2=fun({ok,File}) -> + {match,1,_}= + regexp:first_match(File, + "^"++"p1"++Name++atom_to_list(N)), + true; + (_) -> + false + end, + ?l true=lists:all(Fun2,FileResults1), + ?l TiFile="p1"++Name++"_ti_"++atom_to_list(N)++".ti", + true; + (_)-> + false + end, + ?l true=check_noderesults(RemoteNodes,CheckFun2,NodeResults2), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +fetch_log_dist_error_1(suite) -> []; +fetch_log_dist_error_1(doc) -> + [""]; +fetch_log_dist_error_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + ?l {ok,_Pid}=inviso:start(), % Start a control component. + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + ?l {ok,NodeResults2}=inviso:fetch_log(RemoteNodes,"foo","bar"), +io:format("~p~n",[NodeResults2]), + ?l true=check_noderesults(RemoteNodes, + fun({_N,{error,no_tracerdata}})->true; + (_)->false + end, + NodeResults2), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +fetch_log_dist_error_2(suite) -> []; +fetch_log_dist_error_2(doc) -> + [""]; +fetch_log_dist_error_2(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + PrivDir=filename:join(?config(priv_dir,Config),""), + ?l {ok,_Pid}=inviso:start(), % Start a control component. + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + ?l NodeLogList=lists:map(fun(N)->{N,[{trace_log, + PrivDir, + ["f1,fil","f2.fil"]}, + {ti_log, + PrivDir, + ["f.ti"]}]} + end, + RemoteNodes), + ?l {ok,NodeResults2}=inviso:fetch_log(NodeLogList,"foo","bar"), + io:format("~p~n",[NodeResults2]), + ?l true=check_noderesults(RemoteNodes, + fun({_N,{incomplete,_}}) -> + true; + (_) -> + false + end, + NodeResults2), + ?l NodeTracerData=lists:map(fun(N)->{N, + [{trace,{file,filename:join(PrivDir,"foo")}}, + {ti,{file,filename:join(PrivDir,"bar.ti")}}]} + end, + RemoteNodes), + {ok,NodeResults3}=inviso:fetch_log(NodeTracerData,"foo","bar"), + io:format("~p~n",[NodeResults3]), +%% This should work this way. Now it says complete [], which is not entirely +%% incorrect. But to follow the sematics of when fetching named files should +%% say incomplete. +%% Must do some rework to make that work. No real danger leaving it this way +%% for now. +% ?l true=check_noderesults(RemoteNodes, +% fun({_N,{incomplete,_}}) -> +% true; +% (_) -> +% false +% end, +% NodeResults3), + stop(Nodes), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: This case tests that the log file merger merges files in the +%% correct order, based on the timestamps. +lfm_trace_dist_1(suite) -> []; +lfm_trace_dist_1(doc) -> + [""]; +lfm_trace_dist_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + [RNode1,RNode2|_]=RemoteNodes, + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList= + lists:map(fun(N)->{N,{file,filename:join([PrivDir,"lfm1_"++atom_to_list(N)])}} end, + Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}), + activate_local_tracing(Nodes), + activate_traceflags(Nodes), + + {inviso_test_proc,RNode2} ! {apply,code,which,[lists]}, + timer:sleep(300), + {inviso_test_proc,RNode1} ! {apply,code,which,[lists]}, + timer:sleep(300), + {inviso_test_proc,RNode1} ! {apply,code,which,[lists]}, + timer:sleep(300), + inviso_test_proc ! {apply,code,which,[lists]}, + timer:sleep(300), + {inviso_test_proc,RNode2} ! {apply,code,which,[lists]}, + timer:sleep(300), + inviso_test_proc ! {apply,code,which,[lists]}, + + deactivate_traceflags(Nodes), + deactivate_local_tracing(Nodes), + stop_tracing(Nodes), + stop(Nodes), + + DestFile=filename:join(PrivDir,"lfm1_out.txt"), + ?l {ok,6}= + inviso_lfm:merge([{node(), + [{trace_log, + [filename:join(PrivDir,"lfm1_"++atom_to_list(node()))]}]}, + {RNode1, + [{trace_log, + [filename:join(PrivDir,"lfm1_"++atom_to_list(RNode1))]}]}, + {RNode2, + [{trace_log, + [filename:join(PrivDir,"lfm1_"++atom_to_list(RNode2))]}]}], + DestFile), + ?l {ok,FD}=file:open(DestFile,[read]), + ?l S1=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode2),S1), + ?l S2=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode1),S2), + ?l S3=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode1),S3), + ?l S4=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(node()),S4), + ?l S5=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode2),S5), + ?l S6=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(node()),S6), + ?l file:close(FD), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: Testing to the full extent that pid-mappings work with both +%% local and global registration. Also checks that pidmappings can be removed +%% and that consequently the mappings in the resulting merged file stops. +lfm_trace_ti_dist_2(suite) -> []; +lfm_trace_ti_dist_2(doc) -> + [""]; +lfm_trace_ti_dist_2(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + [RNode1,RNode2|_]=RemoteNodes, + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList= + lists:map(fun(N)->{N,[{trace,{file,filename:join(PrivDir,"lfm2_"++atom_to_list(N))}}, + {ti,{file,filename:join(PrivDir,"lfm2_ti_"++atom_to_list(N))}}]} + end, + Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok},{ti_log,ok}]}), + activate_local_tracing(Nodes), + activate_meta_tracing(Nodes), + activate_traceflags(Nodes), + + {inviso_test_proc,RNode2} ! {apply,code,which,[lists]}, + timer:sleep(300), + {inviso_test_proc,RNode1} ! {apply,code,which,[lists]}, + timer:sleep(300), + {inviso_test_proc,RNode1} ! {apply,code,which,[lists]}, + timer:sleep(300), + inviso_test_proc ! {apply,code,which,[lists]}, + timer:sleep(300), + + P2=spawn(RNode2,?MODULE,test_proc_loop,[]), + P1=spawn(RNode1,?MODULE,test_proc_loop,[]), + P0=spawn_link(?MODULE,test_proc_loop,[]), + ThisNode=node(), + ?l {ok,[{ThisNode,{ok,[1]}}]}=inviso:tf([node()],P0,[call,timestamp]), + ?l {ok,[{RNode1,{ok,[1]}}]}=inviso:tf([RNode1],P1,[call,timestamp]), + ?l {ok,[{RNode2,{ok,[1]}}]}=inviso:tf([RNode2],P2,[call,timestamp]), + P2 ! {apply,code,which,[lists]}, + timer:sleep(300), + P1 ! {apply,code,which,[lists]}, + timer:sleep(300), + P0 ! {apply,code,which,[lists]}, + timer:sleep(300), + + P3=spawn(RNode2,?MODULE,test_proc_loop,[]), + ?l yes=global:register_name(inviso_test_proc_globalname,P3), + ?l {ok,[{RNode2,{ok,[1]}}]}=inviso:tf([RNode2],P3,[call,timestamp]), + timer:sleep(300), + P3 ! {apply,code,which,[lists]}, + timer:sleep(300), + + P4=rpc:call(RNode1,erlang,whereis,[inviso_test_proc]), + ?l true=rpc:call(RNode1,erlang,unregister,[inviso_test_proc]), + timer:sleep(300), + P4 ! {apply,code,which,[lists]}, + timer:sleep(300), + + ?l true=rpc:call(RNode1,erlang,register,[inviso_test_proc,P4]), + + ?l global:unregister_name(inviso_test_proc_globalname), + timer:sleep(300), + ?l P3 ! {apply,code,which,[lists]}, + timer:sleep(300), + + deactivate_traceflags(Nodes), + deactivate_local_tracing(Nodes), + stop_tracing(Nodes), + stop(Nodes), + + DestFile=filename:join(PrivDir,"lfm2_out.txt"), + ?l {ok,10}= + inviso_lfm:merge([ + {node(), + [{trace_log, + [filename:join(PrivDir,"lfm2_"++atom_to_list(node()))]}, + {ti_log, + [filename:join(PrivDir,"lfm2_ti_"++atom_to_list(node()))]}]}, + {RNode1, + [{trace_log, + [filename:join(PrivDir,"lfm2_"++atom_to_list(RNode1))]}, + {ti_log, + [filename:join(PrivDir,"lfm2_ti_"++atom_to_list(RNode1))]}]}, + {RNode2, + [{trace_log, + [filename:join(PrivDir,"lfm2_"++atom_to_list(RNode2))]}, + {ti_log, + [filename:join(PrivDir,"lfm2_ti_"++atom_to_list(RNode2))]}]} + ], + DestFile), + ?l {ok,FD}=file:open(DestFile,[read]), + ?l S1=io:get_line(FD,""), +io:format("S1 is:~p~n",[S1]), + ?l true=lists:prefix(atom_to_list(RNode2)++" [inviso_test_proc",S1), + ?l S2=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode1)++" [inviso_test_proc",S2), + ?l S3=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode1)++" [inviso_test_proc",S3), + ?l S4=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(node())++" [inviso_test_proc",S4), + ?l S5=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode2)++" []",S5), + ?l S6=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode1)++" []",S6), + ?l S7=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(node())++" []",S7), + ?l S8=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode2)++" [{global,inviso_test_proc_globalname}]",S8), + ?l S9=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode1)++" []",S9), + ?l S10=io:get_line(FD,""), + ?l true=lists:prefix(atom_to_list(RNode2)++" []",S10), + ?l file:close(FD), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: This tests that the wrapset sorter works. +handle_logfile_sort_wrapset(suite) -> []; +handle_logfile_sort_wrapset(doc) -> + [""]; +handle_logfile_sort_wrapset(Config) when is_list(Config) -> + File0="prefix10.fil", + File1="prefix11.fil", + File2="prefix12.fil", + File3="prefix13.fil", + ?l [File0,File1,File2,File3]= + inviso_lfm_tpfreader:handle_logfile_sort_wrapset([File2,File1,File0,File3]), + File5="prefix15.fil", + ?l [File5,File0,File1,File2,File3]= + inviso_lfm_tpfreader:handle_logfile_sort_wrapset([File2,File5,File1,File0,File3]), + ok. +%% ----------------------------------------------------------------------------- + +%% TEST CASE: This case tests that the regexp mechanism in the inviso_rt_lib can +%% find modules using regexps and that its only_loaded mechanism works. +%% This test case can not be run when using cover because cover will make the +%% modules no longer loaded from the path containing "runtime_tools". +expand_regexp_dist_1(suite) -> []; +expand_regexp_dist_1(doc) -> + [""]; +expand_regexp_dist_1(Config) when is_list(Config) -> + case ?t:is_cover() of + true -> + {skip,"Cover is running"}; + false -> + expand_regexp_dist_1_nocover(Config) + end. + +expand_regexp_dist_1_nocover(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + [RNode1|_]=RemoteNodes, + ?l NodeResults1=inviso_rt_lib:expand_regexp(Nodes,"^inviso_rt.*",[]), + ?l L1=length(Nodes), + ?l L1=length(NodeResults1), + ?l true=lists:all(fun({_,Mods})-> + ?l 3=length(Mods), + ?l true=lists:member(inviso_rt,Mods), + ?l true=lists:member(inviso_rt_lib,Mods), + ?l true=lists:member(inviso_rt_meta,Mods), + true; + (_) -> + false + end, + NodeResults1), + %% Check the dir-option. In the following inviso_tool_lib shall not be found. + ?l NodeResults2=inviso_rt_lib:expand_regexp(Nodes,"runtime_tools","invi.*lib.*",[]), +?l io:format("NodeResults2:~w~n",[NodeResults2]), + ?l L1=length(NodeResults2), % Same number of nodes replying. + ?l true=lists:all(fun({_,Mods})-> + 2=length(Mods), + true=lists:member(inviso_as_lib,Mods), + true=lists:member(inviso_rt_lib,Mods), + true; + (_) -> + false + end, + NodeResults2), + ?l [{RNode1,[]}]= + inviso_rt_lib:expand_regexp([RNode1],"^inviso_testmodule1.*",[only_loaded]), + ?l [{RNode1,[inviso_testmodule1_foo]}]= + inviso_rt_lib:expand_regexp([RNode1],"^inviso_testmodule1.*",[]), + ok. +%% ----------------------------------------------------------------------------- + + +only_loaded_dist_1(suite) -> []; +only_loaded_dist_1(doc) -> + [""]; +only_loaded_dist_1(Config) when is_list(Config) -> + RemoteNodes=get_remotenodes_config(Config), + Nodes=[node()|RemoteNodes], + [RNode1|_]=RemoteNodes, + PrivDir=filename:join(?config(priv_dir,Config),""), + TracerDataList= + lists:map(fun(N)->{N,[{trace,{file,filename:join(PrivDir,"ol_1_"++atom_to_list(N))}}]} + end, + Nodes), + start_and_init_tracing2(Nodes,[],TracerDataList,{ok,[{trace_log,ok}]}), + ?l false=rpc:call(RNode1,erlang,module_loaded,[inviso_testmodule1_foo]), + ?l {ok,[{RNode1,{ok,[0]}}]}= + inviso:tpl([RNode1],inviso_testmodule1_foo,'_','_',[],[only_loaded]), + ?l false=rpc:call(RNode1,erlang,module_loaded,[inviso_testmodule1_foo]), + ?l {ok,[{RNode1,{ok,[3]}}]}= + inviso:tpl([RNode1],inviso_testmodule1_foo,'_','_',[],[]), + stop_tracing(Nodes), + stop(Nodes), + ok. + + +%% ============================================================================== +%% Common functions setting up inviso. +%% ============================================================================== + +%% Starts controlcomponent and adds runtime components on the nodes specified. +%% Also initiates tracing on the nodes. +start_and_init_tracing1(Nodes,Options,TracerData,Reply) when is_list(Nodes) -> + ?l {ok,_Pid}=inviso:start(), % Start a control component. + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,Options), + io:format("~p~n",[NodeResults1]), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + ?l {ok,NodeResults2}=inviso:get_status(Nodes), + ?l true=check_noderesults(Nodes,{ok,{new,running}},NodeResults2), + ?l {ok,NodeResults3}=inviso:init_tracing(Nodes,TracerData), + ?l true=check_noderesults(Nodes,Reply,NodeResults3), + ok. +start_and_init_tracing2(Nodes,Options,TracerDataList,Reply) -> + ?l {ok,_Pid}=inviso:start(), % Start a control component. + ?l {ok,NodeResults1}=inviso:add_nodes(Nodes,a_ref,Options), + io:format("~p~n",[NodeResults1]), + ?l true=check_noderesults(Nodes,{ok,new},NodeResults1), + ?l {ok,NodeResults2}=inviso:get_status(Nodes), + ?l true=check_noderesults(Nodes,{ok,{new,running}},NodeResults2), + ?l {ok,NodeResults4}=inviso:get_tracerdata(Nodes), + ?l true=check_noderesults(Nodes,{ok,no_tracerdata},NodeResults4), + ?l {ok,NodeResults3}=inviso:init_tracing(TracerDataList), + io:format("Tracerdatalist:~p~n",[TracerDataList]), + ?l true=check_noderesults(Nodes,Reply,NodeResults3), + + ?l Fun1=fun({N,{ok,TD}}) when is_list(TD)-> + ?l {value,{trace,Trace}}=lists:keysearch(trace,1,TD), + ?l {value,{N,TD2}}=lists:keysearch(N,1,TracerDataList), + ?l true=lists:member({trace,Trace},TD2), + %% Check that the trace file really exists. + ?l case Trace of % Trace={file,FilePortParameters} + {file,FileName1} when is_list(FileName1) -> + ?l {ok,_}=rpc:call(N,file,read_file_info,[FileName1]); + _ -> % This should be extended with more cases. + true + end, + ?l case lists:keysearch(ti,1,TD2) of + {value,{_,Ti}} -> % Ok, we have ti too. + ?l {value,{_,Ti}}=lists:keysearch(ti,1,TD), + ?l FileName2=element(2,Ti), + ?l {ok,_}=rpc:call(N,file,read_file_info,[FileName2]), + true; + false -> % No ti, we are done now. + true + end; + ({N,{ok,{file,FileName}}}) -> + ?l {value,{N,{file,FileName}}}=lists:keysearch(N,1,TracerDataList), + ?l {ok,_}=rpc:call(N,file,read_file_info,[FileName]), + true; + ({N,{ok,LogTD}}) -> % The case using a fun. + ?l {value,{N,LogTD}}=lists:keysearch(N,1,TracerDataList), + true + end, + ?l {ok,NodeResults5}=inviso:get_tracerdata(Nodes), + ?l true=check_noderesults(Nodes,Fun1,NodeResults5), + ok. +%% ------------------------------------------------------------------------------ + +%% Stops tracing on Nodes. +stop_tracing(Nodes) when is_list(Nodes) -> + ?l {ok,NodeResults1}=inviso:stop_tracing(Nodes), + ?l true=check_noderesults(Nodes,{ok,idle},NodeResults1), + ?l {ok,NodeResults2}=inviso:get_status(Nodes), + ?l true=check_noderesults(Nodes,{ok,{idle,running}},NodeResults2), + %% The implementation says that the meta tracer shall be stopped when + %% tracing is stopped. Check that. + ?l lists:foreach(fun(N)-> + ok=poll(erlang,whereis,[inviso_rt_meta],undefined,20) + end, + Nodes). +%% ------------------------------------------------------------------------------ + +%% Stops the runtime components on Nodes and stops the control component at this +%% Erlang node. +stop(Nodes) when is_list(Nodes) -> + ?l true=check_on_nodes(Nodes,erlang,whereis,[inviso_rt],fun(P) when is_pid(P)->true end), + ?l {ok,NodeResults}=inviso:stop_nodes(Nodes), + ?l true=check_noderesults(Nodes,ok,NodeResults), + ?l true=check_on_nodes(Nodes,erlang,whereis,[inviso_rt],fun(undefined)->true end), + ?l true=is_pid(whereis(inviso_c)), + ?l shutdown=inviso:stop(), + ?l ok=poll(erlang,whereis,[inviso_c],undefined,20). +%% ------------------------------------------------------------------------------ + +%% Help function activating local tracing. +activate_local_tracing(Nodes) when is_list(Nodes) -> + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{code,which,1},traced], + {traced,false}), + ?l {ok,NodeResults}=inviso:tpl(Nodes,code,which,1,[]), + ?l true=check_noderesults(Nodes,fun({_,{ok,[1]}})->true end,NodeResults), + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{code,which,1},traced], + {traced,local}). +%% ------------------------------------------------------------------------------ + +%% Help function activating global tracing. +activate_global_tracing(Nodes) when is_list(Nodes) -> + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{code,get_path,0},traced], + {traced,false}), + ?l {ok,NodeResults}=inviso:tp(Nodes,code,get_path,0,[]), + ?l true=check_noderesults(Nodes,fun({_,{ok,[1]}})->true end,NodeResults), + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{code,get_path,0},traced], + {traced,global}). +%% ------------------------------------------------------------------------------ + + +%% Help function activating local tracing and using a regexp to point out modules. +%% Returns the structure of modules and functions that were activated. Must be used +%% when deactivating. +activate_global_tracing_regexp(Nodes) when is_list(Nodes) -> + %% First find out which modules will be effected. + ?l Mods1=inviso_rt_lib:expand_regexp("application.*",[]), + ?l true=(length(Mods1)>1), % Should find more than one module! + ?l Funcs1=lists:foldl(fun(M,Acc)->[{M,M:module_info(exports)}|Acc] end,[],Mods1), + %% Check that these functions are not traced. + io:format("Modules:~w~n",[Mods1]), + ?l {ok,NodeResults}=inviso:tp(Nodes,"application.*",'_','_',[],[]), + io:format("Here 2~w~n",[NodeResults]), + ?l N=lists:foldl(fun({_,L1},A1)->lists:foldl(fun(_,A2)->A2+1 end,A1,L1) end,0,Funcs1), + ?l true=check_noderesults(Nodes,fun({_,{ok,L}})-> N==lists:sum(L) end,NodeResults), + io:format("Here 3~n",[]), + %% Check again! + ?l lists:foreach(fun({M,Funcs})-> + lists:foreach(fun({F,Arity})-> + true=check_on_nodes(Nodes, + erlang, + trace_info, + [{M,F,Arity},traced], + {traced,global}) + end, + Funcs) + end, + Funcs1), + Funcs1. +%% ------------------------------------------------------------------------------ + +%% Help function as above but uses the dir feature as well. +activate_global_tracing_regexp_dir(Nodes) when is_list(Nodes) -> + %% First find out which modules will be effected. + ?l Mods1=inviso_rt_lib:expand_regexp(".*kernel.*","application.*",[]), + ?l true=(length(Mods1)>1), % Should find more than one module! + ?l Funcs1=lists:foldl(fun(M,Acc)->[{M,M:module_info(exports)}|Acc] end,[],Mods1), + %% Check that these functions are not traced. + io:format("Modules:~w~n",[Mods1]), + ?l {ok,NodeResults}=inviso:tp(Nodes,{".*kernel.*","application.*"},'_','_',[],[]), + io:format("Here 2~w~n",[NodeResults]), + ?l N=lists:foldl(fun({_,L1},A1)->lists:foldl(fun(_,A2)->A2+1 end,A1,L1) end,0,Funcs1), + ?l true=check_noderesults(Nodes,fun({_,{ok,L}})-> N==lists:sum(L) end,NodeResults), + io:format("Here 3~n",[]), + %% Check again! + ?l lists:foreach(fun({M,Funcs})-> + lists:foreach(fun({F,Arity})-> + true=check_on_nodes(Nodes, + erlang, + trace_info, + [{M,F,Arity},traced], + {traced,global}) + end, + Funcs) + end, + Funcs1), + Funcs1. +%% ------------------------------------------------------------------------------ + +deactivate_local_tracing(Nodes) when is_list(Nodes) -> + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{code,which,1},traced], + {traced,local}), + ?l {ok,NodeResults}=inviso:ctpl(Nodes,code,'_','_'), + ?l true=check_noderesults(Nodes,fun({_,{ok,[N]}})when is_integer(N)->true end,NodeResults), + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{code,which,1},traced], + {traced,false}). +%% ------------------------------------------------------------------------------ + +deactivate_global_tracing(Nodes) when is_list(Nodes) -> + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{code,get_path,0},traced], + {traced,global}), + ?l {ok,NodeResults}=inviso:ctp(Nodes,code,'_','_'), + ?l true=check_noderesults(Nodes,fun({_,{ok,[N]}})when is_integer(N)->true end,NodeResults), + ?l true=check_on_nodes(Nodes, + erlang, + trace_info, + [{code,get_path,0},traced], + {traced,false}). +%% ------------------------------------------------------------------------------ + + +%% Function deactivating the functions activated by activate_global_tracing_regexp/1. +deactivate_global_tracing_regexp(Nodes,Funcs1) -> + ?l lists:foreach(fun({M,Funcs})-> + lists:foreach(fun({F,Arity})-> + true=check_on_nodes(Nodes, + erlang, + trace_info, + [{M,F,Arity},traced], + {traced,global}) + end, + Funcs) + end, + Funcs1), + ?l {ok,NodeResults}=inviso:ctp(Nodes,"application.*",'_','_'), + ?l N=lists:foldl(fun({_,L1},A1)->lists:foldl(fun(_,A2)->A2+1 end,A1,L1) end,0,Funcs1), + io:format("Noderesult from deactivate;~w~n",[NodeResults]), + ?l true=check_noderesults(Nodes,fun({_,{ok,L}})-> N==lists:sum(L) end,NodeResults), + ?l lists:foreach(fun({M,Funcs})-> + lists:foreach(fun({F,Arity})-> + true=check_on_nodes(Nodes, + erlang, + trace_info, + [{M,F,Arity},traced], + {traced,false}) + end, + Funcs) + end, + Funcs1). +%% ------------------------------------------------------------------------------ + +%% Function deactivating the functions activated by activate_global_tracing_regexp_dir/1. +deactivate_global_tracing_regexp_dir(Nodes,Funcs1) -> + ?l lists:foreach(fun({M,Funcs})-> + lists:foreach(fun({F,Arity})-> + true=check_on_nodes(Nodes, + erlang, + trace_info, + [{M,F,Arity},traced], + {traced,global}) + end, + Funcs) + end, + Funcs1), + ?l {ok,NodeResults}=inviso:ctp(Nodes,{".*kernel.*","application.*"},'_','_'), + ?l N=lists:foldl(fun({_,L1},A1)->lists:foldl(fun(_,A2)->A2+1 end,A1,L1) end,0,Funcs1), + io:format("Noderesult from deactivate;~w~n",[NodeResults]), + ?l true=check_noderesults(Nodes,fun({_,{ok,L}})-> N==lists:sum(L) end,NodeResults), + ?l lists:foreach(fun({M,Funcs})-> + lists:foreach(fun({F,Arity})-> + true=check_on_nodes(Nodes, + erlang, + trace_info, + [{M,F,Arity},traced], + {traced,false}) + end, + Funcs) + end, + Funcs1). +%% ------------------------------------------------------------------------------ + +%% Help function which starts the inviso_test_proc on all nodes and then sets +%% the call flag on that process. +activate_traceflags(Nodes) -> + ?l lists:foreach(fun(N)->spawn(N,?MODULE,test_proc_init,[]) end,Nodes), + ?l lists:foreach(fun(N)-> + P=rpc:call(N,erlang,whereis,[inviso_test_proc]), + {flags,[]}=rpc:call(N,erlang,trace_info,[P,flags]) + end, + Nodes), + ?l {ok,NodeResults}=inviso:tf(Nodes,inviso_test_proc,[call,timestamp]), + ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults), + ?l lists:foreach(fun(N)-> + P=rpc:call(N,erlang,whereis,[inviso_test_proc]), + {flags,Flags}=rpc:call(N,erlang,trace_info,[P,flags]), + true=lists:member(call,Flags), + true=lists:member(timestamp,Flags) + end, + Nodes), + %% Now try a globally registered process. + ?l [ANode|_]=Nodes, + ?l GPid=spawn(ANode,?MODULE,global_test_proc_init,[]), + ?l ok=poll(global,whereis_name,[global_inviso_test_proc], + fun(P) when is_pid(P)->true;(_)->false end, + 10), + ?l {ok,NodeResults2}= + inviso:tf(Nodes,{global,global_inviso_test_proc},[call,timestamp]), + ?l true=check_noderesults(Nodes, + fun({N,{ok,[1]}}) when N==ANode->true; + ({_,{ok,[0]}})->true; + (_)->false + end, + NodeResults2), + ?l {flags,Flags2}=rpc:call(ANode,erlang,trace_info,[GPid,flags]), + ?l 2=length(Flags2), + ?l true=lists:member(call,Flags2), + ?l true=lists:member(timestamp,Flags2), + true. +%% ------------------------------------------------------------------------------ + +deactivate_traceflags(Nodes) -> + ?l lists:foreach(fun(N)-> + P=rpc:call(N,erlang,whereis,[inviso_test_proc]), + {flags,Flags}=rpc:call(N,erlang,trace_info,[P,flags]), + true=lists:member(call,Flags), + true=lists:member(timestamp,Flags) + end, + Nodes), + ?l {ok,NodeResults}=inviso:ctf(Nodes,inviso_test_proc,[call,timestamp]), + ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults), + ?l lists:foreach(fun(N)-> + P=rpc:call(N,erlang,whereis,[inviso_test_proc]), + {flags,[]}=rpc:call(N,erlang,trace_info,[P,flags]) + end, + Nodes), + ?l GPid=global:whereis_name(global_inviso_test_proc), + ?l ANode=node(GPid), + ?l {flags,Flags2}=rpc:call(ANode,erlang,trace_info,[GPid,flags]), + ?l 2=length(Flags2), + ?l {ok,NodeResults2}=inviso:ctf(Nodes,{global,global_inviso_test_proc},[call,timestamp]), + ?l true=check_noderesults(Nodes, + fun({N,{ok,[1]}}) when N==ANode->true; + ({_,{ok,[0]}})->true; + (_)->false + end, + NodeResults2). +%% ------------------------------------------------------------------------------ + + +activate_meta_tracing(Nodes) -> + ?l {ok,NodeResults1}=inviso:tpm_localnames(), + ?l true=check_noderesults(Nodes,{{ok,1},{ok,1}},NodeResults1), + ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]), + {meta,P}=rpc:call(N,erlang,trace_info,[{erlang,register,2},meta]) + end, + Nodes), + ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]), + {meta,P}=rpc:call(N,erlang,trace_info,[{erlang,unregister,1},meta]) + end, + Nodes), + ?l {ok,NodeResults2}=inviso:tpm_globalnames(), + ?l true=check_noderesults(Nodes,{{ok,1},{ok,1}},NodeResults2), + ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]), + {meta,P}=rpc:call(N, + erlang, + trace_info, + [{global,handle_call,3},meta]) + end, + Nodes), + ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]), + {meta,P}=rpc:call(N, + erlang, + trace_info, + [{global,delete_global_name,2},meta]) + end, + Nodes), + + ?l lists:foreach(fun(N)->true=rpc:call(N, + ets, + insert, + [inviso_sideeffect_tab,{tpm_init_func1,0}]), + true=rpc:call(N, + ets, + insert, + [inviso_sideeffect_tab,{tpm_call_func1,0}]), + true=rpc:call(N, + ets, + insert, + [inviso_sideeffect_tab,{tpm_return_func1,0}]) + end, + Nodes), + ?l {ok,NodeResults3}= + inviso:init_tpm(lists, + module_info, + 0, + {?MODULE,tpm_init_func1}, + {?MODULE,tpm_call_func1}, + {?MODULE,tpm_return_func1}, + {?MODULE,tpm_remove_func1}), + ?l true=check_noderesults(Nodes,ok,NodeResults3), + ?l [{_,1}]=ets:lookup(inviso_sideeffect_tab,tpm_init_func1), + ?l {ok,NodeResults3a}= + inviso:init_tpm(lists, + module_info, + 0, + {?MODULE,tpm_init_func1}, + {?MODULE,tpm_call_func1}, + {?MODULE,tpm_return_func1}, + {?MODULE,tpm_remove_func1}), + ?l true=check_noderesults(Nodes,{error,already_initiated},NodeResults3a), +% %% Try more forbidden things. Wildcards not allowed in meta tracing! +% ?l {ok,NodeResults3b}=inviso:tpm(Nodes,lists,'_',0,[{'_',[],[{return_trace}]}]), +% io:format("The noderesults3b is:~w~n",[NodeResults3b]), +% ?l true=check_noderesults(Nodes,{error,bad_mfa},NodeResults3b), + ?l {ok,NodeResults3c}=inviso:tpm(Nodes,lists,module_info,0,[{'_',[],[{return_trace}]}]), + ?l true=check_noderesults(Nodes,{ok,1},NodeResults3c), + ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]), + {meta,P}=rpc:call(N,erlang,trace_info,[{lists,module_info,0},meta]) + end, + Nodes), + ?l lists:foreach(fun(N)->rpc:call(N,lists,module_info,[]) end,Nodes), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_call_func1],[{tpm_call_func1,1}],20), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_return_func1],[{tpm_return_func1,1}],20), + ?l lists:foreach(fun(N)->rpc:call(N,lists,module_info,[]) end,Nodes), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_call_func1],[{tpm_call_func1,2}],20), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_return_func1],[{tpm_return_func1,2}],20), + + ?l {ok,NodeResults4}= + inviso:init_tpm(math, + module_info, + 1, + {?MODULE,tpm_init_func2}, % Does not exist on purpose. + {?MODULE,tpm_call_func2}, % Does not exist on purpose. + {?MODULE,tpm_return_func2}, % Does not exist on purpose. + {?MODULE,tpm_remove_func2}), % Does not exist on purpose. + ?l true=check_noderesults(Nodes,ok,NodeResults4), + ?l {ok,NodeResults5}= + inviso:tpm_ms(math,module_info,1,ms1,[{'_',[],[{return_trace}]}]), + ?l true=check_noderesults(Nodes,{ok,1},NodeResults5), + ?l lists:foreach(fun(N)->{meta_match_spec,[{'_',[],[{return_trace}]}]}= + rpc:call(N,erlang,trace_info,[{math,module_info,1}, + meta_match_spec]) + end, + Nodes), + + ?l {ok,NodeResults6}=inviso:tpm_ms(math,module_info,1,ms2,[{[exports],[],[]}]), + ?l true=check_noderesults(Nodes,{ok,1},NodeResults6), + ?l lists:foreach(fun(N)->{meta_match_spec,[{[exports],[],[]},{'_',[],[{return_trace}]}]}= + rpc:call(N,erlang,trace_info,[{math,module_info,1}, + meta_match_spec]) + end, + Nodes), + ?l {ok,NodeResults7}=inviso:tpm_ms(math,module_info,1,ms3,[{[attributes],[],[]}]), + ?l true=check_noderesults(Nodes,{ok,1},NodeResults7), + ?l lists:foreach(fun(N)->{meta_match_spec,[{[attributes],[],[]}, + {[exports],[],[]}, + {'_',[],[{return_trace}]}]}= + rpc:call(N,erlang,trace_info,[{math,module_info,1}, + meta_match_spec]) + end, + Nodes), + ?l {ok,NodeResults8}=inviso:ctpm_ms(math,module_info,1,ms2), + ?l true=check_noderesults(Nodes,ok,NodeResults8), + ?l lists:foreach(fun(N)->{meta_match_spec,[{[attributes],[],[]}, + {'_',[],[{return_trace}]}]}= + rpc:call(N,erlang,trace_info,[{math,module_info,1}, + meta_match_spec]) + end, + Nodes), + ?l io:format("whereis:~w~n",[lists:map(fun(N)->rpc:call(N,erlang,whereis,[inviso_rt_meta]) end,Nodes)]), + ?l {ok,NodeResults8}=inviso:ctpm_ms(math,module_info,1,ms3), + ?l io:format("whereis:~w~n",[lists:map(fun(N)->rpc:call(N,erlang,whereis,[inviso_rt_meta]) end,Nodes)]), + ?l {ok,NodeResults8}=inviso:ctpm_ms(math,module_info,1,ms1), + ?l lists:foreach(fun(N)->{meta_match_spec,false}= + rpc:call(N,erlang,trace_info,[{math,module_info,1}, + meta_match_spec]) + end, + Nodes), + + %% Now try to do this with exception tracing instead. + %% Reset the side effect tables. + ?l lists:foreach(fun(N)->true=rpc:call(N, + ets, + insert, + [inviso_sideeffect_tab,{tpm_init_func1,0}]), + true=rpc:call(N, + ets, + insert, + [inviso_sideeffect_tab,{tpm_call_func1,0}]), + true=rpc:call(N, + ets, + insert, + [inviso_sideeffect_tab,{tpm_return_func1,0}]) + end, + Nodes), + ?l {ok,NodeResults9}= + inviso:init_tpm(?MODULE, + failing_function, + 1, + {?MODULE,tpm_init_func1}, + {?MODULE,tpm_call_func1}, + {?MODULE,tpm_return_func1}, + {?MODULE,tpm_remove_func1}), + ?l true=check_noderesults(Nodes,ok,NodeResults9), + ?l [{_,1}]=ets:lookup(inviso_sideeffect_tab,tpm_init_func1), + ?l {ok,NodeResults10}=inviso:tpm(Nodes,?MODULE,failing_function,1,[{'_',[],[{exception_trace}]}]), + ?l true=check_noderesults(Nodes,{ok,1},NodeResults10), + ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]), + {meta,P}=rpc:call(N,erlang,trace_info,[{?MODULE,failing_function,1},meta]) + end, + Nodes), + ?l lists:foreach(fun(N)->rpc:call(N,?MODULE,failing_function,[nofailure]) end,Nodes), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_call_func1],[{tpm_call_func1,1}],20), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_return_func1],[{tpm_return_func1,1}],20), + ?l lists:foreach(fun(N)->rpc:call(N,?MODULE,failing_function,[failure]) end,Nodes), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_call_func1],[{tpm_call_func1,2}],20), + ?l ok=poll(ets,lookup,[inviso_sideeffect_tab,tpm_return_func1],[{tpm_return_func1,3}],20), + + ok. +%% ------------------------------------------------------------------------------ + +%% This function is for testing that appending the tracer to a trace action term +%% works. +activate_deactivate_meta_tracing_tracer(Nodes) -> + ?l {ok,NodeResults}= + inviso:tpm_tracer(Nodes,lists,module_info,0,[{'_',[],[{trace,[all],[call]}]}],void), + ?l true=check_noderesults(Nodes,{ok,1},NodeResults), + ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]), + {meta,P}=rpc:call(N,erlang,trace_info,[{lists,module_info,0},meta]), + {meta_match_spec,[{'_',[],[{trace,[all],Enable}]}]}= + rpc:call(N,erlang,trace_info,[{lists,module_info,0}, + meta_match_spec]), + true=list_search(Enable,fun({{tracer,P}}) when is_port(P)->true; + (_) -> false + end) + end, + Nodes), + ?l {ok,NodeResults2}= + inviso:ctpm(Nodes,lists,module_info,0), + ?l true=check_noderesults(Nodes,ok,NodeResults2), + ?l lists:foreach(fun(N)->{meta,false}= + rpc:call(N,erlang,trace_info,[{lists,module_info,0},meta]) + end, + Nodes), + ok. +%% ------------------------------------------------------------------------------ + +deactivate_meta_tracing(Nodes) -> + ?l lists:foreach(fun(N)->{meta,P}= + rpc:call(N,erlang,trace_info,[{erlang,register,2},meta]), + true=is_pid(P) + end, + Nodes), + ?l lists:foreach(fun(N)->{meta,P}= + rpc:call(N,erlang,trace_info,[{erlang,unregister,1},meta]), + true=is_pid(P) + end, + Nodes), + ?l {ok,NodeResults1}=inviso:ctpm_localnames(), + ?l lists:foreach(fun(N)->{meta,false}= + rpc:call(N,erlang,trace_info,[{erlang,register,2},meta]) end, + Nodes), + ?l lists:foreach(fun(N)->{meta,false}= + rpc:call(N,erlang,trace_info,[{erlang,unregister,1},meta]) + end, + Nodes), + ?l true=check_noderesults(Nodes,{ok,ok},NodeResults1), + + ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]), + {meta,P}=rpc:call(N, + erlang, + trace_info, + [{global,handle_call,3},meta]) + end, + Nodes), + ?l lists:foreach(fun(N)->P=rpc:call(N,erlang,whereis,[inviso_rt_meta]), + {meta,P}=rpc:call(N, + erlang, + trace_info, + [{global,delete_global_name,2},meta]) + end, + Nodes), + ?l {ok,NodeResults1b}=inviso:ctpm_globalnames(), + ?l true=check_noderesults(Nodes,{ok,ok},NodeResults1b), + ?l lists:foreach(fun(N)-> + {meta,false}=rpc:call(N, + erlang, + trace_info, + [{global,handle_call,3},meta]) + end, + Nodes), + ?l lists:foreach(fun(N)-> + {meta,false}=rpc:call(N, + erlang, + trace_info, + [{global,delete_global_name,2},meta]) + end, + Nodes), + + ?l lists:foreach(fun(N)->{meta,P}= + rpc:call(N,erlang,trace_info,[{lists,module_info,0},meta]), + true=is_pid(P) + end, + Nodes), + ?l {ok,NodeResults2}=inviso:ctpm(lists,module_info,0), + ?l true=check_noderesults(Nodes,ok,NodeResults2), + ?l lists:foreach(fun(N)->{meta,false}= + rpc:call(N,erlang,trace_info,[{lists,module_info,0},meta]) end, + Nodes), + ?l [{_,0}]=ets:lookup(inviso_sideeffect_tab,tpm_init_func1), + ?l {ok,NodeResults3}=inviso:ctpm(math,module_info,1), + ?l true=check_noderesults(Nodes,ok,NodeResults3), + ok. +%% ------------------------------------------------------------------------------ + +%% Functions acting as callbacks for testing the meta tracing mechanisms. +tpm_init_func1(_M,_F,_Arity,PublLD) -> + ets:update_counter(inviso_sideeffect_tab,tpm_init_func1,1), + {ok,PublLD,void}. +tpm_call_func1(_Pid,{call,_Args,_TS},PublLD) -> + ets:update_counter(inviso_sideeffect_tab,tpm_call_func1,1), + {ok,PublLD,void}. +tpm_return_func1(_Pid,{return_from,_ReturnVal,_TS},PublLD) -> + ets:update_counter(inviso_sideeffect_tab,tpm_return_func1,1), + {ok,PublLD,void}; +tpm_return_func1(_Pid,{exception_from,_ReturnVal,_TS},PublLD) -> + ets:update_counter(inviso_sideeffect_tab,tpm_return_func1,1), + ets:update_counter(inviso_sideeffect_tab,tpm_return_func1,1), + {ok,PublLD,void}. +tpm_remove_func1(_M,_F,_Arity,PublLD) -> + ets:update_counter(inviso_sideeffect_tab,tpm_init_func1,-1), + {ok,PublLD}. +%% ------------------------------------------------------------------------------ + + +%% Help function which traces on a function and makes function calls until there +%% are two files in the wrap-set. +fill_and_reach_two_wrapfiles(PrivDir,RegExp,Nodes) -> + ?l lists:foreach(fun(N)->spawn(N,?MODULE,test_proc_init,[]) end,Nodes), + ?l {ok,NodeResults1}=inviso:tpl(Nodes,?MODULE,test_function,0,[]), + ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults1), + ?l {ok,NodeResults2}=inviso:tf(Nodes,inviso_test_proc,[call]), + ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults2), + fill_and_reach_two_wrapfiles_2(PrivDir,RegExp,Nodes), + ?l {ok,NodeResults3}=inviso:ctf(Nodes,inviso_test_proc,[call]), + ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults3), + ?l {ok,NodeResults4}=inviso:ctpl(Nodes,?MODULE,test_function,0), + ?l true=check_noderesults(Nodes,{ok,[1]},NodeResults4), + ok. + +fill_and_reach_two_wrapfiles_2(PrivDir,RegExp,[Node|Rest]) -> + ?l ok=rpc:call(Node,?MODULE,fill_and_reach_two_wrapfiles_3,[PrivDir,RegExp]), + fill_and_reach_two_wrapfiles_2(PrivDir,RegExp,Rest); +fill_and_reach_two_wrapfiles_2(_,_,[]) -> + ok. + +fill_and_reach_two_wrapfiles_3(Dir,RegExp) -> + ok=send_to_test_proc({apply,?MODULE,test_function,[]}, + fun reach_two_wraps_stopfun/1, + {Dir,RegExp++atom_to_list(node())}, + 100). + +%% Help function intended to be used as fun in a send_to_test_proc/4 call. +%% The function lists the content of Dir and looks for occurancies of String. +%% If two files containing the string String are found, 'done' is returned. +%% Otherwise 'continue'. +reach_two_wraps_stopfun({Dir,RegExp}) -> + case file:list_dir(Dir) of + {ok,FileNames} -> + case how_many_files_regexp(FileNames,RegExp,0) of + {ok,2} -> + done; + _ -> + continue + end; + {error,_Reason} -> + error + end. +%% ------------------------------------------------------------------------------ + +%% ------------------------------------------------------------------------------ +%% Help function for the overload tests. These functions are used as callbacks. +%% ------------------------------------------------------------------------------ + +overload1(_) -> + ets:update_counter(inviso_sideeffect_tab,ovl1,1), + ok. +%% This function is used when timeout occurs inside the runtime component. +%% That is it is time to check for overload. +overload2({timeout,overload2i_data}) -> + ets:update_counter(inviso_sideeffect_tab,ovl2,1), + ok. +overload2i() -> + ets:insert(inviso_sideeffect_tab,{ovl2,0}), + {ok,overload2i_data}. +overload2r(overload2i_data) -> + ets:delete(inviso_sideeffect_tab,ovl2). + +%% This function is used when timeout occurs inside the runtime component. +%% That is it is time to check for overload. +overload3({timeout,overload3i_data}) -> + ets:update_counter(inviso_sideeffect_tab,ovl3,1), + ok; +overload3(_) -> % Must handle garbage too. + ignore. +overload3i() -> + ets:insert(inviso_sideeffect_tab,{ovl3,0}), + {ok,overload3i_data}. +overload3r(overload3i_data) -> + ets:insert(inviso_sideeffect_tab,{ovl3r,done}), + ets:delete(inviso_sideeffect_tab,ovl3). + +overload4(_) -> + case ets:lookup(inviso_sideeffect_tab,ovl4_suspend) of + [] -> % We are supposed to be running. + ets:update_counter(inviso_sideeffect_tab,ovl4,1), + ok; + [_] -> + {suspend,test} + end. + +%% This function is used when overload check is done by icomming message. +overload5({msg,{test_of_loadcheck,overload5i_data}}) -> + ets:update_counter(inviso_sideeffect_tab,ovl5,1), + ok; +overload5(_) -> + ignore. +overload5i() -> + ets:insert(inviso_sideeffect_tab,{ovl5,0}), + {ok,overload5i_data}. +overload5r(overload5i_data) -> + ets:delete(inviso_sideeffect_tab,ovl5), + ets:insert(inviso_sideeffect_tab,{ovl5r,done}); +overload5r(X) -> + erlang:display({'***',overload5r,X}). + +overload6(_) -> + ets:update_counter(inviso_sideeffect_tab,ovl6,1), + ok. +%% ------------------------------------------------------------------------------ + +%% ------------------------------------------------------------------------------ +%% Help function for the subscription tests. These function implements a collector +%% process which will subscribe to inviso_events from the control component. +%% ------------------------------------------------------------------------------ + +%% Function which can be used to check if an inviso_event has arrived. The function +%% takes a fun which tests the messages. +check_msg_collector([],_,_) -> + true; +check_msg_collector(_,_,0) -> + false; +check_msg_collector(Nodes,Fun,T) -> + Ref=make_ref(), + inviso_collector_proc ! {fetch_message,self(),Ref,Fun}, + receive + {inviso,Ref,{true,Node}} -> + check_msg_collector(lists:delete(Node,Nodes),Fun,T-1); + {inviso,Ref,false} -> + timer:sleep(100), + check_msg_collector(Nodes,Fun,T-1) + end. + +%% Spawn on this function to get a subscriber. +inviso_msg_collector() -> + register(inviso_collector_proc,self()), + inviso_msg_collector_loop([]). + +inviso_msg_collector_loop(Msgs) -> + receive + {fetch_message,From,Ref,Fun} -> + {NewMsgs,Reply}=inviso_msg_collector_selector(Msgs,Fun,[]), + From ! {inviso,Ref,Reply}, + inviso_msg_collector_loop(NewMsgs); + Msg -> + inviso_msg_collector_loop([Msg|Msgs]) + end. + +inviso_msg_collector_selector([M|Rest],Fun,Accum) -> + case Fun(M) of + {true,X} -> + {Rest++Accum,{true,X}}; + _ -> + inviso_msg_collector_selector(Rest,Fun,[M|Accum]) + end; +inviso_msg_collector_selector([],_,Accum) -> + {Accum,false}. +%% ------------------------------------------------------------------------------ + + +%% ============================================================================== +%% Help functions +%% ============================================================================== + +list_search([E|Rest],Fun) -> + case Fun(E) of + true -> + true; + false -> + list_search(Rest,Fun) + end; +list_search([],_Fun) -> + false. +%% ------------------------------------------------------------------------------ + +%% Help function checking that there is a Result for each node in Nodes. +%% Returns 'true' if successful. +check_noderesults(Nodes,Fun,[{Node,Result}|Rest]) when is_function(Fun) -> + case Fun({Node,Result}) of + true -> + case lists:member(Node,Nodes) of + true -> + check_noderesults(lists:delete(Node,Nodes),Fun,Rest); + false -> % Not good. + unknown_node_in_returnvalue + end; + _ -> + illegal_result + end; +check_noderesults(Nodes,Result,[{Node,Result}|Rest]) -> + case lists:member(Node,Nodes) of + true -> + check_noderesults(lists:delete(Node,Nodes),Result,Rest); + false -> % Not good. + unknown_node_in_returnvalue + end; +check_noderesults([],_,[]) -> + true; +check_noderesults(X,Y,Z) -> + io:format("Bad arguments to check noderesults:~w~n~w~n~w~n",[X,Y,Z]), + false. +%% ------------------------------------------------------------------------------ + +%% Help function doing rpc on all nodes in Nodes calling M:F. Returns 'true' if +%% successful. +check_on_nodes([Node|Rest],M,F,Args,Result) when Node==node() -> + if + is_function(Result) -> + ?l true=Result(apply(M,F,Args)); + true -> + ?l Result=apply(M,F,Args) + end, + check_on_nodes(Rest,M,F,Args,Result); +check_on_nodes([Node|Rest],M,F,Args,Result) -> + if + is_function(Result) -> + ?l true=Result(rpc:call(Node,M,F,Args)); + true -> + ?l Result=rpc:call(Node,M,F,Args) + end, + check_on_nodes(Rest,M,F,Args,Result); +check_on_nodes([],_,_,_,_) -> + true. +%% ------------------------------------------------------------------------------ + +%% Help function which given a list of files searches through it and returns +%% how many satisfies the RegExp. +%% Returns {ok,N}. +how_many_files_regexp([],_,N) -> + {ok,N}; +how_many_files_regexp([FName|Rest],RegExp,N) -> + case regexp:first_match(FName,RegExp) of + {match,1,_} -> + how_many_files_regexp(Rest,RegExp,N+1); + nomatch -> + how_many_files_regexp(Rest,RegExp,N); + {error,Reason} -> + test_server:fail(Reason) + end. +%% ------------------------------------------------------------------------------ + +%% Help function killing a bunch of registered processes. +process_killer([RegName|Rest]) -> + case whereis(RegName) of + undefined -> + case global:whereis_name(RegName) of + undefined -> + process_killer(Rest); + P when is_pid(P) -> + if + node()==node(P) -> + exit(P,kill); + true -> + true + end, + process_killer(Rest) + end; + P when is_pid(P) -> + exit(P,kill), + process_killer(Rest) + end; +process_killer([]) -> + true. +%% ------------------------------------------------------------------------------ + +%% Help function which waits for a function call to become Result. This is useful +%% if what we are waiting for can happend independantly of indications we have +%% access to. +poll(_,_,_,_,0) -> + error; +poll(M,F,Args,Result,Times) -> + try apply(M,F,Args) of + What when is_function(Result) -> + case Result(What) of + true -> + ok; + _ -> + timer:sleep(100), + poll(M,F,Args,Result,Times-1) + end; + Result -> + ok; + _ -> + timer:sleep(100), + poll(M,F,Args,Result,Times-1) + catch + error:Reason -> + io:format("Apply in suite-function poll/5 failed, ~w~n",[Reason]), + timer:sleep(100), + poll(M,F,Args,Result,Times-1) + end. +%% ------------------------------------------------------------------------------ + +insert_remotenode_config(Name,Node,Config) -> + [{remotenode,{Name,Node}}|Config]. +%% ------------------------------------------------------------------------------ + +insert_timetraphandle_config(Handle,Config) -> + [{timetraphandle,Handle}|Config]. +%% ------------------------------------------------------------------------------ + +get_remotenode_config(Name, [{remotenode, {Name, Node}}| _Cs]) -> + Node; +get_remotenode_config(Name, [_ | Cs]) -> + get_remotenode_config(Name, Cs); +get_remotenode_config(Name, []) -> + exit({no_remotenode, Name}). + +%% ------------------------------------------------------------------------------ + +get_timetraphandle_config(Config) -> + {value,{_,Handle}}=lists:keysearch(timetraphandle,1,Config), + Handle. +%% ------------------------------------------------------------------------------ + +get_remotenodes_config([{remotenode,{_Name,Node}}|Config]) -> + [Node|get_remotenodes_config(Config)]; +get_remotenodes_config([_|Config]) -> + get_remotenodes_config(Config); +get_remotenodes_config([]) -> + []. +%% ------------------------------------------------------------------------------ + +remove_remotenode_config(Name, [{remotenode, {Name, _}} | Cs]) -> + Cs; +remove_remotenode_config(Name, [C | Cs]) -> + [C | remove_remotenode_config(Name, Cs)]; +remove_remotenode_config(_Name, []) -> + []. + +%% ------------------------------------------------------------------------------ + +remove_timetraphandle_config(Config) -> + lists:keydelete(timetraphandle,1,Config). +%% ------------------------------------------------------------------------------ + +%% This function can be meta traced in order to check that exception_trace works. +%% Must be exported. +failing_function(nofailure) -> + true; +failing_function(failure) -> + exit(failure). +%% ------------------------------------------------------------------------------ + +%% ============================================================================== +%% Code for a test process which can be started. +%% ============================================================================== + +test_proc_init() -> + register(inviso_test_proc,self()), + test_proc_loop(). + +test_proc_loop() -> + receive + {apply,M,F,Args} -> + apply(M,F,Args), + test_proc_loop(); + X -> + io:format("Got ~w~n",[X]), + test_proc_loop() + end. + +global_test_proc_init() -> + global:register_name(global_inviso_test_proc,self()), + test_proc_loop(). +%% ------------------------------------------------------------------------------ + +send_to_test_proc(_,_,_,0) -> + error; +send_to_test_proc(Msg,Fun,FunArg,N) -> + inviso_test_proc ! Msg, + case Fun(FunArg) of + done -> + ok; + error -> + test_server:fail(send_to_test_proc); + _ -> + send_to_test_proc(Msg,Fun,FunArg,N-1) + end. +%% ------------------------------------------------------------------------------ + + +%% This function is here to be traced on by the inviso_test_proc. Must be exported. +test_function() -> + 1+1. +%% ------------------------------------------------------------------------------ + + +%% ============================================================================== +%% Code for a test side effect table process. +%% ============================================================================== + +%% The side effect logger is a process owning a public ETS table. The idea is that +%% various callback functions can write in the table when called. In that way +%% correct calling of the call-backs can be verified. +start_side_effect_logger(Node) -> + ?l true=is_pid(spawn(Node,?MODULE,side_effect_logger_proc,[])), + ?l ok=poll(rpc,call,[Node,ets,lookup,[inviso_sideeffect_tab,foo]],[],20). + +%% This one must be exported. +side_effect_logger_proc() -> + register(inviso_tab_proc,self()), % So we can kill it later. + ets:new(inviso_sideeffect_tab,[public,named_table]), + side_effect_logger_proc_2(). + +side_effect_logger_proc_2() -> + receive + _X -> % This process is not expecting anything! + side_effect_logger_proc_2() + end. +%% ------------------------------------------------------------------------------ diff --git a/lib/runtime_tools/test/inviso_testmodule1_foo.erl b/lib/runtime_tools/test/inviso_testmodule1_foo.erl new file mode 100644 index 0000000000..a7a22cad39 --- /dev/null +++ b/lib/runtime_tools/test/inviso_testmodule1_foo.erl @@ -0,0 +1,9 @@ +-module(inviso_testmodule1_foo). + +-compile(export_all). + +%% The purpose of this module is simply to have a module that is +%% guaranteed not loaded. + +foo() -> + true. diff --git a/lib/runtime_tools/test/runtime_tools.cover b/lib/runtime_tools/test/runtime_tools.cover new file mode 100644 index 0000000000..2d62ebe6ac --- /dev/null +++ b/lib/runtime_tools/test/runtime_tools.cover @@ -0,0 +1 @@ +{exclude,[observer_backend]}. diff --git a/lib/runtime_tools/test/runtime_tools.spec b/lib/runtime_tools/test/runtime_tools.spec new file mode 100644 index 0000000000..a60a533ce2 --- /dev/null +++ b/lib/runtime_tools/test/runtime_tools.spec @@ -0,0 +1 @@ +{topcase, {dir, "../runtime_tools_test"}}. diff --git a/lib/runtime_tools/test/runtime_tools_SUITE.erl b/lib/runtime_tools/test/runtime_tools_SUITE.erl new file mode 100644 index 0000000000..84e255e126 --- /dev/null +++ b/lib/runtime_tools/test/runtime_tools_SUITE.erl @@ -0,0 +1,50 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(runtime_tools_SUITE). +-include("test_server.hrl"). + +%% Test server specific exports +-export([all/1]). +-export([init_per_testcase/2, end_per_testcase/2]). + +%% Test cases +-export([app_file/1]). + +%% Default timetrap timeout (set in init_per_testcase) +-define(default_timeout, ?t:minutes(1)). + +init_per_testcase(_Case, Config) -> + Dog = test_server:timetrap(?default_timeout), + [{watchdog, Dog} | Config]. + +end_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + ?t:timetrap_cancel(Dog), + ok. + +all(suite) -> + [app_file]. + +app_file(suite) -> + []; +app_file(doc) -> + ["Testing .app file"]; +app_file(Config) when is_list(Config) -> + ?line ok = ?t:app_test(runtime_tools), + ok. diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src index 82114c9afd..09249e5e39 100644 --- a/lib/ssh/src/ssh.appup.src +++ b/lib/ssh/src/ssh.appup.src @@ -19,9 +19,9 @@ {"%VSN%", [ - {"1.1.10", [{load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}, - {"1.1.9", [{load_module, ssh_channel, soft_purge, soft_purge, []}, - {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}, + {"1.1.11", [{restart_application, ssh}]}, + {"1.1.10", [{restart_application, ssh}]}, + {"1.1.9", [{restart_application, ssh}]}, {"1.1.8", [{restart_application, ssh}]}, {"1.1.7", [{restart_application, ssh}]}, {"1.1.6", [{restart_application, ssh}]}, @@ -31,9 +31,9 @@ {"1.1.2", [{restart_application, ssh}]} ], [ - {"1.1.10", [{load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}, - {"1.1.9", [{load_module, ssh_channel, soft_purge, soft_purge, []}, - {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}, + {"1.1.11", [{restart_application, ssh}]}, + {"1.1.10", [{restart_application, ssh}]}, + {"1.1.9", [{restart_application, ssh}]}, {"1.1.8", [{restart_application, ssh}]}, {"1.1.7", [{restart_application, ssh}]}, {"1.1.6", [{restart_application, ssh}]}, diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index 822ef8f8f9..926d4fddce 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -705,11 +705,19 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName, Byte == ?SSH_MSG_CHANNEL_REQUEST; Byte == ?SSH_MSG_CHANNEL_SUCCESS; Byte == ?SSH_MSG_CHANNEL_FAILURE -> - ssh_connection_manager:event(Pid, Msg), - State = generate_event_new_state(State0, EncData), - next_packet(State), - {next_state, StateName, State}; + try + ssh_connection_manager:event(Pid, Msg), + State = generate_event_new_state(State0, EncData), + next_packet(State), + {next_state, StateName, State} + catch + exit:{noproc, _Reason} -> + Report = io_lib:format("~p Connection Handler terminated: ~p~n", + [self(), Pid]), + error_logger:info_report(Report), + {stop, normal, State0} + end; generate_event(Msg, StateName, State0, EncData) -> Event = ssh_bits:decode(Msg), State = generate_event_new_state(State0, EncData), diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index 8e31851a8e..cf90e3b11e 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,9 +1,12 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 1.1.11 +SSH_VSN = 1.1.12 APP_VSN = "ssh-$(SSH_VSN)" -TICKETS = OTP-8735 +TICKETS = OTP-8807 \ + OTP-8881 + +TICKETS_1.1.11 = OTP-8735 TICKETS_1.1.10 = OTP-8714 diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml index 0f30ae9eca..91a98808a2 100644 --- a/lib/xmerl/doc/src/notes.xml +++ b/lib/xmerl/doc/src/notes.xml @@ -31,6 +31,21 @@ <p>This document describes the changes made to the Xmerl application.</p> +<section><title>Xmerl 1.2.4.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> An empty element declared as simpleContent was not + properly validated. </p> + <p> + Own Id: OTP-8599</p> + </item> + </list> + </section> + +</section> + <section><title>Xmerl 1.2.4</title> <section><title>Improvements and New Features</title> diff --git a/lib/xmerl/src/xmerl_xsd.erl b/lib/xmerl/src/xmerl_xsd.erl index c7bca86205..1aedc9e270 100644 --- a/lib/xmerl/src/xmerl_xsd.erl +++ b/lib/xmerl/src/xmerl_xsd.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2006-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2006-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% @@ -2687,13 +2687,16 @@ check_element_type(XML=[E=#xmlElement{name=Name}|Rest], _ -> {error,{error_path(E,Name),?MODULE,{element_bad_match,E,Any,Env}}} end; -check_element_type([],CM,_Env,_Block,_S,Checked) -> +check_element_type([],CM,_Env,_Block,S,Checked) -> %% #schema_complex_type, any, #schema_group, anyType and lists are %% catched above. case CM of + #schema_simple_type{} -> + {NewVal,S2} = check_type(CM,[],unapplied,S), + {NewVal,[],S2}; {simpleType,_} -> - {error,{error_path(Checked,undefined),?MODULE, - {empty_content_not_allowed,CM}}}; + {NewVal,S2} = check_type(CM,[],unapplied,S), + {NewVal,[],S2}; _ -> {error,{error_path(Checked,undefined),?MODULE, {empty_content_not_allowed,CM}}} diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk index 96133d687a..39213a2c4a 100644 --- a/lib/xmerl/vsn.mk +++ b/lib/xmerl/vsn.mk @@ -1,4 +1,4 @@ -XMERL_VSN = 1.2.4 +XMERL_VSN = 1.2.4.1 TICKETS = \ |