1 // ============================================================================
4 // This class implements a CORBA client for a redundant CosNaming
5 // Service using stubs generated by the TAO ORB IDL compiler.
8 // Rich Seibel <seibel_r@ociweb.com>
9 // ============================================================================
11 #include "test_objectS.h"
12 #include "orbsvcs/CosNamingC.h"
13 #include "orbsvcs/Naming/Naming_Server.h"
14 #include "tao/debug.h"
15 #include "ace/Get_Opt.h"
16 #include "ace/OS_NS_stdio.h"
17 #include "ace/High_Res_Timer.h"
19 #if defined (_MSC_VER)
20 # pragma warning (disable : 4250)
23 class My_Test_Object
:
24 public virtual POA_Test_Object
27 My_Test_Object (CORBA::Short id
= 0);
33 // = Interface implementation accessor methods.
35 void id (CORBA::Short id
);
45 My_Test_Object::My_Test_Object (CORBA::Short id
)
50 My_Test_Object::~My_Test_Object ()
61 My_Test_Object::id (CORBA::Short id
)
67 // This function runs the test.
70 ACE_TMAIN(int argc
, ACE_TCHAR
*argv
[])
75 ACE_TCHAR
*ns1ref
= 0;
76 ACE_TCHAR
*ns2ref
= 0;
79 ACE_Get_Opt
get_opts (argc
, argv
, ACE_TEXT ("b:d:o:p:q:t:"));
83 while ((c
= get_opts ()) != -1)
87 i
= ACE_OS::atoi(get_opts
.opt_arg ());
91 ACE_TEXT ("Invalid breadth, must be 2 or more\n")));
97 i
= ACE_OS::atoi(get_opts
.opt_arg ());
100 ACE_ERROR ((LM_ERROR
,
101 ACE_TEXT ("Invalid depth, must be 2 or more\n")));
107 i
= ACE_OS::atoi(get_opts
.opt_arg ());
110 ACE_ERROR ((LM_ERROR
,
111 ACE_TEXT ("Invalid breadth, must be 2 or more\n")));
117 ns1ref
= get_opts
.opt_arg ();
120 i
= ACE_OS::atoi (get_opts
.opt_arg ());
123 ACE_ERROR ((LM_ERROR
,
124 ACE_TEXT ("Invalid number of test runs. ")
125 ACE_TEXT ("Must be 1 or more\n")));
131 ns2ref
= get_opts
.opt_arg ();
134 ACE_ERROR_RETURN ((LM_ERROR
,
135 ACE_TEXT ("Argument %c \n usage: %s")
136 ACE_TEXT (" [-b <breadth of context tree>]")
137 ACE_TEXT (" [-d <depth of context tree>]")
138 ACE_TEXT (" [-o <breadth of object tree>]")
139 ACE_TEXT (" [-t <number of performance test runs>]")
140 ACE_TEXT (" -p <ior of first name server>")
141 ACE_TEXT (" -q <ior of second name server>")
146 CosNaming::NamingContext_var root_context_1
;
147 CosNaming::NamingContext_var root_context_2
;
152 CORBA::ORB_var orb
= CORBA::ORB_init(argc
, argv
);
154 // ior's are specified for the name servers through a commandline
157 // Resolve the first name server
159 CORBA::Object_var ns1obj
= orb
->string_to_object (
160 ACE_TEXT_ALWAYS_CHAR (ns1ref
));
162 if (CORBA::is_nil (ns1obj
.in ()))
163 ACE_ERROR_RETURN ((LM_ERROR
,
164 ACE_TEXT ("invalid ior <%s>\n"),
167 root_context_1
= CosNaming::NamingContext::_narrow (ns1obj
.in ());
169 // Resolve the second name server
171 CORBA::Object_var ns2obj
= orb
->string_to_object (
172 ACE_TEXT_ALWAYS_CHAR (ns2ref
));
174 if (CORBA::is_nil (ns2obj
.in ()))
175 ACE_ERROR_RETURN ((LM_ERROR
,
176 ACE_TEXT ("invalid ior <%s>\n"),
179 root_context_2
= CosNaming::NamingContext::_narrow (ns2obj
.in ());
181 catch (const CORBA::Exception
& ex
)
183 ex
._tao_print_exception (ACE_TEXT ("Unable to resolve name servers"));
187 // Create a bunch of objects in one context
188 // Note: strings to the naming service must be char, not wchar
191 // Bind one context level under root.
192 CosNaming::Name level1
;
194 level1
[0].id
= CORBA::string_dup ("level1_context");
195 CosNaming::NamingContext_var level1_context
;
196 level1_context
= root_context_1
->bind_new_context (level1
);
198 for (i
=0; i
<o_breadth
; i
++)
200 // Instantiate a dummy object and bind it under the new context.
201 My_Test_Object
*impl1
= new My_Test_Object (i
+1);
202 Test_Object_var obj1
= impl1
->_this ();
203 impl1
->_remove_ref ();
207 ACE_OS::sprintf(wide_name
, "obj_%d", i
);
208 level1
[1].id
= CORBA::string_dup (wide_name
);
209 root_context_1
->bind (level1
, obj1
.in ());
211 // See if the newly bound object is available in the
214 CORBA::Object_var obj1_on_replica
=
215 root_context_2
->resolve (level1
);
217 catch (const CosNaming::NamingContext::NotFound
&)
219 ACE_ERROR ((LM_ERROR
,
220 ACE_TEXT("Did not resolve object from replica on first.\n")));
224 CORBA::Object_var obj1_on_replica
=
225 root_context_2
->resolve (level1
);
226 // We did find the object on the replica, but only after a wait.
227 // This would be caused by a race condition to access the variable.
228 ACE_ERROR ((LM_ERROR
,
229 ACE_TEXT("Object appeared after a short wait.\n")));
231 catch (const CosNaming::NamingContext::NotFound
& second_ex
)
233 second_ex
._tao_print_exception ("It really is not there. Failing...\n");
239 catch (const CORBA::Exception
& ex
)
241 ex
._tao_print_exception (ACE_TEXT ("Unable to create a lot of objects"));
245 // Create a deep context tree
248 CosNaming::NamingContext_var next_context
= root_context_1
;
249 for (i
=0; i
<c_depth
; i
++)
251 // Bind level1 context under root.
252 CosNaming::Name deep
;
255 ACE_OS::sprintf(deep_name
, "deep_%d", i
);
256 deep
[0].id
= CORBA::string_dup (deep_name
);
257 CosNaming::NamingContext_var deep_context
;
258 deep_context
= next_context
->bind_new_context (deep
);
259 next_context
= deep_context
;
262 catch (const CORBA::Exception
& ex
)
264 ex
._tao_print_exception (ACE_TEXT ("Unable to create deep context"));
268 // Create a wide context tree
271 for (i
=0; i
<c_breadth
; i
++)
273 // Bind all level of context under root.
274 CosNaming::Name wide
;
277 ACE_OS::sprintf(wide_name
, "wide_%d", i
);
278 wide
[0].id
= CORBA::string_dup (wide_name
);
279 CosNaming::NamingContext_var wide_context
;
280 wide_context
= root_context_1
->bind_new_context (wide
);
283 // Check if the new context is available in the replica
284 CORBA::Object_var obj1_on_replica
=
285 root_context_2
->resolve (wide
);
286 // Make sure it is a context
287 CosNaming::NamingContext_var nc
=
288 CosNaming::NamingContext::_narrow (obj1_on_replica
.in ());
290 catch (const CosNaming::NamingContext::NotFound
&)
292 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT("Unable to resolve wide context object from replica.\n")));
294 // Try again to see if it just was a race condition
296 CORBA::Object_var obj1_on_replica
=
297 root_context_2
->resolve (wide
);
298 // We did find the object on the replica, but only after a wait.
299 // This would be caused by a race condition to access the variable.
300 ACE_DEBUG ((LM_DEBUG
,
301 ACE_TEXT("Object appeared after a short wait.\n")));
303 catch (const CosNaming::NamingContext::NotFound
& second_ex
)
305 second_ex
._tao_print_exception (ACE_TEXT ("It really is not there. Failing...\n"));
311 catch (const CORBA::Exception
& ex
)
313 ex
._tao_print_exception (ACE_TEXT ("Unable to create wide context"));
317 // Delete three selected things, one from each tree
319 // Remove the second to last object from the Naming Context
320 CosNaming::Name wide1
;
322 wide1
[0].id
= CORBA::string_dup ("level1_context");
324 ACE_OS::sprintf(wide_name
, "obj_%d", o_breadth
-2);
325 wide1
[1].id
= CORBA::string_dup (wide_name
);
326 root_context_1
->unbind (wide1
);
328 bool retried
= false;
329 // Make sure it is gone from the replica
331 CORBA::Object_var obj1_on_replica
=
332 root_context_2
->resolve (wide1
);
334 // An exception should be thrown by the above or
335 // there is an error. This means the replica did
336 // not register the loss of the context.
337 ACE_ERROR ((LM_ERROR
,
338 "Unbound deep context not removed from replica. Trying again...\n"));
339 retried
= true; // Mark this so it can be reported in catch block.
341 root_context_2
->resolve (wide1
);
342 ACE_ERROR_RETURN ((LM_ERROR
,
343 "Unbound context not removed from on retry\n"),
346 catch (const CosNaming::NamingContext::NotFound
&)
348 // Not on replica --- as it should be.
349 if (retried
) // Was found on the retry
350 ACE_ERROR ((LM_ERROR
,
351 "Was removed after short wait.\n"));
354 // Remove the second to last context from the wide root Naming Context
355 CosNaming::Name wide2
;
357 ACE_OS::sprintf(wide_name
, "wide_%d", c_breadth
-2);
358 wide2
[0].id
= CORBA::string_dup (wide_name
);
359 CORBA::Object_var result_obj_ref
= root_context_1
->resolve (wide2
);
360 CosNaming::NamingContext_var result_object
=
361 CosNaming::NamingContext::_narrow (result_obj_ref
.in ());
362 if (CORBA::is_nil (result_object
.in ()))
363 ACE_ERROR_RETURN ((LM_ERROR
,
364 ACE_TEXT ("Problems with resolving wide context ")
365 ACE_TEXT ("- nil object ref.\n")),
367 result_object
->destroy();
368 root_context_1
->unbind (wide2
);
370 // Remove the last context from the deep Naming Context
371 CosNaming::Name deep
;
372 deep
.length (c_depth
);
374 for (i
=0; i
<c_depth
; i
++)
376 ACE_OS::sprintf(deep_name
, "deep_%d", i
);
377 deep
[i
].id
= CORBA::string_dup (deep_name
);
379 result_obj_ref
= root_context_1
->resolve (deep
);
381 CosNaming::NamingContext::_narrow (result_obj_ref
.in ());
382 if (CORBA::is_nil (result_object
.in ()))
383 ACE_ERROR_RETURN ((LM_ERROR
,
384 ACE_TEXT ("Problems with resolving deep context ")
385 ACE_TEXT ("- nil object ref.\n")),
387 result_object
->destroy();
388 root_context_1
->unbind (deep
);
391 // Make sure it is gone from the replica
393 CORBA::Object_var obj1_on_replica
=
394 root_context_2
->resolve (deep
);
396 // An exception should be thrown by the above or
397 // there is an error. This means the replica did
398 // not register the loss of the context.
399 ACE_ERROR ((LM_ERROR
,
400 "Unbound deep context not removed from replica. Trying again...\n"));
401 retried
= true; // Mark this so it can be reported in catch block.
403 root_context_2
->resolve (deep
);
404 ACE_ERROR_RETURN ((LM_ERROR
,
405 "Unbound context not removed from on retry\n"),
408 catch (const CosNaming::NamingContext::NotFound
&)
410 // Not on replica --- as it should be.
411 if (retried
) // Was found on the retry
412 ACE_ERROR ((LM_ERROR
,
413 ACE_TEXT("Was removed after short wait.\n")));
416 catch (const CORBA::Exception
& ex
)
418 ex
._tao_print_exception (ACE_TEXT ("Unable to delete objects"));
422 // Now use the other name server to access 3 objects next to the
423 // deleted objects and the 3 deleted objects
426 // Access the last object from the Naming Context
427 CosNaming::Name wide
;
429 wide
[0].id
= CORBA::string_dup ("level1_context");
431 ACE_OS::sprintf(wide_name
, "obj_%d", o_breadth
-1);
432 wide
[1].id
= CORBA::string_dup (wide_name
);
433 CORBA::Object_var result_obj_ref
= root_context_2
->resolve (wide
);
434 Test_Object_var result_object
= Test_Object::_narrow (result_obj_ref
.in ());
435 if (CORBA::is_nil (result_object
.in ()))
436 ACE_ERROR_RETURN ((LM_ERROR
,
437 ACE_TEXT ("Problems with resolving object from ")
438 ACE_TEXT ("redundant server - nil object ref.\n")),
441 catch (const CORBA::Exception
& ex
)
443 ex
._tao_print_exception (ACE_TEXT ("Unable to resolve object from redundant server"));
449 // Access the deleted second to last object from the Naming Context
450 CosNaming::Name wide
;
452 wide
[0].id
= CORBA::string_dup ("level1_context");
454 ACE_OS::sprintf(wide_name
, "obj_%d", o_breadth
-2);
455 wide
[1].id
= CORBA::string_dup (wide_name
);
456 CORBA::Object_var result_obj_ref
= root_context_2
->resolve (wide
);
457 ACE_ERROR_RETURN ((LM_ERROR
,
458 ACE_TEXT ("Problems with resolving object from ")
459 ACE_TEXT ("redundant server - deleted object found.\n")),
462 catch (const CosNaming::NamingContext::NotFound
& ex
)
464 // expect exception since the context was deleted.
465 // Make sure the right exception reason is provided.
466 if (ex
.why
!= CosNaming::NamingContext::missing_node
)
467 ACE_ERROR_RETURN ((LM_ERROR
,
468 ACE_TEXT ("Wrong exception returned during resolve.\n")),
471 catch (const CORBA::Exception
& ex
)
473 ex
._tao_print_exception (ACE_TEXT ("Wrong exception type returned from resolve.\n"));
478 // Access the last context from the wide Naming Context
479 CosNaming::Name wide
;
482 ACE_OS::sprintf(wide_name
, "wide_%d", c_breadth
-1);
483 wide
[0].id
= CORBA::string_dup (wide_name
);
484 CORBA::Object_var result_obj_ref
= root_context_2
->resolve (wide
);
485 CosNaming::NamingContext_var result_object
=
486 CosNaming::NamingContext::_narrow (result_obj_ref
.in ());
487 if (CORBA::is_nil (result_object
.in ()))
488 ACE_ERROR_RETURN ((LM_ERROR
,
489 ACE_TEXT ("Problems with resolving wide context from ")
490 ACE_TEXT ("redundant server - nil object ref.\n")),
493 catch (const CosNaming::NamingContext::NotFound
&)
495 // Expected exception
497 catch (const CORBA::Exception
& ex
)
499 ex
._tao_print_exception (ACE_TEXT ("Unexpected Exception received.\n"));
505 // Access the deleted second to last object from the Naming Context
506 CosNaming::Name wide
;
509 ACE_OS::sprintf(wide_name
, "wide_%d", c_breadth
-2);
510 wide
[0].id
= CORBA::string_dup (wide_name
);
511 CORBA::Object_var result_obj_ref
= root_context_2
->resolve (wide
);
512 ACE_ERROR_RETURN ((LM_ERROR
,
513 ACE_TEXT ("Problems with resolving wide context from ")
514 ACE_TEXT ("redundant server - deleted object found.\n")),
517 catch (const CosNaming::NamingContext::NotFound
&)
519 // Expected exception
521 catch (const CORBA::Exception
& ex
)
523 ex
._tao_print_exception (ACE_TEXT ("Unexpected Exception received.\n"));
529 // Access the deleted last context from the deep Naming Context
530 CosNaming::Name deep
;
531 deep
.length (c_depth
);
533 for (i
=0; i
<c_depth
; i
++)
535 ACE_OS::sprintf(deep_name
, "deep_%d", i
);
536 deep
[i
].id
= CORBA::string_dup (deep_name
);
538 CORBA::Object_var result_obj_ref
= root_context_1
->resolve (deep
);
539 ACE_ERROR_RETURN ((LM_ERROR
,
540 ACE_TEXT ("Problems with resolving deep context from ")
541 ACE_TEXT ("redundant server - deleted object found.\n")),
544 catch (const CosNaming::NamingContext::NotFound
&)
546 // Expected exception
548 catch (const CORBA::Exception
& ex
)
550 ex
._tao_print_exception (
551 ACE_TEXT ("Unexpected Exception received resolving ")
552 ACE_TEXT ("deep cxt from redundant server.\n"));
558 // Access the second to last object from the Naming Context
559 CosNaming::Name deep
;
560 deep
.length (c_depth
-1);
562 for (i
=0; i
<c_depth
-1; i
++)
564 ACE_OS::sprintf(deep_name
, "deep_%d", i
);
565 deep
[i
].id
= CORBA::string_dup (deep_name
);
567 CORBA::Object_var result_obj_ref
= root_context_1
->resolve (deep
);
568 CosNaming::NamingContext_var result_object
=
569 CosNaming::NamingContext::_narrow (result_obj_ref
.in ());
570 if (CORBA::is_nil (result_object
.in ()))
571 ACE_ERROR_RETURN ((LM_ERROR
,
572 ACE_TEXT ("Problems with resolving deep context from ")
573 ACE_TEXT ("redundant server - nil object ref.\n")),
576 catch (const CORBA::Exception
& ex
)
578 ex
._tao_print_exception (
579 ACE_TEXT ("Unable to resolve deep context from redundant server"));
583 // TODO: Cleanup namespace
586 // TODO: Create object groups and bind them. Check the replica.
588 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Redundancy test OK.\n")
589 ACE_TEXT ("Starting performance tests.\n")));
591 // Test performance of binding a bunch of objects in one context
594 // Bind one context level under root.
595 CosNaming::Name level1
;
597 level1
[0].id
= CORBA::string_dup ("perf_context");
598 CosNaming::NamingContext_var perf_context
;
599 perf_context
= root_context_1
->bind_new_context (level1
);
601 // Instantiate a dummy object and bind it under the new context.
602 My_Test_Object
*impl1
= new My_Test_Object (i
+1);
603 Test_Object_var obj1
= impl1
->_this ();
604 impl1
->_remove_ref ();
606 ACE_High_Res_Timer::global_scale_factor_type gsf
=
607 ACE_High_Res_Timer::global_scale_factor ();
609 ACE_hrtime_t start
= ACE_OS::gethrtime ();
611 // Test how long it takes to bind
612 for (i
=0; i
<test_runs
; i
++)
616 ACE_OS::sprintf(wide_name
, "obj_%d", i
);
617 level1
[0].id
= CORBA::string_dup (wide_name
);
618 perf_context
->bind (level1
, obj1
.in ());
621 ACE_hrtime_t elapsed_time
= ACE_OS::gethrtime () - start
;
622 // convert to microseconds
623 ACE_UINT32 usecs
= ACE_UINT32(elapsed_time
/ gsf
);
624 double secs
= usecs
/ 1000000.0;
626 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Bound %i objects in %.2f secs\n"),
629 // Test how long it takes to resolve
630 start
= ACE_OS::gethrtime ();
631 for (i
=0; i
<test_runs
; i
++)
635 ACE_OS::sprintf(wide_name
, "obj_%d", i
);
636 level1
[0].id
= CORBA::string_dup (wide_name
);
637 CORBA::Object_var result_obj_ref
= perf_context
->resolve (level1
);
640 elapsed_time
= ACE_OS::gethrtime () - start
;
641 // convert to microseconds
642 usecs
= ACE_UINT32(elapsed_time
/ gsf
);
643 secs
= ((ACE_INT32
) usecs
) / 1000000.0;
645 ACE_DEBUG ((LM_DEBUG
,
646 ACE_TEXT ("Resolved %i objects in %.2f secs\n"),
649 // Test how long it takes to unbind
650 start
= ACE_OS::gethrtime ();
651 for (i
=0; i
<test_runs
; i
++)
655 ACE_OS::sprintf(wide_name
, "obj_%d", i
);
656 level1
[0].id
= CORBA::string_dup (wide_name
);
657 perf_context
->unbind (level1
);
660 elapsed_time
= ACE_OS::gethrtime () - start
;
661 // convert to microseconds
662 usecs
= ACE_UINT32(elapsed_time
/ gsf
);
663 secs
= ((ACE_INT32
) usecs
) / 1000000.0;
665 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT("Unbound %i objects in %.2f secs\n"),
668 catch (const CORBA::Exception
& ex
)
670 ex
._tao_print_exception (ACE_TEXT ("ERROR: Exception during performance test.\n"));