1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20%%
21%%-----------------------------------------------------------------
22%%
23%% Description:
24%% Test suite for corba/boa/object/orber API functions
25%%
26%%-----------------------------------------------------------------
27-module(corba_SUITE).
28
29-include_lib("common_test/include/ct.hrl").
30-include_lib("orber/include/corba.hrl").
31-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
32-include_lib("orber/src/orber_iiop.hrl").
33
34
35-define(default_timeout, test_server:minutes(5)).
36
37-define(match(ExpectedRes,Expr),
38	fun() ->
39	       AcTuAlReS = (catch (Expr)),
40	       case AcTuAlReS of
41		   ExpectedRes ->
42		       io:format("------ CORRECT RESULT ------~n~p~n",
43				 [AcTuAlReS]),
44		       AcTuAlReS;
45		   _ ->
46		       io:format("###### ERROR ERROR ######~nRESULT:  ~p~n",
47				 [AcTuAlReS]),
48		       exit(AcTuAlReS)
49	       end
50       end()).
51
52%%-----------------------------------------------------------------
53%% External exports
54%%-----------------------------------------------------------------
55-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
56
57%%-----------------------------------------------------------------
58%% Internal exports
59%%-----------------------------------------------------------------
60-export([pseudo_calls/2, pseudo_casts/2]).
61-compile(export_all).
62
63%%-----------------------------------------------------------------
64%% Func: all/1
65%% Args:
66%% Returns:
67%%-----------------------------------------------------------------
68suite() -> [{ct_hooks,[ts_install_cth]}].
69
70all() ->
71    cases().
72
73groups() ->
74    [].
75
76init_per_group(_GroupName, Config) ->
77    Config.
78
79end_per_group(_GroupName, Config) ->
80    Config.
81
82
83cases() ->
84    [exception_info_api, corba_api, object_api, orber_api,
85     orber_objectkeys_api, orber_pseudo_objects,
86     callback_ok_api, callback_arity_api,
87     callback_module_api, callback_function_api,
88     callback_precond_api, callback_postcond_api,
89     callback_exit_api, callback_badarith_api,
90     callback_case_clause_api, callback_function_clause_api].
91
92%% boa_api, request, locate_request, locate_reply].
93
94%%-----------------------------------------------------------------
95%% Init and cleanup functions.
96%%-----------------------------------------------------------------
97
98init_per_testcase(_Case, Config) ->
99    Path = code:which(?MODULE),
100    code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
101    Dog=test_server:timetrap(?default_timeout),
102    [{watchdog, Dog}|Config].
103
104
105end_per_testcase(_Case, Config) ->
106    Path = code:which(?MODULE),
107    code:del_path(filename:join(filename:dirname(Path), "idl_output")),
108    Dog = proplists:get_value(watchdog, Config),
109    test_server:timetrap_cancel(Dog),
110    ok.
111
112init_per_suite(Config) ->
113    corba:orb_init([{orber_debug_level, 10}, {giop_version, {1,2}},
114		    {iiop_port, 0}]),
115    mnesia:delete_schema([node()]),
116    mnesia:create_schema([node()]),
117    orber:install([node()]),
118    application:start(mnesia),
119    application:start(orber),
120    if
121	is_list(Config) ->
122	    Config;
123	true ->
124	    exit("Config not a list")
125    end.
126
127end_per_suite(Config) ->
128    application:stop(orber),
129    application:stop(mnesia),
130    mnesia:delete_schema([node()]),
131    Config.
132
133%%-----------------------------------------------------------------
134%%  API tests for pseudo interface CORBA
135%%-----------------------------------------------------------------
136corba_api(_) ->
137    NIL = corba:create_nil_objref(),
138    ok = corba:dispose(NIL),
139    NS = corba:resolve_initial_references("NameService"),
140    List = corba:list_initial_services(),
141    ["NameService"] = List,
142    NSstring = corba:object_to_string(NS),
143    NS1 = corba:string_to_object(NSstring),
144    NSstring = corba:object_to_string(NS1),
145    true = corba:add_initial_service("MyData", NS),
146    NS = corba:resolve_initial_references("MyData"),
147    [_,_] = corba:list_initial_services(),
148    false = corba:remove_initial_service("Wrong"),
149    NIL = corba:resolve_initial_references("Wrong"),
150    NS = corba:string_to_object("corbaloc:rir:/MyData"),
151    true = corba:remove_initial_service("MyData"),
152    ["NameService"] = corba:list_initial_services(),
153
154    %% This is a collection of different stringified IOR:s (correct & incorrect)
155    %% which we use to test IOR encode/decode.
156    IOR1 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000040000000000000100000102010000000a3132372e302e302e31009d610000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e2316570000000003030300000002000000210000007800010202000000010040020200000022000000080003030300000000004000400000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c00030303000100010000000400010020000101090001010005010001000101090000000200010100050100010000000000000184000102010000000a3132372e302e302e310000000000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e231657000000000303030000000300000021000000ec000102020000000200060202000000240000001c0001006600060202000000010000000a3132372e302e302e31009d600000000000000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f00460202000000240000001c0001006600060202000000010000000a3132372e302e302e31009d62004000400000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f00000014000000080001006600069d5e000000010000002c000303030001000100000004000100200001010900010100050100010001010900000002000101000501000100000000000000dc000102010000000a3132372e302e302e31009d5f0000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e23165700000000030303000000020000002100000054000102020000000100000202000000220000000800030303000000000000000000000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c00030303000100010000000400010020000101090001010005010001000101090000000200010100050100010000000000000080000102010000000a3132372e302e302e31009d5d0000002dabacab3131303432343836383731005f526f6f74504f4100414c4c5f504f410000cafebabe3e2316570000000003030300000001000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
157    IOR2 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e30000303030000000100000000000000e0000102010000000a3132372e302e302e31009d5f00000034abacab3131303432343836383731005f526f6f74504f410049494f505f43534976325f504f410000cafebabe3e23165700000000000000020000002100000054000102020000000100000202000000220000000800030303000000000000000000000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
158    IOR3 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000108000102010000000a3132372e302e302e31009d6100000037abacab3131303432343836383731005f526f6f74504f410049494f505f43534976325f55505f504f410000cafebabe3e231657000000000100000002000000210000007800010202000000010040020200000022000000080003030300000000004000400000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
159    IOR4 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000080000102010000000a3132372e302e302e31009d5d0000002eabacab3131303432343836383731005f526f6f74504f410049494f505f504f410000cafebabe3e23165700000000020200000001000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
160    IOR5 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e30000303030000000100000000000000fc000102010000000a3132372e302e302e3100000000000033abacab3131303432343836383731005f526f6f74504f4100544c535f43534976325f504f410000cafebabe3e231657000000000100000002000000210000007000010202000000010006020200000024000000220001006600060202000000010000000f3132382e3233302e3230382e353500019d6000000000020200000000000000000400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
161    IOR6 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000124000102010000000a3132372e302e302e3100000000000036abacab3131303432343836383731005f526f6f74504f4100544c535f43534976325f55505f504f410000cafebabe3e23165700000000020200000002000000210000009400010202000000010046020200000024000000220001006600060202000000010000000f3132382e3233302e3230382e353500019d620040004002020000000806066781020101010000001b0401000806066781020101010000000b40616469726f6e2e636f6d010400000000000000000000020000000806066781020101010000000b06092a864886f712010202010000000f000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
162    IOR7 = ?match({'IOP_IOR',_,_}, corba:string_to_object("IOR:000303030000000d49444c3a746573743a312e3000030303000000010000000000000090000102010000000a3132372e302e302e310000000000002dabacab3131303432343836383731005f526f6f74504f4100544c535f504f410000cafebabe3e231657000000000303030000000200000014000000080001006600069d5e000000010000002c0003030300010001000000040001002000010109000101000501000100010109000000020001010005010001")),
163    IOR1 = corba:string_to_object(corba:object_to_string(IOR1)),
164    IOR2 = corba:string_to_object(corba:object_to_string(IOR2)),
165    IOR3 = corba:string_to_object(corba:object_to_string(IOR3)),
166    IOR4 = corba:string_to_object(corba:object_to_string(IOR4)),
167    IOR5 = corba:string_to_object(corba:object_to_string(IOR5)),
168    IOR6 = corba:string_to_object(corba:object_to_string(IOR6)),
169    IOR7 = corba:string_to_object(corba:object_to_string(IOR7)),
170    ?match(ok, corba:print_object(IOR1)),
171    ?match(ok, corba:print_object(IOR2)),
172    ?match(ok, corba:print_object(IOR3)),
173    ?match(ok, corba:print_object(IOR4)),
174    ?match(ok, corba:print_object(IOR5)),
175    ?match(ok, corba:print_object(IOR6)),
176    ?match(ok, corba:print_object(IOR7)),
177    ?match(ok, corba:print_object("IOR:000303030000000d49444c3a746573743a312e300003030300000002000000000000003000010001000000136d792e686f73742e65726c616e672e6f72670001801a02020000000c424f410a00000a0000070a010000000100000024000303030000000100000001000000140003030300010001000000000001010900000000")),
178    [IP] = ?match([_], orber:host()),
179    ?match(#'IOP_IOR'{profiles=[#'IOP_TaggedProfile'
180				{tag=?TAG_INTERNET_IOP,
181				 profile_data=#'IIOP_ProfileBody_1_1'
182				 {host = IP}}]},
183	   corba:string_to_object(corba:object_to_string(NS))),
184    ?match(#'IOP_IOR'{profiles=[#'IOP_TaggedProfile'
185				{tag=?TAG_INTERNET_IOP,
186				 profile_data=#'IIOP_ProfileBody_1_1'
187				 {host = "127.0.0.1"}}]},
188	   corba:string_to_object(corba:object_to_string(NS, ["127.0.0.1"]))),
189    ?match(#'IOP_IOR'{profiles=[#'IOP_TaggedProfile'
190				{tag=?TAG_INTERNET_IOP,
191				 profile_data=#'IIOP_ProfileBody_1_1'
192				 {host = "127.0.0.1", port = 5468}}]},
193	   corba:string_to_object(corba:object_to_string(NS, ["127.0.0.1"],
194							 5468))),
195    ok.
196
197%%-----------------------------------------------------------------
198%% API tests for interface BOA
199%%-----------------------------------------------------------------
200boa_api(_) ->
201    ok.
202
203%%-----------------------------------------------------------------
204%% API tests for interface OBJECT
205%%-----------------------------------------------------------------
206object_api(_) ->
207    oe_orber_test_server:oe_register(),
208    EC = orber_test_server:oe_create(),
209    NS = corba:resolve_initial_references("NameService"),
210    %% testing corba_object:is_a(Obj, IFRID) locally.
211    orber_test_lib:corba_object_tests(EC, NS),
212
213    ?match(false, corba_object:non_existent(NS)),
214
215    corba:dispose(EC),
216    oe_orber_test_server:oe_unregister(),
217    ok.
218
219%%-----------------------------------------------------------------
220%% API tests for orbers main module
221%%-----------------------------------------------------------------
222orber_api(_) ->
223    ok = orber:uninstall(),
224    orber:install([node()]),
225    application:start(orber),
226    NodeList = orber:orber_nodes(),
227    NL = node(),
228    [NL] = NodeList,
229    ok.
230
231%%-----------------------------------------------------------------
232%% API tests for exception mapping
233%%-----------------------------------------------------------------
234exception_info_api(_) ->
235    {ok, S1} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1163001858,'COMPLETED_NO'}}),
236    {ok, S2} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1330446337,'COMPLETED_NO'}}),
237    {ok, S3} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1398079490,'COMPLETED_NO'}}),
238    {ok, S4} = orber:exception_info({'EXCEPTION',{'MARSHAL',[],1347813377,'COMPLETED_NO'}}),
239    {ok, S5} = orber:exception_info({'EXCEPTION', {'CosNaming_NamingContext_InvalidName',"IDL:omg.org/CosNaming/NamingContext/InvalidName:1.0"}}),
240    error_logger:info_msg("~s", [S1]),
241    error_logger:info_msg("~s", [S2]),
242    error_logger:info_msg("~s", [S3]),
243    error_logger:info_msg("~s", [S4]),
244    error_logger:info_msg("~s", [S5]),
245    ok.
246
247%%-----------------------------------------------------------------
248%% API tests for orbers pseudo objects.
249%%-----------------------------------------------------------------
250orber_pseudo_objects(_) ->
251    oe_orber_test_server:oe_register(),
252    Obj1=(catch orber_test_server:oe_create(state,[{pseudo,true},
253						   {local_typecheck, true}])),
254    ?match({_,pseudo,orber_test_server_impl, _,_, _}, Obj1),
255    Obj2=(catch orber_test_server:oe_create([],[{pseudo, truce}])),
256    ?match({'EXCEPTION',{'BAD_PARAM',[],_,'COMPLETED_NO'}}, Obj2),
257    spawn(?MODULE, pseudo_calls, [20, Obj1]),
258    ?match({ok, 10000}, orber_test_server:pseudo_call_delay(Obj1, 10000)),
259    spawn(?MODULE, pseudo_casts, [20, Obj1]),
260    ?match(ok, orber_test_server:pseudo_cast_delay(Obj1, 10000)),
261
262    ?match('object_here', corba:locate(Obj1)),
263
264    NS = corba:resolve_initial_references("NameService"),
265
266    orber_test_lib:corba_object_tests(Obj1, NS),
267
268    ?match("IDL:omg.org/orber_test/server:1.0",orber_test_server:typeID()),
269
270    %% Test if exceptions are handled properly.
271    ?match({'EXCEPTION',{'BAD_QOS',_,_,_}},
272	   orber_test_server:pseudo_call_raise_exc(Obj1, 1)),
273    ?match({'EXCEPTION',{'BAD_QOS',_,_,_}},
274	   orber_test_server:pseudo_call_raise_exc(Obj1, 2)),
275
276    %% Test if exit is handled properly.
277    ?match({'EXCEPTION',{'TRANSIENT',_,_,_}},
278	   orber_test_server:stop_brutal(Obj1)),
279
280    orber_test_lib:test_coding(Obj1, true),
281
282    %% possible to use subobject key?
283    ?match(state, binary_to_term(corba:get_subobject_key(Obj1))),
284
285    ?match({'EXCEPTION',{'INV_OBJREF',[],_,'COMPLETED_NO'}},
286		 corba:get_pid(Obj1)),
287    ?match(false, corba_object:non_existent(Obj1)),
288
289    ?match(ok, corba:dispose(Obj1)),
290
291    ?match(false, corba_object:non_existent(Obj1)),
292
293    %% Try if it's possible to stringify and recover the object reference.
294    IOR_string = (catch corba:object_to_string(Obj1)),
295    Obj3 =(catch corba:string_to_object(IOR_string)),
296    ?match(IOR_string, corba:object_to_string(Obj3)),
297
298    Obj4=(catch orber_test_server:oe_create(undefined,[{pseudo,true}])),
299    ?match(ok, corba:dispose(Obj4)),
300    oe_orber_test_server:oe_unregister(),
301    ok.
302
303%%-----------------------------------------------------------------
304%% API tests for orbers objectkeys server.
305%%-----------------------------------------------------------------
306orber_objectkeys_api(_) ->
307    Obj0=(catch orber_test_server:oe_create([], [{sup_child, true}])),
308    Obj1=(catch orber_test_server:oe_create([], [{persistent, true},
309						 {regname, {local,obj1}}])),
310    Obj2=(catch orber_test_server:oe_create([], [{persistent, true},
311						 {regname, {global,{obj2, 12345}}}])),
312
313    %% Obj0 is supposed to be a child started by a supervisor (r6) which
314    %% handles not only {ok, Pid} but also {ok,Pid, Returnvalue}. In our
315    %% case the Returnvalue is an ObjectRef.
316    ?match({ok,_,{_,key,_, _,_, _}}, Obj0),
317    {ok,_,Obj0Ref} = Obj0,
318    corba:dispose(Obj0Ref),
319
320    %% Only 'global' servers are at the moment allowed to be persistent.
321    ?match({'EXCEPTION',{'BAD_PARAM',[],_,'COMPLETED_NO'}}, Obj1),
322
323    %% We created a persistent object successfully.
324    ?match({_,key,_,_,_, _}, Obj2),
325
326    %% Get key and Pid
327    {_,_,Key,_,_, _} = Obj2,
328    PID=(catch orber_objectkeys:get_pid(Key)),
329
330    %% Use the two different ways to look up if the server is persistent.
331    ?match(true, orber_objectkeys:is_persistent(Key)),
332    ?match(true, orber_objectkeys:is_persistent(PID)),
333
334    %% Create servers using every possible way.
335    O1=(catch orber_test_server:oe_create()),
336    O2=(catch orber_test_server:oe_create_link()),
337    O3=(catch orber_test_server:oe_create([])),
338    O4=(catch orber_test_server:oe_create_link([])),
339    %% NOTE!!! Next four lines requires that we still support RegName instead of
340    %% only OptionList as the second argument to oe_create*/2. Remove these when that
341    %% is no longer the case.
342    O5=(catch orber_test_server:oe_create([], {'local', o5})),
343    O6=(catch orber_test_server:oe_create([], {'global', {o6, obj}})),
344    O7=(catch orber_test_server:oe_create_link([], {'local', o7})),
345    O8=(catch orber_test_server:oe_create_link([], {'global', {o8, obj}})),
346
347    %% Test if all the object references are correct.
348    ?match({_,key,_,_,_, _}, O1),
349    ?match({_,key,_,_,_, _}, O2),
350    ?match({_,key,_,_,_, _}, O3),
351    ?match({_,key,_,_,_, _}, O4),
352    ?match({_, registered, o5, _,_, _}, O5),
353    ?match({_,key,_,_,_, _}, O6),
354    ?match({_, registered, o7, _,_, _}, O7),
355    ?match({_,key,_,_,_, _}, O8),
356
357    %% Test if persistent.
358    {_,_,Key1,_,_, _} = O1,
359    PID1=(catch orber_objectkeys:get_pid(Key1)),
360    ?match(false, orber_objectkeys:is_persistent(Key1)),
361    ?match(false, orber_objectkeys:is_persistent(PID1)),
362
363    %% all the servers are alive(?!).
364    ?match(false, corba_object:non_existent(O1)),
365    ?match(false, corba_object:non_existent(O2)),
366    ?match(false, corba_object:non_existent(O3)),
367    ?match(false, corba_object:non_existent(O4)),
368    ?match(false, corba_object:non_existent(O5)),
369    ?match(false, corba_object:non_existent(O6)),
370    ?match(false, corba_object:non_existent(O7)),
371    ?match(false, corba_object:non_existent(O8)),
372    ?match(false, corba_object:non_existent(Obj2)),
373
374    %% Does locate work?
375    ?match('object_here', corba:locate(O1)),
376    ?match('object_here', corba:locate(O2)),
377    ?match('object_here', corba:locate(O3)),
378    ?match('object_here', corba:locate(O4)),
379    ?match('object_here', corba:locate(O5)),
380    ?match('object_here', corba:locate(O6)),
381    ?match('object_here', corba:locate(O7)),
382    ?match('object_here', corba:locate(O8)),
383    ?match('object_here', corba:locate(Obj2)),
384
385    %% Terminate all servers with reason 'normal'.
386    catch corba:dispose(O1),
387    catch corba:dispose(O2),
388    catch corba:dispose(O3),
389    catch corba:dispose(O4),
390    catch corba:dispose(O5),
391    catch corba:dispose(O6),
392    catch corba:dispose(O7),
393    catch corba:dispose(O8),
394    catch corba:dispose(Obj2),
395
396
397    %% To make sure that orber_objectkeys-server is able to
398    %% clean up we wait.
399    timer:sleep(2000),
400
401    %% all the servers are dead(?!). If one of these test-cases
402    %% fails the only error can be that we didn't sleep long enough, i.e.,
403    %% try a longer timeout. If still fails something is wrong.
404    ?match(true, corba_object:non_existent(O1)),
405    ?match(true, corba_object:non_existent(O2)),
406    ?match(true, corba_object:non_existent(O3)),
407    ?match(true, corba_object:non_existent(O4)),
408    ?match(true, corba_object:non_existent(O5)),
409    ?match(true, corba_object:non_existent(O6)),
410    ?match(true, corba_object:non_existent(O7)),
411    ?match(true, corba_object:non_existent(O8)),
412    ?match(true, corba_object:non_existent(Obj2)),
413
414    %% Create a new persistent server.
415    Obj3=(catch orber_test_server:oe_create([],
416					    [{persistent, true},
417					     {regname, {global,{obj2, 12345}}}])),
418
419    %% OK?!
420    ?match({_,key,_,_,_, _}, Obj3),
421
422    %% Try to create a server with the same name (naturally it fails).
423    ?match({'EXCEPTION',{'INTERNAL',[],_,'COMPLETED_NO'}},
424		 orber_test_server:oe_create([],
425					     [{persistent, true},
426					      {regname, {global,{obj2, 12345}}}])),
427    %% Try to remove all 'dead' servers. No server should be removed.
428    orber_objectkeys:gc(0),
429
430    %% Kill object brutal, i.e., not with reason 'normal' or 'shutdown'.
431    P3 = corba:get_pid(Obj3),
432    exit(P3, kill),
433
434    {_,_,Key3,_,_, _} = Obj3,
435
436    %% Give time to clean up.
437    timer:sleep(2000),
438    ?match({'EXCEPTION',{'TRANSIENT',[],_,'COMPLETED_NO'}},
439		 gen_server:call(orber_objkeyserver,
440				 {get_pid, Key3},
441				 infinity)),
442
443    ?match(false,corba_object:non_existent(Obj3)),
444
445    %% Run gc wit a "huge" time-limit. Will not erase the dead object.
446    orber_objectkeys:gc(10000),
447    ?match(false,corba_object:non_existent(Obj3)),
448
449    %% Run gc with minimum time-limit. Will erase the dead object.
450    orber_objectkeys:gc(0),
451    ?match(true,corba_object:non_existent(Obj3)),
452
453    %% Create a new persistent server.
454    Obj4=(catch orber_test_server:oe_create([],
455					    [{persistent, true},
456					     {regname, {global,{obj2, 12345}}}])),
457
458    %% OK?!
459    ?match({_,key,_,_,_, _}, Obj4),
460    %% Kill object brutal, i.e., not with reason 'normal' or 'shutdown'.
461    P4 = corba:get_pid(Obj4),
462    exit(P4, kill),
463
464    %% Give time to clean up.
465    timer:sleep(2000),
466%    ?match({'EXCEPTION',{'COMM_FAILURE',[],0,'COMPLETED_NO'}},
467    ?match({error, _},
468		 corba:get_pid(Obj4)),
469
470    ?match(false,corba_object:non_existent(Obj4)),
471
472    %% Restart the object.
473    Obj5=(catch orber_test_server:oe_create([],
474					    [{persistent, true},
475					     {regname, {global,{obj2, 12345}}}])),
476    %% OK?!
477    ?match({_,key,_,_,_, _}, Obj5),
478
479    %% Run gc with minimum time-limit.
480    orber_objectkeys:gc(0),
481    ?match(false,corba_object:non_existent(Obj5)),
482    corba:dispose(Obj5),
483    ok.
484
485
486%%-----------------------------------------------------------------
487%% API tests for callback functions
488%%-----------------------------------------------------------------
489-define(DO_EXIT_FLAG, 0).
490-define(NO_EXIT_FLAG, 16#10).
491
492-define(DO_EXIT, {is, 0}).
493-define(NO_EXIT, {is, 16#10}).
494
495
496
497%% Successful callback API tests
498callback_ok_api(_) ->
499    %% Init
500    ?match({ok, {?DO_EXIT, state}}, corba:handle_init(?MODULE, {?DO_EXIT_FLAG, state})),
501    %% Terminate
502    ?match(ok, corba:handle_terminate(?MODULE, "reason", {?DO_EXIT, state})),
503    %% Handle_call
504    ?match({reply,ok,{?DO_EXIT,state}},
505		 corba:handle_call(?MODULE, foo, [],
506				   {?DO_EXIT, state}, [], false, false)),
507    %% Handle_cast
508    ?match({noreply, {?DO_EXIT,state}},
509		 corba:handle_cast(?MODULE, foo_1w, [],
510				   {?DO_EXIT, state}, [], false)),
511    %% Handle_call precond/postcond
512    ?match({reply, ok, {?DO_EXIT, state}},
513		 corba:handle_call(?MODULE, foo, [],
514				   {?DO_EXIT, state}, [], false, false, {?MODULE, precond},
515				   {?MODULE, postcond}, ?MODULE)),
516    %% Handle_cast precond/postcond
517    ?match({noreply, {?DO_EXIT, state}},
518		 corba:handle_cast(?MODULE, foo_1w, [],
519				   {?DO_EXIT, state}, [], false, {?MODULE, precond},
520				   {?MODULE, postcond}, ?MODULE)),
521    %% Handle_info
522    ?match({noreply, {?DO_EXIT, state}},
523		 corba:handle_info(?MODULE, "info", {?DO_EXIT, state})),
524    ok.
525
526%% Callback arity API tests
527callback_arity_api(_) ->
528    %% Handle_call - stay-alive == false
529    ?match({'EXIT', {undef,_}},
530		 corba:handle_call(?MODULE, foo, [to, many, arguments],
531				   {?DO_EXIT, state}, [], false, false)),
532    %% Handle_call - stay-alive == true
533    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
534		 corba:handle_call(?MODULE, foo, [to, many, arguments],
535				   {?NO_EXIT, state}, [], false, false)),
536    %% Handle_call - stay-alive == false
537    ?match({'EXIT', _},
538		 corba:handle_call(?MODULE, foo, [],
539				   {?DO_EXIT, arity}, [], false, false)),
540    %% Handle_call - stay-alive == true
541    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
542		 corba:handle_call(?MODULE, foo, [],
543				   {?NO_EXIT, arity}, [], false, false)),
544    %% Handle_cast - stay-alive == false
545    ?match({'EXIT', {undef,_}},
546		 corba:handle_cast(?MODULE, foo_1w, [to, many, arguments],
547				   {?DO_EXIT, state}, [], false)),
548    %% Handle_cast - stay-alive == true
549    ?match({noreply, {?NO_EXIT, state}},
550		 corba:handle_cast(?MODULE, foo_1w, [to, many, arguments],
551				   {?NO_EXIT, state}, [], false)),
552    %% Handle_cast - stay-alive == false
553    ?match({'EXIT', _},
554		 corba:handle_cast(?MODULE, foo_1w, [],
555				   {?DO_EXIT, arity}, [], false)),
556    %% Handle_cast - stay-alive == true
557    ?match({noreply, {?NO_EXIT, arity}},
558		 corba:handle_cast(?MODULE, foo_1w, [],
559				   {?NO_EXIT, arity}, [], false)),
560    %% Handle_info - stay-alive == false
561    ?match({'EXIT', _},
562		 corba:handle_info(?MODULE, "info", {?DO_EXIT, arity})),
563
564    %% Handle_info - stay-alive == true
565    ?match({noreply, {?NO_EXIT, arity}},
566		 corba:handle_info(?MODULE, "info", {?NO_EXIT, arity})),
567    ok.
568
569%% Module callback API tests
570callback_module_api(_) ->
571    %% Handle_call - stay-alive == false
572    ?match({'EXIT', {undef,_}},
573		 corba:handle_call(wrong_mod, foo, [],
574				   {?DO_EXIT, state}, [], false, false)),
575    %% Handle_call - stay-alive == true
576    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
577		 corba:handle_call(wrong_mod, foo, [],
578				   {?NO_EXIT, state}, [], false, false)),
579    %% Handle_cast - stay-alive == false
580    ?match({'EXIT', {undef,_}},
581		 corba:handle_cast(wrong_mod, foo_1w, [],
582				   {?DO_EXIT, state}, [], false)),
583    %% Handle_cast - stay-alive == true
584    ?match({noreply, {?NO_EXIT, state}},
585		 corba:handle_cast(wrong_mod, foo_1w, [],
586				   {?NO_EXIT, state}, [], false)),
587    %% Handle_info - stay-alive == false.
588    ?match({'EXIT', _},
589		 corba:handle_info(wrong_mod, "info", {?DO_EXIT, state})),
590
591    %% Handle_info - stay-alive == true.
592    ?match({noreply, {?NO_EXIT, state}},
593		 corba:handle_info(wrong_mod, "info", {?NO_EXIT, state})),
594    ok.
595
596%% Function callback API tests
597callback_function_api(_) ->
598    %% Handle_call - stay-alive == false
599    ?match({'EXIT', {undef,_}},
600		 corba:handle_call(?MODULE, bad_function, [],
601				   {?DO_EXIT, state}, [], false, false)),
602    %% Handle_call - stay-alive == true
603    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
604		 corba:handle_call(?MODULE, bad_function, [],
605				   {?NO_EXIT, state}, [], false, false)),
606    %% Handle_cast - stay-alive == false
607    ?match({'EXIT', {undef,_}},
608		 corba:handle_cast(?MODULE, bad_function, [],
609				   {?DO_EXIT, state}, [], false)),
610    %% Handle_cast - stay-alive == true
611    ?match({noreply, {?NO_EXIT, state}},
612		 corba:handle_cast(?MODULE, bad_function, [],
613				   {?NO_EXIT, state}, [], false)),
614    %% Handle_info - stay-alive == false. Note, we cannot use ?MODULE here.
615    ?match({'EXIT', _},
616		 corba:handle_info(corba, "info", {?DO_EXIT, state})),
617
618    %% Handle_info - stay-alive == true. Note, we cannot use ?MODULE here.
619    ?match({noreply, {?NO_EXIT, state}},
620		 corba:handle_info(corba, "info", {?NO_EXIT, state})),
621    ok.
622
623%% Precond callback API tests
624callback_precond_api(_) ->
625    %% Handle_call - stay-alive == false
626    ?match({'EXIT', _},
627		 corba:handle_call(?MODULE, foo, [],
628				   {?DO_EXIT, state}, [], false, false, {wrong_mod, precond},
629				   {?MODULE, postcond}, ?MODULE)),
630    %% Handle_call - stay-alive == false
631    ?match({'EXIT', _},
632		 corba:handle_call(?MODULE, foo, [],
633				   {?DO_EXIT, state}, [], false, false, {?MODULE, bad_precond},
634				   {?MODULE, postcond}, ?MODULE)),
635    %% Handle_call - stay-alive == true
636    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_},
637		 corba:handle_call(?MODULE, foo, [],
638				   {?NO_EXIT, state}, [], false, false, {wrong_mod, precond},
639				   {?MODULE, postcond}, ?MODULE)),
640    %% Handle_call - stay-alive == true
641    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_},
642		 corba:handle_call(?MODULE, foo, [],
643				   {?NO_EXIT, state}, [], false, false, {?MODULE, bad_precond},
644				   {?MODULE, postcond}, ?MODULE)),
645    %% Handle_cast - stay-alive == false
646    ?match({'EXIT', _},
647		 corba:handle_cast(?MODULE, foo_1w, [],
648				   {?DO_EXIT, state}, [], false, {wrong_mod, precond},
649				   {?MODULE, postcond}, ?MODULE)),
650    %% Handle_cast - stay-alive == false
651    ?match({'EXIT', _},
652		 corba:handle_cast(?MODULE, foo_1w, [],
653				   {?DO_EXIT, state}, [], false, {?MODULE, bad_precond},
654				   {?MODULE, postcond}, ?MODULE)),
655    %% Handle_cast - stay-alive == true
656    ?match({noreply, {?NO_EXIT, state}},
657		 corba:handle_cast(?MODULE, foo_1w, [],
658				   {?NO_EXIT, state}, [], false, {wrong_mod, precond},
659				   {?MODULE, postcond}, ?MODULE)),
660    %% Handle_cast - stay-alive == true
661    ?match({noreply, {?NO_EXIT, state}},
662		 corba:handle_cast(?MODULE, foo_1w, [],
663				   {?NO_EXIT, state}, [], false, {?MODULE, bad_precond},
664				  {?MODULE, postcond}, ?MODULE)),
665    ok.
666
667
668%% Postcond callback API tests
669callback_postcond_api(_) ->
670    %% Handle_call - stay-alive == false
671    ?match({'EXIT', _},
672		 corba:handle_call(?MODULE, foo, [],
673				   {?DO_EXIT, state}, [], false, false, {?MODULE, precond},
674				   {wrong_mod, postcond}, ?MODULE)),
675    %% Handle_call - stay-alive == false
676    ?match({'EXIT', _},
677		 corba:handle_call(?MODULE, foo, [],
678				   {?DO_EXIT, state}, [], false, false, {?MODULE, precond},
679				  {?MODULE, bad_postcond}, ?MODULE)),
680    %% Handle_call - stay-alive == true
681    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_},
682		 corba:handle_call(?MODULE, foo, [],
683				   {?NO_EXIT, state}, [], false, false, {?MODULE, precond},
684				   {wrong_mod, postcond}, ?MODULE)),
685    %% Handle_call - stay-alive == true
686    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_},
687		 corba:handle_call(?MODULE, foo, [],
688				   {?NO_EXIT, state}, [], false, false, {?MODULE, precond},
689				  {?MODULE, bad_postcond}, ?MODULE)),
690    %% Handle_cast - stay-alive == false
691    ?match({'EXIT', _},
692		 corba:handle_cast(?MODULE, foo_1w, [],
693				   {?DO_EXIT, state}, [], false, {?MODULE, precond},
694				  {wrong_mod, postcond}, ?MODULE)),
695    %% Handle_cast - stay-alive == false
696    ?match({'EXIT', _},
697		 corba:handle_cast(?MODULE, foo_1w, [],
698				   {?DO_EXIT, state}, [], false, {?MODULE, precond},
699				  {?MODULE, bad_postcond}, ?MODULE)),
700    %% Handle_cast - stay-alive == true
701    ?match({noreply, {?NO_EXIT, state}},
702		 corba:handle_cast(?MODULE, foo_1w, [],
703				   {?NO_EXIT, state}, [], false, {?MODULE, precond},
704				   {wrong_mod, postcond}, ?MODULE)),
705    %% Handle_cast - stay-alive == true
706    ?match({noreply, {?NO_EXIT, state}},
707		 corba:handle_cast(?MODULE, foo_1w, [],
708				   {?NO_EXIT, state}, [], false, {?MODULE, precond},
709				   {?MODULE, bad_postcond}, ?MODULE)),
710    ok.
711
712
713%% Callback exit API tests
714callback_exit_api(_) ->
715    %% Handle_call - stay-alive == false
716    ?match({'EXIT', _},
717		 corba:handle_call(?MODULE, foo, [],
718				   {?DO_EXIT, exit}, [], false, false)),
719    %% Handle_call - stay-alive == true
720    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
721		 corba:handle_call(?MODULE, foo, [],
722				   {?NO_EXIT, exit}, [], false, false)),
723    %% Handle_cast - stay-alive == false
724    ?match({'EXIT', _},
725		 corba:handle_cast(?MODULE, foo_1w, [],
726				   {?DO_EXIT, exit}, [], false)),
727    %% Handle_cast - stay-alive == true
728    ?match({noreply, {?NO_EXIT, exit}},
729		 corba:handle_cast(?MODULE, foo_1w, [],
730				   {?NO_EXIT, exit}, [], false)),
731    %% Handle_info - stay-alive == false
732    ?match({'EXIT', _},
733		 corba:handle_info(?MODULE, "info", {?DO_EXIT, exit})),
734
735    %% Handle_info - stay-alive == true
736    ?match({noreply, {?NO_EXIT, exit}},
737		 corba:handle_info(?MODULE, "info", {?NO_EXIT, exit})),
738    ok.
739
740
741%% Callback badarith API tests
742callback_badarith_api(_) ->
743    %% Handle_call - stay-alive == false
744    ?match({'EXIT', _},
745		 corba:handle_call(?MODULE, foo, [],
746				   {?DO_EXIT, badarith}, [], false, false)),
747    %% Handle_call - stay-alive == true
748    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}},_},
749		 corba:handle_call(?MODULE, foo, [],
750				   {?NO_EXIT, badarith}, [], false, false)),
751    %% Handle_cast - stay-alive == false
752    ?match({'EXIT', _},
753		 corba:handle_cast(?MODULE, foo_1w, [],
754				   {?DO_EXIT, badarith}, [], false)),
755    %% Handle_cast - stay-alive == true
756    ?match({noreply, {?NO_EXIT, badarith}},
757		 corba:handle_cast(?MODULE, foo_1w, [],
758				   {?NO_EXIT, badarith}, [], false)),
759    %% Handle_info - stay-alive == false
760    ?match({'EXIT', _},
761		 corba:handle_info(?MODULE, "info", {?DO_EXIT, badarith})),
762
763    %% Handle_info - stay-alive == true
764    ?match({noreply, {?NO_EXIT, badarith}},
765		 corba:handle_info(?MODULE, "info", {?NO_EXIT, badarith})),
766    ok.
767
768%% Callback case_clause API tests
769callback_case_clause_api(_) ->
770    %% Handle_call - stay-alive == false
771    ?match({'EXIT', _},
772		 corba:handle_call(?MODULE, foo, [],
773				   {?DO_EXIT, case_clause}, [], false, false)),
774    %% Handle_call - stay-alive == true
775    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
776		 corba:handle_call(?MODULE, foo, [],
777				   {?NO_EXIT, case_clause}, [], false, false)),
778    %% Handle_cast - stay-alive == false
779    ?match({'EXIT', _},
780		 corba:handle_cast(?MODULE, foo_1w, [],
781				   {?DO_EXIT, case_clause}, [], false)),
782    %% Handle_cast - stay-alive == true
783    ?match({noreply, {?NO_EXIT, case_clause}},
784		 corba:handle_cast(?MODULE, foo_1w, [],
785				   {?NO_EXIT, case_clause}, [], false)),
786    %% Handle_info - stay-alive == false
787    ?match({'EXIT', _},
788		 corba:handle_info(?MODULE, "info", {?DO_EXIT, case_clause})),
789
790    %% Handle_info - stay-alive == true
791    ?match({noreply, {?NO_EXIT, case_clause}},
792		 corba:handle_info(?MODULE, "info", {?NO_EXIT, case_clause})),
793    ok.
794
795%% Callback function_clause API tests
796callback_function_clause_api(_) ->
797    %% Handle_call - stay-alive == false
798    ?match({'EXIT', _},
799		 corba:handle_call(?MODULE, foo, [],
800				   {?DO_EXIT, function_clause}, [], false, false)),
801    %% Handle_call - stay-alive == true
802    ?match({reply, {'EXCEPTION', #'OBJ_ADAPTER'{}}, _},
803		 corba:handle_call(?MODULE, foo, [],
804				   {?NO_EXIT, function_clause}, [], false, false)),
805    %% Handle_cast - stay-alive == false
806    ?match({'EXIT', _},
807		 corba:handle_cast(?MODULE, foo_1w, [],
808				   {?DO_EXIT, function_clause}, [], false)),
809    %% Handle_cast - stay-alive == true
810    ?match({noreply, {?NO_EXIT, function_clause}},
811		 corba:handle_cast(?MODULE, foo_1w, [],
812				   {?NO_EXIT, function_clause}, [], false)),
813    %% Handle_info - stay-alive == false
814    ?match({'EXIT', _},
815		 corba:handle_info(?MODULE, "info", {?DO_EXIT, function_clause})),
816    %% Handle_info - stay-alive == true
817    ?match({noreply, {?NO_EXIT, function_clause}},
818		 corba:handle_info(?MODULE, "info", {?NO_EXIT, function_clause})),
819    ok.
820
821%% Faked mandatory operations
822init(State) ->
823    evaluate_state(State),
824    {ok, State}.
825terminate(_Reason, State) ->
826    evaluate_state(State),
827    ok.
828
829code_change(_OldVsn, State, _Extra) ->
830    evaluate_state(State),
831    {ok, State}.
832handle_call(_,_, State) ->
833    evaluate_state(State),
834    {noreply, State}.
835handle_cast(_, State) ->
836    evaluate_state(State),
837    {noreply, State}.
838handle_info(_Info, State) ->
839    evaluate_state(State),
840    {noreply, State}.
841
842foo(State) ->
843    evaluate_state(State),
844    {reply, ok, State}.
845foo(State, _Arg) ->
846    evaluate_state(State),
847    {reply, ok, State}.
848
849foo_1w(State) ->
850    evaluate_state(State),
851    {noreply, State}.
852foo_1w(State, _Arg) ->
853    evaluate_state(State),
854    {noreply, State}.
855
856precond(_Module, _Function, _Args) ->
857    ok.
858
859postcond(_Module, _Function, _Args, _Result) ->
860    ok.
861
862evaluate_state(exit) ->
863    exit("exit on purpose");
864evaluate_state(badarith) ->
865    10 * atom;
866evaluate_state(case_clause) ->
867    case 10 of
868	false ->
869	    ok
870    end;
871evaluate_state(module) ->
872    non_existing_module:bar();
873evaluate_state(function) ->
874    ?MODULE:non_existing_function();
875evaluate_state(arity) ->
876    ?MODULE:foo(to, many, arguments);
877evaluate_state(function_clause) ->
878    evaluate_state(incorrect_state);
879evaluate_state(state) ->
880    ok.
881
882%%-----------------------------------------------------------------
883%% Local functions.
884%%-----------------------------------------------------------------
885
886pseudo_calls(0, _) ->
887    ok;
888pseudo_calls(Times, Obj) ->
889    orber_test_server:pseudo_call(Obj),
890    New = Times - 1,
891    pseudo_calls(New, Obj).
892pseudo_casts(0, _) ->
893    ok;
894pseudo_casts(Times, Obj) ->
895    orber_test_server:pseudo_cast(Obj),
896    New = Times - 1,
897    pseudo_casts(New, Obj).
898