1 // -*- c++ -*-
2 // Generated by assa-genesis
3 //------------------------------------------------------------------------------
4 // $Id: inifile_test.cpp,v 1.11 2006/07/20 02:30:56 vlg Exp $
5 //------------------------------------------------------------------------------
6 //                            IniFile_Test.cpp
7 //------------------------------------------------------------------------------
8 //  Copyright (c) 2003,2005 by Vladislav Grinchenko
9 //
10 //  This program is free software; you can redistribute it and/or
11 //  modify it under the terms of the GNU General Public License
12 //  as published by the Free Software Foundation; either version
13 //  2 of the License, or (at your option) any later version.
14 //------------------------------------------------------------------------------
15 //
16 // Date   : Sat Sep  6 22:10:05 2003
17 //
18 //------------------------------------------------------------------------------
19 
20 static const char help_msg[]=
21 "                                                                            \n"
22 " NAME:                                                                      \n"
23 "                                                                            \n"
24 "   inifile_test                                                             \n"
25 "                                                                            \n"
26 " DESCRIPTION:                                                               \n"
27 "                                                                            \n"
28 "   Driver for IniFile class. Tests IniFile class interface.                 \n"
29 "                                                                            \n"
30 " USAGE:                                                                     \n"
31 "                                                                            \n"
32 "   shell>  inifile_test [OPTIONS]                                           \n"
33 "                                                                            \n"
34 " OPTIONS:                                                                   \n"
35 "                                                                            \n"
36 " -D, --log-file NAME     - Write debug to NAME file                         \n"
37 " -d, --log-stdout        - Write debug to standard output                   \n"
38 " -z, --log-size NUM      - Maximum size debug file can reach (dfl: is 10Mb) \n"
39 "                                                                            \n"
40 " -c, --log-level NUM     - Log verbosity                                    \n"
41 " -s, --with-log-server   - Redirect log messages to the log server          \n"
42 " -S, --log-server NAME   - Define assa-logd server address                  \n"
43 " -m, --mask MASK         - Mask (default: ALL = 0x7fffffff)                 \n"
44 "                                                                            \n"
45 " -h, --help              - Print this messag                                \n"
46 " -v, --version           - Print version number                            \n";
47 //------------------------------------------------------------------------------
48 
49 #include <fstream>
50 #include <iostream>
51 
52 #ifdef HAVE_CONFIG_H
53 #    include "config.h"
54 #endif
55 #include <string>
56 using std::string;
57 
58 #include <assa/Assure.h>
59 #include <assa/GenServer.h>
60 #include <assa/Singleton.h>
61 #include <assa/IniFile.h>
62 using ASSA::IniFile;
63 
64 enum { TEST = ASSA::USR1 };
65 
66 /* Perform double-logging: to the file and STDOUT
67  */
log_status(const std::string & m_)68 void log_status (const std::string& m_)
69 {
70     std::cout << m_ << std::flush;
71     DL((TEST," %s", m_.c_str ()));
72 }
73 
74 //------------------------------------------------------------------------------
75 class IniFile_Test :
76     public ASSA::GenServer,
77     public ASSA::Singleton<IniFile_Test>
78 {
79 public:
80     IniFile_Test ();
81     ~IniFile_Test ();
82 
83     virtual void init_service ();
84     virtual void process_events ();
85 
86 private:
87 	int run_test_one   ();
88 	int run_test_two   ();
89 	int run_test_three ();
90 	int run_test_four  ();
91 	int run_test_five  ();
92 
93 private:
94 	string m_test_fname;
95 	IniFile m_ini_file;
96 };
97 //------------------------------------------------------------------------------
98 /* Useful definitions */
99 
100 #define INIFILE_TEST  IniFile_Test::get_instance()
101 #define REACTOR INIFILE_TEST->get_reactor()
102 
103 // Static declarations mandated by Singleton class
104 ASSA_DECL_SINGLETON(IniFile_Test);
105 
106 //------------------------------------------------------------------------------
107 IniFile_Test::
IniFile_Test()108 IniFile_Test () :
109 	m_test_fname ("test-inifile.conf"),
110 	m_ini_file (m_test_fname)
111 {
112     // ---Configuration---
113     rm_opt ('f', "config-file"  );
114     rm_opt ('n', "instance"     );
115     rm_opt ('p', "port"         );
116 
117     // ---Process bookkeeping---
118     rm_opt ('b', "daemon"       );
119     rm_opt ('l', "pidfile"      );
120     rm_opt ('L', "ommit-pidfile");
121 
122     /*---
123      * By defauil disable all debugging
124      *---*/
125     // m_debug_mask = ASSA::APP | ASSA::ASSAERR;
126     m_log_file = "IniFile_Test.log";
127 
128 	// Enable if you want to see internal messages
129     m_mask = TEST | ASSA::INIFILE | ASSA::ASSAERR;
130 }
131 
132 IniFile_Test::
~IniFile_Test()133 ~IniFile_Test ()
134 {
135 	if (get_exit_value () == 0) {
136 		::unlink (m_test_fname.c_str ());
137 	}
138 }
139 
140 void
141 IniFile_Test::
init_service()142 init_service ()
143 {
144     trace("IniFile_Test::init_service");
145 
146 	std::ofstream test_file;
147 
148 	test_file.open (m_test_fname.c_str (), std::ios::out);
149 
150 	if (!test_file) {
151 		set_exit_value (1);
152 		stop_service ();
153 		return;
154 	}
155 
156 	test_file << "# This is the input test file for \n"
157 			  << "# inifile_test driver\n"
158 			  << "#\n"
159 			  << "\n"
160 			  << "[options]  \n"
161 			  << "gtk_options = --g-fatal-warnings --disable-crash-dialog  \n"
162 			  << "wavjoin_options=\n"
163 			  << "log_file=gwm.log\n"
164 			  << "  log_size  = 0\n"
165 			  << "\tmask =  \t 0x0\n"
166 			  << "log_stdout=false\n"
167 			  << "\n"
168 			  << "[History] \n"
169 			  << "0=/Segment25/Segment25.gwm\n"
170 			  << "1=/Segment26/Segment26.gwm\n"
171 			  << "2=/Segment27/Segment27.gwm\n"
172 			  << "\n"
173 			  << "[Default]\n"
174 			  << "jump=true\n"
175 			  << "\n";
176 
177 	test_file.close ();
178 }
179 
180 void
181 IniFile_Test::
process_events()182 process_events ()
183 {
184 	if (!service_is_active ()) {
185 		goto failed;
186     }
187 
188 	log_status ("= Running inifile_test Test =\n");
189 
190 	if (run_test_one () < 0) {
191 		goto failed;
192 	}
193 
194 	if (run_test_two () < 0) {
195 		goto failed;
196 	}
197 
198 	if (run_test_three () < 0) {
199 		goto failed;
200 	}
201 
202 	if (run_test_four () < 0) {
203 		goto failed;
204 	}
205 
206 	if (run_test_five () < 0) {
207 		goto failed;
208 	}
209 
210 	log_status ("inifile_test Passed\n");
211 	m_reactor.stopReactor ();
212 	return;
213 
214  failed:
215 	log_status ("inifile_test Failed!\n");
216 	set_exit_value (1);
217     m_reactor.stopReactor ();
218 }
219 
220 /*
221   Load configuration file that was generated by init_service().
222   Save configuration in cache to inifile01.conf.
223   Reload it into another IniFile object, test01, and compare.
224 */
225 int
226 IniFile_Test::
run_test_one()227 run_test_one ()
228 {
229 	std::string alt_fname = "inifile01.conf";
230 	std::string err;
231 
232 	log_status ("Testing load() ... ");
233 
234 	if (m_ini_file.load () < 0) {
235 		err = " failed to load(\"" + m_test_fname + "\" file ...!\n";
236 		log_status (err);
237 		return -1;
238 
239 	}
240 	m_ini_file.dump ();
241 	log_status ("ok\n");
242 
243 	log_status ("Testing sync(file) ... ");
244 	if (m_ini_file.sync (alt_fname) < 0) {
245 		err = " failed to sync(\"" + alt_fname + "\") file ...!\n";
246 		log_status (err);
247 		return -1;
248 	}
249 
250 	IniFile test01 (alt_fname);
251 	if (test01.load () < 0) {
252 		err = " failed to re-load(\"" + alt_fname + "\") !\n";
253 		log_status (err);
254 		return -1;
255 	}
256 
257 	if (test01 != m_ini_file) {
258 		err = " failed to sync(\"" + alt_fname + "\") !\n";
259 		log_status (err);
260 		return -1;
261 	}
262 
263 	log_status ("ok\n");
264 	return 0;
265 }
266 
267 /*
268   Check for expected values.
269   Check for non-existing value.
270 */
271 int
272 IniFile_Test::
run_test_two()273 run_test_two ()
274 {
275 	log_status ("Testing get_value() ... ");
276 
277 	if (m_ini_file.get_value ("options", "log_file") != "gwm.log") {
278 		log_status (" failed to get_value(\"options\", \"log_file\")\n");
279 		return -1;
280 	}
281 
282 	if (m_ini_file.get_value ("History", "2") != "/Segment27/Segment27.gwm") {
283 		log_status (" failed to get_value(\"options\", \"log_file\")\n");
284 		return -1;
285 	}
286 
287 	if (m_ini_file.get_value ("Bogus", "Not an option") == "failure") {
288 		log_status (" get_value(\"Bogus\", \"Not an option\") succeeded\n");
289 		return -1;
290 	}
291 
292 	log_status ("ok\n");
293 	return 0;
294 }
295 
296 /**
297    Add new section and test to see if it was added.
298    Fill up newly created section with values and test
299    to see if they were added.
300 */
301 
302 int
303 IniFile_Test::
run_test_three()304 run_test_three ()
305 {
306 	log_status ("Testing add_section() / set_pair() ... ");
307 
308 	m_ini_file.add_section ("Interface");
309 
310 	if (m_ini_file.find_section ("Interface") == m_ini_file.sect_end ()) {
311 		log_status (" failed to find_section (\"Interface\") ...!\n");
312 		return -1;
313 
314 	}
315 
316 	if (m_ini_file.set_pair ("Interface",
317 							 IniFile::tuple_type ("zoom", "true")) < 0)
318 	{
319 		log_status (" failed to set_pair(\"Interface\","
320 					"(\"zoom\",\"true\"))!\n");
321 		return -1;
322 	}
323 
324 	if (m_ini_file.set_pair ("Interface",
325 							 IniFile::tuple_type ("profile", "default")) < 0)
326 	{
327 		log_status (" failed to set_pair(\"Interface\", "
328 					"(\"profile\",\"default\"))!\n");
329 		return -1;
330 	}
331 
332 	if (m_ini_file.get_value ("Interface", "zoom") != "true") {
333 		log_status (" failed to get_value (\"Interface\", \"zoom\") ...!\n");
334 		return -1;
335 	}
336 
337 	if (m_ini_file.get_value ("Interface", "profile") != "default") {
338 		log_status (" failed to get_value (\"Interface\", \"profile\")!\n");
339 		return -1;
340 	}
341 
342 	log_status ("ok\n");
343 	return 0;
344 }
345 
346 /**
347    Traverse through the list of sections and print out section names.
348    Traverse through a section and print out its name/value pairs.
349 */
350 int
351 IniFile_Test::
run_test_four()352 run_test_four ()
353 {
354 	log_status ("Testing iteration through list of sections  ...\n");
355 
356 	int count = 0;
357 	std::ostringstream msg;
358 
359 	IniFile::const_config_iterator i = m_ini_file.sect_begin ();
360 
361 	while (i != m_ini_file.sect_end ()) {
362 		msg << "    " << (*i).first.c_str () << "\n";
363 		log_status (msg.str ().c_str ());
364 		i++, count++;
365 		msg.str (string ()), msg.clear ();
366 	}
367 	msg.str (string ()), msg.clear ();
368 
369 	if (count != m_ini_file.size ()) {
370 		msg << " failed! # of sections " << count << " != "
371 			<< m_ini_file.size () << "\n" << std::ends;
372 		log_status (msg.str ().c_str ());
373 		return -1;
374 	}
375 	msg.str (string ()), msg.clear ();
376 
377 	log_status ("ok\n");
378 
379 	log_status ("Testing iteration through a section  ...\n");
380 	count = 0;
381 	IniFile::const_config_iterator j = m_ini_file.find_section ("History");
382 
383 	if (j != m_ini_file.sect_end ()) {
384 		IniFile::const_tuple_iterator k = (*j).second.begin ();
385 		while (k != (*j).second.end ()) {
386 			msg << "    " << (*k).first.c_str () << "=" << (*k).second.c_str ()
387 				<< "\n";
388 			log_status (msg.str ());
389 			k++, count++;
390 			msg.str (string ()), msg.clear ();
391 		}
392 	}
393 	msg.str (string ()), msg.clear ();
394 
395 	if (count != 3) {
396 		msg << " failed! # of name/value pairs " << count << " != 3\n";
397 		log_status (msg.str ());
398 		return -1;
399 	}
400 	log_status ("ok\n");
401 
402 	return 0;
403 }
404 
405 /**
406 	Remove section and test that it has been deleted.
407 	Clean up the entire configuration cache.
408 */
409 int
410 IniFile_Test::
run_test_five()411 run_test_five ()
412 {
413 
414 	log_status ("Testing drop_pair() ... ");
415 
416 	if (m_ini_file.drop_pair ("Interface", "profile") < 0) {
417 		log_status (" failed to drop_pair (\"Interface\", \"profile\")!\n");
418 		return -1;
419 	}
420 	if (m_ini_file.get_value ("Interface", "profile") != "") {
421 		log_status (" failed to get_value (\"Interface\",\"profile\")!\n");
422 		return -1;
423 	}
424 	log_status ("ok\n");
425 
426 	log_status ("Testing drop_section() ... ");
427 	if (m_ini_file.drop_section ("Interface") < 0) {
428 		log_status (" failed to drop_section (\"Interface\")!\n");
429 		return -1;
430 	}
431 	if (m_ini_file.find_section ("Interface") != m_ini_file.sect_end ()) {
432 		log_status (" failed to remove \"Interface\" section!\n");
433 		return -1;
434 	}
435 	log_status ("ok\n");
436 
437 	log_status ("Testing drop_all() ... ");
438 	m_ini_file.drop_all ();
439 	if (m_ini_file.size () != 0) {
440 		log_status (" failed to drop_all() !\n");
441 		return -1;
442 	}
443 	log_status ("ok\n");
444 
445 	return 0;
446 }
447 
448 int
main(int argc,char * argv[])449 main (int argc, char* argv[])
450 {
451     static const char release[] = "1.0";
452     int patch_level = 0;
453 
454     INIFILE_TEST->set_version (release, patch_level);
455     INIFILE_TEST->set_author  ("Vladislav Grinchenko");
456     INIFILE_TEST->set_flags   (ASSA::GenServer::RMLOG);
457 
458     INIFILE_TEST->init (&argc, argv, help_msg);
459 
460     INIFILE_TEST->init_service ();
461     INIFILE_TEST->process_events ();
462 
463     return INIFILE_TEST->get_exit_value ();
464 }
465 
466 
467