Use =default for skeleton copy constructor
[ACE_TAO.git] / ACE / tests / Logging_Strategy_Test.cpp
blob13d22a2ceec6955f09bdfe08c4f0352ffda7dc67
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 //=============================================================================
28 #include "test_config.h"
29 #include "ace/OS_NS_stdio.h"
30 #include "ace/OS_NS_string.h"
31 #include "ace/OS_NS_unistd.h"
32 #include "ace/OS_NS_sys_stat.h"
33 #include <memory>
34 #include "ace/Service_Config.h"
35 #include "ace/Reactor.h"
36 #include "ace/Thread_Manager.h"
38 #if defined (ACE_AS_STATIC_LIBS) || \
39 (!defined (ACE_WIN32) && !defined (ACE_HAS_SVR4_DYNAMIC_LINKING))
40 #include "ace/Logging_Strategy.h"
41 #endif
43 #include "ace/Get_Opt.h"
44 #include "ace/OS_NS_time.h"
46 // Considering UNIX OS to be default. On Win32 platforms, the symbols
47 // are got form the .exe as one cant have .exe and .dll for the same
48 // .cpp. Also, on Win32 platforms one cant use the .obj to obtain
49 // symbols dynamically at runtime.
51 #if defined (ACE_WIN32)
52 # define OBJ_SUFFIX ACE_TEXT (".exe")
53 # define OBJ_PREFIX ACE_TEXT ("")
54 #else
55 # define OBJ_SUFFIX ACE_DLL_SUFFIX
56 # define OBJ_PREFIX "./" ACE_DLL_PREFIX
57 #endif /*ACE_WIN32*/
59 ACE_TCHAR const *
60 cdecl_decoration (ACE_TCHAR const *func_name)
62 #if defined(ACE_NEEDS_DL_UNDERSCORE)
63 static ACE_TCHAR decorated_func_name[10*1024];
64 ACE_OS::snprintf (decorated_func_name, 10*1024, ACE_TEXT ("_%s"), func_name);
65 return decorated_func_name;
66 #else
67 return func_name;
68 #endif /* ACE_NEEDS_DL_UNDERSCORE */
71 // Global variables.
72 static ACE_TCHAR *file_name = 0;
73 static int max_size_files = 0;
74 static int max_num_files = 0;
75 static int interval_time = 0;
76 static bool order_state = false;
77 static int num_files = 0;
78 static bool wipeout_logfile = false;
80 // This adapter function runs the Reactor's event loop in a separate
81 // thread of control.
83 static void *
84 run_reactor (void *)
86 ACE_Reactor::instance ()->owner
87 (ACE_Thread_Manager::instance ()->thr_self ());
88 ACE_Reactor::instance ()->run_reactor_event_loop ();
89 return 0;
92 // Initiate the cycle of messages.
94 static
95 void print_till_death ()
97 ACE_DEBUG ((LM_DEBUG,
98 "\n-> start generating messages...\n"));
100 for (int i = 0; i < 1000; i++)
102 if (i % 50 == 0)
103 ACE_OS::sleep (1);
105 if (i == 0)
106 ACE_DEBUG ((LM_DEBUG,
107 " (%t) (%D) message\n"));
108 else
109 ACE_DEBUG ((LM_DEBUG,
110 " (%t) %d message\n",
111 i));
114 if (ACE_Reactor::instance ()->end_reactor_event_loop () == -1)
115 ACE_ERROR ((LM_ERROR,
116 "Error ending reactor.\n"));
118 ACE_DEBUG ((LM_DEBUG,
119 "-< generating messages finished \n\n"));
122 // Count the generated files.
124 static void
125 count_files ()
127 int i = 0;
128 int error = 0;
129 FILE *stream;
130 ACE_TCHAR backup_ct[MAXPATHLEN+1];
131 ACE_DEBUG ((LM_DEBUG,
132 "-> start counting...\n"));
136 if (i == 0)
137 ACE_OS::snprintf (backup_ct, MAXPATHLEN + 1,
138 ACE_TEXT ("%s"),
139 file_name);
140 else
141 ACE_OS::snprintf (backup_ct, MAXPATHLEN + 1,
142 ACE_TEXT ("%s.%d"),
143 file_name,
146 stream = ACE_OS::fopen (backup_ct, ACE_TEXT ("r"));
147 if (stream == 0)
148 error = 1;
149 else
151 i++;
152 ACE_OS::fclose (stream);
156 while (error != 1);
158 num_files = i;
160 if (max_num_files !=0)
162 if (max_num_files != num_files)
163 ACE_DEBUG ((LM_DEBUG,
164 ACE_TEXT ("Creating files...Failed!")
165 ACE_TEXT (" Input value=%d, Checked value=%d"),
166 max_num_files,
167 num_files));
168 else
169 ACE_DEBUG ((LM_DEBUG,
170 ACE_TEXT (" Creating files...OK!")
171 ACE_TEXT (" Input value=%d, Checked value=%d"),
172 max_num_files,
173 num_files));
175 else
176 ACE_DEBUG ((LM_DEBUG,
177 ACE_TEXT (" The number of files generated is: %d"),
178 num_files));
180 ACE_DEBUG ((LM_DEBUG,
181 "\n-< counting finished...\n"));
184 // get the file statistics
186 static time_t
187 get_statistics (ACE_TCHAR *f_name)
189 ACE_stat buf;
191 // Get data associated with "file_name":
192 int result = ACE_OS::stat (f_name, &buf);
194 // Check if statistics are valid:
195 if (result != 0)
196 ACE_OS::perror (ACE_TEXT ("\nProblem getting information"));
197 else
199 // Output some of the statistics:
200 ACE_DEBUG ((LM_DEBUG,
201 ACE_TEXT (" File name : %s\n"),
202 f_name));
203 ACE_DEBUG ((LM_DEBUG,
204 ACE_TEXT (" File size (B): %d\n"),
205 buf.st_size));
207 ACE_DEBUG ((LM_DEBUG,
208 ACE_TEXT (" Time modified : %s\n"),
209 ACE_OS::ctime (&buf.st_mtime)));
212 return buf.st_mtime;
215 // analyse the file order
216 static void
217 order ()
219 ACE_DEBUG ((LM_DEBUG,
220 ACE_TEXT ("\n-> start testing order...\n")));
222 if (num_files <= 2)
224 if (num_files == 1)
225 get_statistics (file_name);
226 ACE_DEBUG ((LM_DEBUG,
227 ACE_TEXT (" Ordering...OK! - ")
228 ACE_TEXT (" Only %d file (s) was (were) generated"),
229 num_files));
231 else
233 time_t tm_bk_1, tm_bk_2;
234 ACE_TCHAR backup_1[MAXPATHLEN+1];
235 ACE_TCHAR backup_2[MAXPATHLEN+1];
236 ACE_OS::snprintf (backup_1, MAXPATHLEN + 1,
237 ACE_TEXT ("%s.%d"),
238 file_name,
240 ACE_OS::snprintf (backup_2, MAXPATHLEN + 1,
241 ACE_TEXT ("%s.%d"),
242 file_name,
243 num_files - 1);
245 tm_bk_1 = get_statistics (backup_1);
246 tm_bk_2 = get_statistics (backup_2);
248 if (tm_bk_1 > tm_bk_2 && !order_state)
250 ACE_DEBUG ((LM_DEBUG,
251 ACE_TEXT (" %s (newest) ; %s (oldest)\n"),
252 backup_1,
253 backup_2));
254 ACE_DEBUG ((LM_DEBUG,
255 ACE_TEXT (" Ordering...OK!")));
257 else
259 if (tm_bk_1 < tm_bk_2 && order_state)
261 ACE_DEBUG ((LM_DEBUG,
262 ACE_TEXT (" %s (newest);")
263 ACE_TEXT ("%s (oldest)\n"),
264 backup_2,
265 backup_1));
266 ACE_DEBUG ((LM_DEBUG,
267 ACE_TEXT (" Ordering...OK!")));
269 else
270 ACE_DEBUG ((LM_DEBUG,
271 ACE_TEXT (" Ordering...FAILED!")
272 ACE_TEXT ("- The files are disorderly")));
276 ACE_DEBUG ((LM_DEBUG,
277 ACE_TEXT ("\n-< testing order finished...\n\n")));
280 // remove log_files
282 static void
283 remove_files ()
285 ACE_DEBUG ((LM_DEBUG,
286 ACE_TEXT ("-> removing existent files...\n")));
288 int error = 0;
289 int i = 0;
293 ++i;
294 ACE_TCHAR backup[MAXPATHLEN+1];
295 ACE_OS::snprintf (backup, MAXPATHLEN + 1,
296 ACE_TEXT ("%s.%d"),
297 file_name,
299 if (ACE_OS::unlink (backup) != 0)
300 error = 1;
302 while (error != 1);
304 ACE_DEBUG ((LM_DEBUG,
305 ACE_TEXT ("-< removing existing files...\n\n")));
308 static int
309 parse_args (int argc, ACE_TCHAR *argv[])
311 ACE_DEBUG ((LM_DEBUG,
312 ACE_TEXT ("Specifications:\n")));
313 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("s:i:m:f:N:ow"));
314 int c;
316 while ((c = get_opt ()) != EOF)
318 switch (c)
320 case 's':
321 file_name = get_opt.opt_arg ();
322 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("File name: %s\n"),
323 file_name));
324 break;
325 case 'i':
326 interval_time = ACE_OS::atoi (get_opt.opt_arg ());
328 //FUZZ: disable check_for_lack_ACE_OS
329 ACE_DEBUG ((LM_DEBUG,
330 ACE_TEXT ("Interval time (s): %d\n"),
331 interval_time));
332 //FUZZ: enable check_for_lack_ACE_OS
333 break;
334 case 'm':
335 max_size_files = ACE_OS::atoi (get_opt.opt_arg ());
336 ACE_DEBUG ((LM_DEBUG,
337 ACE_TEXT ("Maximum size (KB): %d\n"),
338 max_size_files));
339 break;
340 case 'f':
341 ACE_DEBUG ((LM_DEBUG,
342 ACE_TEXT ("Modes: %s\n"),
343 get_opt.opt_arg ()));
344 break;
345 case 'N':
346 max_num_files = ACE_OS::atoi (get_opt.opt_arg ());
347 ACE_DEBUG ((LM_DEBUG,
348 ACE_TEXT ("Maximum files number: %d\n"),
349 max_num_files));
350 break;
351 case 'o':
352 ACE_DEBUG ((LM_DEBUG,
353 ACE_TEXT ("Ordering files activated\n")));
354 order_state = true;
355 break;
356 case 'w':
357 ACE_DEBUG ((LM_DEBUG,
358 ACE_TEXT ("Wipeout logfile activated\n")));
359 wipeout_logfile = true;
360 break;
361 default:
362 ACE_ERROR_RETURN
363 ((LM_ERROR,
364 ACE_TEXT ("usage: [-s]<file_name>")
365 ACE_TEXT ("[-i]<sample_interval> ")
366 ACE_TEXT ("[-m]<max_size> [-f]<msg_flags> ")
367 ACE_TEXT ("[-n]<num_files> [-o]\n")
368 ACE_TEXT ("\t-s: Specify the name of the log files.\n")
369 ACE_TEXT ("\t-i: Define the sample interval in secs.\n")
370 ACE_TEXT ("\t-m: Define the max size for the log_files in KB.\n")
371 ACE_TEXT ("\t-f: Indicates the Log_Msg flags.\n")
372 ACE_TEXT ("\t-N: Define the maximum number of log_files.\n")
373 ACE_TEXT ("\t-o: If activated puts the log_files ordered.\n"),
374 ACE_TEXT ("\t-w: If activated cause the logfile to be wiped out,")
375 ACE_TEXT (" both on startup and on reconfigure.\n")),
376 -1);
377 /* NOTREACHED */
378 break;
382 ACE_UNUSED_ARG (wipeout_logfile);
383 return 0;
386 int run_main (int argc, ACE_TCHAR *argv [])
388 ACE_START_TEST (ACE_TEXT ("Logging_Strategy_Test"));
390 ACE_TCHAR *l_argv[4];
392 if (argc > 1)
394 if (parse_args (argc, argv) == -1)
395 ACE_ERROR_RETURN ((LM_ERROR,
396 "Invalid command-line parameters.\n"),
399 else
401 l_argv[0] = (ACE_TCHAR *)ACE_TEXT ("Logging_Strategy_Test");
402 l_argv[1] =
403 (ACE_TCHAR *) ACE_TEXT ("-s")
404 ACE_DEFAULT_TEST_DIR
405 ACE_TEXT ("log/Logging_Strategy_Test")
406 ACE_LOG_FILE_EXT_NAME;
407 l_argv[2] = (ACE_TCHAR *) ACE_TEXT ("-o");
408 l_argv[3] = 0;
410 if (parse_args (3, l_argv) == -1)
411 ACE_ERROR_RETURN ((LM_ERROR,
412 "Invalid command-line parameters.\n"),
414 argv = l_argv;
415 argc = 3;
418 // Remove existing files.
419 remove_files ();
421 // This is necessary only if the provided logfile name is the same
422 // as the default name. If so, nothing will be written as the
423 // previous ofstream is closed only at the end (ACE_END_TEST)
424 ACE_CLOSE_TEST_LOG;
426 // When Dlls are used, we utilize the dynamic service configuration
427 // mechanism to activate the logging strategy. This is not a must
428 // though, and you may activate the logging strategy as described in
429 // the non-DLL section below under DLL environments as well.
431 #if !defined (ACE_AS_STATIC_LIBS) && (defined (ACE_WIN32) || defined (ACE_HAS_SVR4_DYNAMIC_LINKING))
433 // Platform support DLLs, and not configured to link statically
434 ACE_TCHAR arg_str[250];
435 ACE_OS::snprintf (arg_str, 250,
436 ACE_TEXT ("dynamic Logger Service_Object ")
437 ACE_TEXT ("*ACE:_make_ACE_Logging_Strategy()")
438 ACE_TEXT ("\""));
440 for (int i = 1; i < argc; i++)
442 ACE_OS::strcat (arg_str, argv[i]);
443 ACE_OS::strcat (arg_str, ACE_TEXT (" "));
446 ACE_OS::strcat (arg_str, ACE_TEXT ("\""));
448 if (ACE_Service_Config::process_directive (arg_str) == -1)
449 ACE_ERROR_RETURN ((LM_ERROR,
450 "Error opening _make_ACE_Log_Strategy.\n"),
452 #else // Platform doesn't support DLLs, or configured to link
453 // statically
454 ACE_Logging_Strategy logging_strategy;
455 unsigned char ls_argc = argc - 1;
456 std::unique_ptr<ACE_TCHAR *> ls_argv (new ACE_TCHAR *[ls_argc]);
458 for (unsigned char c = 0; c < ls_argc; c++)
459 (ls_argv.get ())[c] = argv[c+1];
461 if (logging_strategy.init (ls_argc, ls_argv.get ()) == -1)
462 ACE_ERROR_RETURN
463 ((LM_ERROR,
464 "Error initializing the ACE_Logging_Strategy.\n"),
466 #endif /* !ACE_AS_STATIC_LIBS && (ACE_WIN32 ACE_HAS_SVR4_DYNAMIC_LINKING) */
468 // launch a new Thread
469 if (ACE_Thread_Manager::instance ()->spawn
470 (ACE_THR_FUNC (run_reactor)) == -1)
471 ACE_ERROR_RETURN ((LM_ERROR,
472 "Spawning Reactor.\n"),
475 // Function to print the message
476 print_till_death ();
478 // Counts the generated files
479 count_files ();
481 // Get the file order
482 order ();
484 // Wait for the thread to exit before we exit.
485 ACE_Thread_Manager::instance ()->wait ();
486 ACE_END_TEST;
487 return 0;