Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / ACE / tests / Logging_Strategy_Test.cpp
blob700d697dbf22fd41ea88706495582fad7717b10f
2 //=============================================================================
3 /**
4 * @file Logging_Strategy_Test.cpp
6 * This program tests the <ACE_Logging_Strategy> class in various
7 * ways and also illustrates many of the features of the
8 * <ACE_Log_Msg>. The test works as follows:
9 * -Load the inserted arguments;
10 * -Remove existent log_files with the file_name specified by the
11 * user;
12 * -Generate 1000 messages to create the DEBUG statements to be
13 * stored in the files;
14 * -Counts the created log_files and if it was specified a maximum
15 * number of log_files, compare and verify if they are the same.
16 * -Verify the order of the files with the order argument.
18 * When Dlls are used, we utilize the dynamic service
19 * configuration mechanism to activate the logging strategy. This
20 * is not a must though, and you may activate the logging strategy
21 * as described in the non-DLL section below under DLL
22 * environments as well.
24 * @author Orlando Ribeiro <oribeiro@inescporto.pt>
26 //=============================================================================
29 #include "test_config.h"
30 #include "ace/OS_NS_stdio.h"
31 #include "ace/OS_NS_string.h"
32 #include "ace/OS_NS_unistd.h"
33 #include "ace/OS_NS_sys_stat.h"
34 #include "ace/Auto_Ptr.h"
35 #include "ace/Service_Config.h"
36 #include "ace/Reactor.h"
37 #include "ace/Thread_Manager.h"
39 #if defined (ACE_AS_STATIC_LIBS) || \
40 (!defined (ACE_WIN32) && !defined (ACE_HAS_SVR4_DYNAMIC_LINKING) && \
41 !defined (__hpux))
42 #include "ace/Logging_Strategy.h"
43 #endif
45 #include "ace/Auto_Ptr.cpp"
46 #include "ace/Get_Opt.h"
47 #include "ace/OS_NS_time.h"
49 // Considering UNIX OS to be default. On Win32 platforms, the symbols
50 // are got form the .exe as one cant have .exe and .dll for the same
51 // .cpp. Also, on Win32 platforms one cant use the .obj to obtain
52 // symbols dynamically at runtime.
54 #if defined (ACE_WIN32)
55 # define OBJ_SUFFIX ACE_TEXT (".exe")
56 # define OBJ_PREFIX ACE_TEXT ("")
57 #else
58 # define OBJ_SUFFIX ACE_DLL_SUFFIX
59 # define OBJ_PREFIX "./" ACE_DLL_PREFIX
60 #endif /*ACE_WIN32*/
62 ACE_TCHAR const *
63 cdecl_decoration (ACE_TCHAR const *func_name)
65 #if defined(ACE_NEEDS_DL_UNDERSCORE)
66 static ACE_TCHAR decorated_func_name[10*1024];
67 ACE_OS::snprintf (decorated_func_name, 10*1024, ACE_TEXT ("_%s"), func_name);
68 return decorated_func_name;
69 #else
70 return func_name;
71 #endif /* ACE_NEEDS_DL_UNDERSCORE */
74 // Global variables.
75 static ACE_TCHAR *file_name = 0;
76 static int max_size_files = 0;
77 static int max_num_files = 0;
78 static int interval_time = 0;
79 static bool order_state = false;
80 static int num_files = 0;
81 static bool wipeout_logfile = false;
83 // This adapter function runs the Reactor's event loop in a separate
84 // thread of control.
86 static void *
87 run_reactor (void *)
89 ACE_Reactor::instance ()->owner
90 (ACE_Thread_Manager::instance ()->thr_self ());
91 ACE_Reactor::instance ()->run_reactor_event_loop ();
92 return 0;
95 // Initiate the cycle of messages.
97 static
98 void print_till_death (void)
100 ACE_DEBUG ((LM_DEBUG,
101 "\n-> start generating messages...\n"));
103 for (int i = 0; i < 1000; i++)
105 if (i % 50 == 0)
106 ACE_OS::sleep (1);
108 if (i == 0)
109 ACE_DEBUG ((LM_DEBUG,
110 " (%t) (%D) message\n"));
111 else
112 ACE_DEBUG ((LM_DEBUG,
113 " (%t) %d message\n",
114 i));
117 if (ACE_Reactor::instance ()->end_reactor_event_loop () == -1)
118 ACE_ERROR ((LM_ERROR,
119 "Error ending reactor.\n"));
121 ACE_DEBUG ((LM_DEBUG,
122 "-< generating messages finished \n\n"));
125 // Count the generated files.
127 static void
128 count_files (void)
130 int i = 0;
131 int error = 0;
132 FILE *stream;
133 ACE_TCHAR backup_ct[MAXPATHLEN+1];
134 ACE_DEBUG ((LM_DEBUG,
135 "-> start counting...\n"));
139 if (i == 0)
140 ACE_OS::snprintf (backup_ct, MAXPATHLEN + 1,
141 ACE_TEXT ("%s"),
142 file_name);
143 else
144 ACE_OS::snprintf (backup_ct, MAXPATHLEN + 1,
145 ACE_TEXT ("%s.%d"),
146 file_name,
149 stream = ACE_OS::fopen (backup_ct, ACE_TEXT ("r"));
150 if (stream == 0)
151 error = 1;
152 else
154 i++;
155 ACE_OS::fclose (stream);
159 while (error != 1);
161 num_files = i;
163 if (max_num_files !=0)
165 if (max_num_files != num_files)
166 ACE_DEBUG ((LM_DEBUG,
167 ACE_TEXT ("Creating files...Failed!")
168 ACE_TEXT (" Input value=%d, Checked value=%d"),
169 max_num_files,
170 num_files));
171 else
172 ACE_DEBUG ((LM_DEBUG,
173 ACE_TEXT (" Creating files...OK!")
174 ACE_TEXT (" Input value=%d, Checked value=%d"),
175 max_num_files,
176 num_files));
178 else
179 ACE_DEBUG ((LM_DEBUG,
180 ACE_TEXT (" The number of files generated is: %d"),
181 num_files));
183 ACE_DEBUG ((LM_DEBUG,
184 "\n-< counting finished...\n"));
187 // get the file statistics
189 static time_t
190 get_statistics (ACE_TCHAR *f_name)
192 ACE_stat buf;
194 // Get data associated with "file_name":
195 int result = ACE_OS::stat (f_name, &buf);
197 // Check if statistics are valid:
198 if (result != 0)
199 ACE_OS::perror (ACE_TEXT ("\nProblem getting information"));
200 else
202 // Output some of the statistics:
203 ACE_DEBUG ((LM_DEBUG,
204 ACE_TEXT (" File name : %s\n"),
205 f_name));
206 ACE_DEBUG ((LM_DEBUG,
207 ACE_TEXT (" File size (B): %d\n"),
208 buf.st_size));
210 ACE_DEBUG ((LM_DEBUG,
211 ACE_TEXT (" Time modified : %s\n"),
212 ACE_OS::ctime (&buf.st_mtime)));
215 return buf.st_mtime;
218 // analyse the file order
219 static void
220 order (void)
222 ACE_DEBUG ((LM_DEBUG,
223 ACE_TEXT ("\n-> start testing order...\n")));
225 if (num_files <= 2)
227 if (num_files == 1)
228 get_statistics (file_name);
229 ACE_DEBUG ((LM_DEBUG,
230 ACE_TEXT (" Ordering...OK! - ")
231 ACE_TEXT (" Only %d file (s) was (were) generated"),
232 num_files));
234 else
236 time_t tm_bk_1, tm_bk_2;
237 ACE_TCHAR backup_1[MAXPATHLEN+1];
238 ACE_TCHAR backup_2[MAXPATHLEN+1];
239 ACE_OS::snprintf (backup_1, MAXPATHLEN + 1,
240 ACE_TEXT ("%s.%d"),
241 file_name,
243 ACE_OS::snprintf (backup_2, MAXPATHLEN + 1,
244 ACE_TEXT ("%s.%d"),
245 file_name,
246 num_files - 1);
248 tm_bk_1 = get_statistics (backup_1);
249 tm_bk_2 = get_statistics (backup_2);
251 if (tm_bk_1 > tm_bk_2 && !order_state)
253 ACE_DEBUG ((LM_DEBUG,
254 ACE_TEXT (" %s (newest) ; %s (oldest)\n"),
255 backup_1,
256 backup_2));
257 ACE_DEBUG ((LM_DEBUG,
258 ACE_TEXT (" Ordering...OK!")));
260 else
262 if (tm_bk_1 < tm_bk_2 && order_state)
264 ACE_DEBUG ((LM_DEBUG,
265 ACE_TEXT (" %s (newest);")
266 ACE_TEXT ("%s (oldest)\n"),
267 backup_2,
268 backup_1));
269 ACE_DEBUG ((LM_DEBUG,
270 ACE_TEXT (" Ordering...OK!")));
272 else
273 ACE_DEBUG ((LM_DEBUG,
274 ACE_TEXT (" Ordering...FAILED!")
275 ACE_TEXT ("- The files are disorderly")));
279 ACE_DEBUG ((LM_DEBUG,
280 ACE_TEXT ("\n-< testing order finished...\n\n")));
283 // remove log_files
285 static void
286 remove_files (void)
288 ACE_DEBUG ((LM_DEBUG,
289 ACE_TEXT ("-> removing existent files...\n")));
291 int error = 0;
292 int i = 0;
296 ++i;
297 ACE_TCHAR backup[MAXPATHLEN+1];
298 ACE_OS::snprintf (backup, MAXPATHLEN + 1,
299 ACE_TEXT ("%s.%d"),
300 file_name,
302 if (ACE_OS::unlink (backup) != 0)
303 error = 1;
305 while (error != 1);
307 ACE_DEBUG ((LM_DEBUG,
308 ACE_TEXT ("-< removing existing files...\n\n")));
311 static int
312 parse_args (int argc, ACE_TCHAR *argv[])
314 ACE_DEBUG ((LM_DEBUG,
315 ACE_TEXT ("Specifications:\n")));
316 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("s:i:m:f:N:ow"));
317 int c;
319 while ((c = get_opt ()) != EOF)
321 switch (c)
323 case 's':
324 file_name = get_opt.opt_arg ();
325 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("File name: %s\n"),
326 file_name));
327 break;
328 case 'i':
329 interval_time = ACE_OS::atoi (get_opt.opt_arg ());
331 //FUZZ: disable check_for_lack_ACE_OS
332 ACE_DEBUG ((LM_DEBUG,
333 ACE_TEXT ("Interval time (s): %d\n"),
334 interval_time));
335 //FUZZ: enable check_for_lack_ACE_OS
336 break;
337 case 'm':
338 max_size_files = ACE_OS::atoi (get_opt.opt_arg ());
339 ACE_DEBUG ((LM_DEBUG,
340 ACE_TEXT ("Maximum size (KB): %d\n"),
341 max_size_files));
342 break;
343 case 'f':
344 ACE_DEBUG ((LM_DEBUG,
345 ACE_TEXT ("Modes: %s\n"),
346 get_opt.opt_arg ()));
347 break;
348 case 'N':
349 max_num_files = ACE_OS::atoi (get_opt.opt_arg ());
350 ACE_DEBUG ((LM_DEBUG,
351 ACE_TEXT ("Maximum files number: %d\n"),
352 max_num_files));
353 break;
354 case 'o':
355 ACE_DEBUG ((LM_DEBUG,
356 ACE_TEXT ("Ordering files activated\n")));
357 order_state = true;
358 break;
359 case 'w':
360 ACE_DEBUG ((LM_DEBUG,
361 ACE_TEXT ("Wipeout logfile activated\n")));
362 wipeout_logfile = true;
363 break;
364 default:
365 ACE_ERROR_RETURN
366 ((LM_ERROR,
367 ACE_TEXT ("usage: [-s]<file_name>")
368 ACE_TEXT ("[-i]<sample_interval> ")
369 ACE_TEXT ("[-m]<max_size> [-f]<msg_flags> ")
370 ACE_TEXT ("[-n]<num_files> [-o]\n")
371 ACE_TEXT ("\t-s: Specify the name of the log files.\n")
372 ACE_TEXT ("\t-i: Define the sample interval in secs.\n")
373 ACE_TEXT ("\t-m: Define the max size for the log_files in KB.\n")
374 ACE_TEXT ("\t-f: Indicates the Log_Msg flags.\n")
375 ACE_TEXT ("\t-N: Define the maximum number of log_files.\n")
376 ACE_TEXT ("\t-o: If activated puts the log_files ordered.\n"),
377 ACE_TEXT ("\t-w: If activated cause the logfile to be wiped out,")
378 ACE_TEXT (" both on startup and on reconfigure.\n")),
379 -1);
380 /* NOTREACHED */
381 break;
385 ACE_UNUSED_ARG (wipeout_logfile);
386 return 0;
389 int run_main (int argc, ACE_TCHAR *argv [])
391 ACE_START_TEST (ACE_TEXT ("Logging_Strategy_Test"));
393 ACE_TCHAR *l_argv[4];
395 if (argc > 1)
397 if (parse_args (argc, argv) == -1)
398 ACE_ERROR_RETURN ((LM_ERROR,
399 "Invalid command-line parameters.\n"),
402 else
404 l_argv[0] = (ACE_TCHAR *)ACE_TEXT ("Logging_Strategy_Test");
405 l_argv[1] =
406 (ACE_TCHAR *) ACE_TEXT ("-s")
407 ACE_DEFAULT_TEST_DIR
408 ACE_TEXT ("log/Logging_Strategy_Test")
409 ACE_LOG_FILE_EXT_NAME;
410 l_argv[2] = (ACE_TCHAR *) ACE_TEXT ("-o");
411 l_argv[3] = 0;
413 if (parse_args (3, l_argv) == -1)
414 ACE_ERROR_RETURN ((LM_ERROR,
415 "Invalid command-line parameters.\n"),
417 argv = l_argv;
418 argc = 3;
421 // Remove existing files.
422 remove_files ();
424 // This is necessary only if the provided logfile name is the same
425 // as the default name. If so, nothing will be written as the
426 // previous ofstream is closed only at the end (ACE_END_TEST)
427 ACE_CLOSE_TEST_LOG;
429 // When Dlls are used, we utilize the dynamic service configuration
430 // mechanism to activate the logging strategy. This is not a must
431 // though, and you may activate the logging strategy as described in
432 // the non-DLL section below under DLL environments as well.
434 #if !defined (ACE_AS_STATIC_LIBS) && \
435 (defined (ACE_WIN32) || defined (ACE_HAS_SVR4_DYNAMIC_LINKING) || \
436 defined (__hpux))
438 // Platform support DLLs, and not configured to link statically
439 ACE_TCHAR arg_str[250];
440 ACE_OS::snprintf (arg_str, 250,
441 ACE_TEXT ("dynamic Logger Service_Object ")
442 ACE_TEXT ("*ACE:_make_ACE_Logging_Strategy()")
443 ACE_TEXT ("\""));
445 for (int i = 1; i < argc; i++)
447 ACE_OS::strcat (arg_str, argv[i]);
448 ACE_OS::strcat (arg_str, ACE_TEXT (" "));
451 ACE_OS::strcat (arg_str, ACE_TEXT ("\""));
453 if (ACE_Service_Config::process_directive (arg_str) == -1)
454 ACE_ERROR_RETURN ((LM_ERROR,
455 "Error opening _make_ACE_Log_Strategy.\n"),
457 #else // Platform doesn't support DLLs, or configured to link
458 // statically
459 ACE_Logging_Strategy logging_strategy;
460 unsigned char ls_argc = argc - 1;
461 ACE_Auto_Basic_Ptr<ACE_TCHAR *> ls_argv (new ACE_TCHAR *[ls_argc]);
463 for (unsigned char c = 0; c < ls_argc; c++)
464 (ls_argv.get ())[c] = argv[c+1];
466 if (logging_strategy.init (ls_argc, ls_argv.get ()) == -1)
467 ACE_ERROR_RETURN
468 ((LM_ERROR,
469 "Error initializing the ACE_Logging_Strategy.\n"),
471 #endif /* !ACE_AS_STATIC_LIBS && (ACE_WIN32 ||
472 ACE_HAS_SVR4_DYNAMIC_LINKING || __hpux) */
474 // launch a new Thread
475 if (ACE_Thread_Manager::instance ()->spawn
476 (ACE_THR_FUNC (run_reactor)) == -1)
477 ACE_ERROR_RETURN ((LM_ERROR,
478 "Spawning Reactor.\n"),
481 // Function to print the message
482 print_till_death ();
484 // Counts the generated files
485 count_files ();
487 // Get the file order
488 order ();
490 // Wait for the thread to exit before we exit.
491 ACE_Thread_Manager::instance ()->wait ();
492 ACE_END_TEST;
493 return 0;