Merge pull request #2303 from jwillemsen/jwi-803
[ACE_TAO.git] / TAO / orbsvcs / tests / Redundant_Naming / client.cpp
blob959933e9d5c090b7ab3e13afe5cc7c92d9e46b25
1 // ============================================================================
2 //
3 // = DESCRIPTION
4 // This class implements a CORBA client for a redundant CosNaming
5 // Service using stubs generated by the TAO ORB IDL compiler.
6 //
7 // = AUTHORS
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)
21 #endif /* _MSC_VER */
23 class My_Test_Object :
24 public virtual POA_Test_Object
26 public:
27 My_Test_Object (CORBA::Short id = 0);
28 // Constructor.
30 ~My_Test_Object ();
31 // Destructor.
33 // = Interface implementation accessor methods.
35 void id (CORBA::Short id);
36 // Sets id.
38 CORBA::Short id ();
39 // Gets id.
41 private:
42 short id_;
45 My_Test_Object::My_Test_Object (CORBA::Short id)
46 : id_ (id)
50 My_Test_Object::~My_Test_Object ()
54 CORBA::Short
55 My_Test_Object::id ()
57 return id_;
60 void
61 My_Test_Object::id (CORBA::Short id)
63 id_ = id;
67 // This function runs the test.
69 int
70 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
72 int c_breath = 4;
73 int c_depth = 4;
74 int o_breath = 4;
75 ACE_TCHAR *ns1ref = 0;
76 ACE_TCHAR *ns2ref = 0;
78 ACE_Get_Opt get_opts (argc, argv, ACE_TEXT ("b:d:o:p:q:"));
79 int c;
80 int i;
82 while ((c = get_opts ()) != -1)
83 switch (c)
85 case 'b':
86 i = ACE_OS::atoi(get_opts.opt_arg ());
87 if (i<2)
89 ACE_ERROR((LM_ERROR,
90 ACE_TEXT ("Invalid breath, must be 2 or more\n")));
91 ACE_OS::exit(1);
93 c_breath = i;
94 break;
95 case 'd':
96 i = ACE_OS::atoi(get_opts.opt_arg ());
97 if (i<2)
99 ACE_ERROR((LM_ERROR,
100 ACE_TEXT ("Invalid depth, must be 2 or more\n")));
101 ACE_OS::exit(1);
103 c_depth = i;
104 break;
105 case 'o':
106 i = ACE_OS::atoi(get_opts.opt_arg ());
107 if (i<2)
109 ACE_ERROR((LM_ERROR,
110 ACE_TEXT ("Invalid breath, must be 2 or more\n")));
111 ACE_OS::exit(1);
113 o_breath = i;
114 break;
115 case 'p':
116 ns1ref = get_opts.opt_arg ();
117 break;
118 case 'q':
119 ns2ref = get_opts.opt_arg ();
120 break;
121 default:
122 ACE_ERROR_RETURN ((LM_ERROR,
123 ACE_TEXT ("Argument %c \n usage: %s")
124 ACE_TEXT (" [-b <breath of context tree>]")
125 ACE_TEXT (" [-d <depth of context tree>]")
126 ACE_TEXT (" [-o <breath of object tree>]")
127 ACE_TEXT (" -p <ior of first name server>")
128 ACE_TEXT (" -q <ior of second name server>")
129 ACE_TEXT ("\n")),
130 -1);
133 CosNaming::NamingContext_var root_context_1;
134 CosNaming::NamingContext_var root_context_2;
138 // Initialize orb
139 CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
141 // ior's are specified for the name servers through a commandline
142 // option or a file.
144 // Resolve the first name server
146 CORBA::Object_var ns1obj = orb->string_to_object (
147 ACE_TEXT_ALWAYS_CHAR (ns1ref));
149 if (CORBA::is_nil (ns1obj.in ()))
150 ACE_ERROR_RETURN ((LM_ERROR,
151 ACE_TEXT ("invalid ior <%s>\n"),
152 ns1ref),
153 -1);
154 root_context_1 = CosNaming::NamingContext::_narrow (ns1obj.in ());
156 // Resolve the second name server
158 CORBA::Object_var ns2obj = orb->string_to_object (
159 ACE_TEXT_ALWAYS_CHAR (ns2ref));
161 if (CORBA::is_nil (ns2obj.in ()))
162 ACE_ERROR_RETURN ((LM_ERROR,
163 ACE_TEXT ("invalid ior <%s>\n"),
164 ns2ref),
165 -1);
166 root_context_2 = CosNaming::NamingContext::_narrow (ns2obj.in ());
168 catch (const CORBA::Exception& ex)
170 ex._tao_print_exception (ACE_TEXT ("Unable to resolve name servers"));
171 return -1;
174 // Create a bunch of objects in one context
175 // Note: strings to the naming service must be char, not wchar
178 // Bind one context level under root.
179 CosNaming::Name level1;
180 level1.length (1);
181 level1[0].id = CORBA::string_dup ("level1_context");
182 CosNaming::NamingContext_var level1_context;
183 level1_context = root_context_1->bind_new_context (level1);
185 for (i=0; i<o_breath; i++)
187 // Instantiate a dummy object and bind it under the new context.
188 My_Test_Object *impl1 = new My_Test_Object (i+1);
189 Test_Object_var obj1 = impl1->_this ();
190 impl1->_remove_ref ();
192 level1.length (2);
193 char wide_name[16];
194 ACE_OS::sprintf(wide_name, "obj_%d", i);
195 level1[1].id = CORBA::string_dup (wide_name);
196 root_context_1->bind (level1, obj1.in ());
200 catch (const CORBA::Exception& ex)
202 ex._tao_print_exception (ACE_TEXT ("Unable to create a lot of objects"));
203 return -1;
206 // Create a deep context tree
209 CosNaming::NamingContext_var next_context = root_context_1;
210 for (i=0; i<c_depth; i++)
212 // Bind level1 context under root.
213 CosNaming::Name deep;
214 deep.length (1);
215 char deep_name[16];
216 ACE_OS::sprintf(deep_name, "deep_%d", i);
217 deep[0].id = CORBA::string_dup (deep_name);
218 CosNaming::NamingContext_var deep_context;
219 deep_context = next_context->bind_new_context (deep);
220 next_context = deep_context;
223 catch (const CORBA::Exception& ex)
225 ex._tao_print_exception (ACE_TEXT ("Unable to create deep context"));
226 return -1;
229 // Create a wide context tree
232 for (i=0; i<c_breath; i++)
234 // Bind all level of context under root.
235 CosNaming::Name wide;
236 wide.length (1);
237 char wide_name[16];
238 ACE_OS::sprintf(wide_name, "wide_%d", i);
239 wide[0].id = CORBA::string_dup (wide_name);
240 CosNaming::NamingContext_var wide_context;
241 wide_context = root_context_1->bind_new_context (wide);
244 catch (const CORBA::Exception& ex)
246 ex._tao_print_exception (ACE_TEXT ("Unable to create wide context"));
247 return -1;
250 // Delete three selected things, one from each tree
253 // Remove the second to last object from the Naming Context
254 CosNaming::Name wide1;
255 wide1.length (2);
256 wide1[0].id = CORBA::string_dup ("level1_context");
257 char wide_name[16];
258 ACE_OS::sprintf(wide_name, "obj_%d", o_breath-2);
259 wide1[1].id = CORBA::string_dup (wide_name);
260 root_context_1->unbind (wide1);
262 // Remove the second to last context from the wide root Naming Context
263 CosNaming::Name wide2;
264 wide2.length (1);
265 ACE_OS::sprintf(wide_name, "wide_%d", c_breath-2);
266 wide2[0].id = CORBA::string_dup (wide_name);
267 CORBA::Object_var result_obj_ref = root_context_1->resolve (wide2);
268 CosNaming::NamingContext_var result_object =
269 CosNaming::NamingContext::_narrow (result_obj_ref.in ());
270 if (CORBA::is_nil (result_object.in ()))
271 ACE_ERROR_RETURN ((LM_ERROR,
272 ACE_TEXT ("Problems with resolving wide context ")
273 ACE_TEXT ("- nil object ref.\n")),
274 -1);
275 result_object->destroy();
276 root_context_1->unbind (wide2);
278 // Remove the last context from the deep Naming Context
279 CosNaming::Name deep;
280 deep.length (c_depth);
281 char deep_name[16];
282 for (i=0; i<c_depth; i++)
284 ACE_OS::sprintf(deep_name, "deep_%d", i);
285 deep[i].id = CORBA::string_dup (deep_name);
287 result_obj_ref = root_context_1->resolve (deep);
288 result_object =
289 CosNaming::NamingContext::_narrow (result_obj_ref.in ());
290 if (CORBA::is_nil (result_object.in ()))
291 ACE_ERROR_RETURN ((LM_ERROR,
292 ACE_TEXT ("Problems with resolving deep context ")
293 ACE_TEXT ("- nil object ref.\n")),
294 -1);
295 result_object->destroy();
296 root_context_1->unbind (deep);
298 catch (const CORBA::Exception& ex)
300 ex._tao_print_exception (ACE_TEXT ("Unable to delete objects"));
301 return -1;
304 // Now use the other name server to access 3 objects next to the
305 // deleted objects and the 3 deleted objects
308 // Access the last object from the Naming Context
309 CosNaming::Name wide;
310 wide.length (2);
311 wide[0].id = CORBA::string_dup ("level1_context");
312 char wide_name[16];
313 ACE_OS::sprintf(wide_name, "obj_%d", o_breath-1);
314 wide[1].id = CORBA::string_dup (wide_name);
315 CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
316 Test_Object_var result_object = Test_Object::_narrow (result_obj_ref.in ());
317 if (CORBA::is_nil (result_object.in ()))
318 ACE_ERROR_RETURN ((LM_ERROR,
319 ACE_TEXT ("Problems with resolving object from ")
320 ACE_TEXT ("redundant server - nil object ref.\n")),
321 -1);
323 catch (const CORBA::Exception& ex)
325 ex._tao_print_exception (
326 ACE_TEXT (
327 "Unable to resolve object from redundant server"));
328 return -1;
333 // Access the deleted second to last object from the Naming Context
334 CosNaming::Name wide;
335 wide.length (2);
336 wide[0].id = CORBA::string_dup ("level1_context");
337 char wide_name[16];
338 ACE_OS::sprintf(wide_name, "obj_%d", o_breath-2);
339 wide[1].id = CORBA::string_dup (wide_name);
340 CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
341 ACE_ERROR_RETURN ((LM_ERROR,
342 ACE_TEXT ("Problems with resolving object from ")
343 ACE_TEXT ("redundant server - deleted object found.\n")),
344 -1);
346 catch (const CORBA::Exception&)
348 //expect exception since the context was deleted
353 // Access the last context from the wide Naming Context
354 CosNaming::Name wide;
355 wide.length (1);
356 char wide_name[16];
357 ACE_OS::sprintf(wide_name, "wide_%d", c_breath-1);
358 wide[0].id = CORBA::string_dup (wide_name);
359 CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
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 from ")
365 ACE_TEXT ("redundant server - nil object ref.\n")),
366 -1);
368 catch (const CORBA::Exception& ex)
370 ex._tao_print_exception (
371 ACE_TEXT (
372 "Unable to resolve wide context from redundant server"));
373 return -1;
378 // Access the deleted second to last object from the Naming Context
379 CosNaming::Name wide;
380 wide.length (2);
381 char wide_name[16];
382 ACE_OS::sprintf(wide_name, "wide_%d", c_breath-2);
383 wide[0].id = CORBA::string_dup (wide_name);
384 CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
385 ACE_ERROR_RETURN ((LM_ERROR,
386 ACE_TEXT ("Problems with resolving wide context from ")
387 ACE_TEXT ("redundant server - deleted object found.\n")),
388 -1);
390 catch (const CORBA::Exception&)
392 //expect exception since the context was deleted
397 // Access the deleted last context from the deep Naming Context
398 CosNaming::Name deep;
399 deep.length (c_depth);
400 char deep_name[16];
401 for (i=0; i<c_depth; i++)
403 ACE_OS::sprintf(deep_name, "deep_%d", i);
404 deep[i].id = CORBA::string_dup (deep_name);
406 CORBA::Object_var result_obj_ref = root_context_1->resolve (deep);
407 ACE_ERROR_RETURN ((LM_ERROR,
408 ACE_TEXT ("Problems with resolving deep context from ")
409 ACE_TEXT ("redundant server - deleted object found.\n")),
410 -1);
412 catch (const CORBA::Exception&)
414 //expect exception since the context was deleted
419 // Access the second to last object from the Naming Context
420 CosNaming::Name deep;
421 deep.length (c_depth-1);
422 char deep_name[16];
423 for (i=0; i<c_depth-1; i++)
425 ACE_OS::sprintf(deep_name, "deep_%d", i);
426 deep[i].id = CORBA::string_dup (deep_name);
428 CORBA::Object_var result_obj_ref = root_context_1->resolve (deep);
429 CosNaming::NamingContext_var result_object =
430 CosNaming::NamingContext::_narrow (result_obj_ref.in ());
431 if (CORBA::is_nil (result_object.in ()))
432 ACE_ERROR_RETURN ((LM_ERROR,
433 ACE_TEXT ("Problems with resolving deep context from ")
434 ACE_TEXT ("redundant server - nil object ref.\n")),
435 -1);
437 catch (const CORBA::Exception& ex)
439 ex._tao_print_exception (
440 ACE_TEXT (
441 "Unable to resolve deep context from redundant server"));
442 return -1;
445 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Redundancy test OK\n")));
447 // Test performance of binding a bunch of objects in one context
450 // Bind one context level under root.
451 CosNaming::Name level1;
452 level1.length (1);
453 level1[0].id = CORBA::string_dup ("perf_context");
454 CosNaming::NamingContext_var perf_context;
455 perf_context = root_context_1->bind_new_context (level1);
457 // Instantiate a dummy object and bind it under the new context.
458 My_Test_Object *impl1 = new My_Test_Object (i+1);
459 Test_Object_var obj1 = impl1->_this ();
460 impl1->_remove_ref ();
462 int test_runs = 100;
463 ACE_High_Res_Timer::global_scale_factor_type gsf =
464 ACE_High_Res_Timer::global_scale_factor ();
466 ACE_hrtime_t start = ACE_OS::gethrtime ();
468 // Test how long it takes to bind
469 for (i=0; i<test_runs; i++)
471 level1.length (1);
472 char wide_name[16];
473 ACE_OS::sprintf(wide_name, "obj_%d", i);
474 level1[0].id = CORBA::string_dup (wide_name);
475 perf_context->bind (level1, obj1.in ());
478 ACE_hrtime_t elapsed_time = ACE_OS::gethrtime () - start;
479 // convert to microseconds
480 ACE_UINT32 usecs = ACE_UINT32(elapsed_time / gsf);
481 double secs = usecs / 1000000.0;
483 ACE_DEBUG ((LM_DEBUG,
484 "Bound %i objects in %.2f secs\n",
485 test_runs, secs));
487 // Test how long it takes to resolve
488 start = ACE_OS::gethrtime ();
489 for (i=0; i<test_runs; i++)
491 level1.length (1);
492 char wide_name[16];
493 ACE_OS::sprintf(wide_name, "obj_%d", i);
494 level1[0].id = CORBA::string_dup (wide_name);
495 CORBA::Object_var result_obj_ref = perf_context->resolve (level1);
498 elapsed_time = ACE_OS::gethrtime () - start;
499 // convert to microseconds
500 usecs = ACE_UINT32(elapsed_time / gsf);
501 secs = ((ACE_INT32) usecs) / 1000000.0;
503 ACE_DEBUG ((LM_DEBUG,
504 "Resolved %i objects in %.2f secs\n",
505 test_runs, secs));
507 // Test how long it takes to unbind
508 start = ACE_OS::gethrtime ();
509 for (i=0; i<test_runs; i++)
511 level1.length (1);
512 char wide_name[16];
513 ACE_OS::sprintf(wide_name, "obj_%d", i);
514 level1[0].id = CORBA::string_dup (wide_name);
515 perf_context->unbind (level1);
518 elapsed_time = ACE_OS::gethrtime () - start;
519 // convert to microseconds
520 usecs = ACE_UINT32(elapsed_time / gsf);
521 secs = ((ACE_INT32) usecs) / 1000000.0;
523 ACE_DEBUG ((LM_DEBUG,
524 "Unbound %i objects in %.2f secs\n",
525 test_runs, secs));
527 catch (const CORBA::Exception& ex)
529 ex._tao_print_exception (ACE_TEXT ("ERROR: Exception during performance test.\n"));
530 return -1;
533 // All tests have passed up to this point
534 return 0;