diff options
author | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:30 +0000 |
---|---|---|
committer | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:30 +0000 |
commit | 7a52d43a162b23d9e85e7b955e9b2c8e9caf550e (patch) | |
tree | 66a84b20d47f2269d8bdc6e0323f338763424d3a /ACE/tests/Config_Test.cpp | |
parent | 0e49389337be86641451a5c36c24bf742fe97523 (diff) | |
download | ATCD-7a52d43a162b23d9e85e7b955e9b2c8e9caf550e.tar.gz |
Repo restructuring
Diffstat (limited to 'ACE/tests/Config_Test.cpp')
-rw-r--r-- | ACE/tests/Config_Test.cpp | 1514 |
1 files changed, 1514 insertions, 0 deletions
diff --git a/ACE/tests/Config_Test.cpp b/ACE/tests/Config_Test.cpp new file mode 100644 index 00000000000..01bc3bf97bf --- /dev/null +++ b/ACE/tests/Config_Test.cpp @@ -0,0 +1,1514 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Config_Test.cpp +// +// = DESCRIPTION +// This is a test that makes sure various classes in +// <ACE_Configuration> work correctly. +// +// = AUTHOR +// Michael Searles <msearles@base16.com>, +// Chris Hafey <chafey@stentor.com>, and +// Jerry D. Odenwelder Jr. <jerry.o@mindspring.com> +// +// ============================================================================ + +#include "test_config.h" +#include "Config_Test.h" +#include "ace/Configuration_Import_Export.h" +#include "ace/OS_NS_ctype.h" +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(tests, Config_Test, "$Id$") + +static int +test (ACE_Configuration *config, + ACE_Configuration_Section_Key &testsection) +{ + ACE_TString stvalue; + + // Set some values. + if (config->set_string_value (testsection, + ACE_TEXT ("stvalue"), + ACE_TEXT ("stvaluetest"))) + return -3; + + else if (config->remove_value (testsection, + ACE_TEXT ("stvalue"))) + return -4; + // Make sure it's really gone + else if (0 == config->get_string_value (testsection, + ACE_TEXT ("stvalue"), + stvalue)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("test:remove_value didn't remove\n")), + -4); + + else if (config->set_string_value (testsection, + ACE_TEXT ("stvalue"), + ACE_TEXT ("stvaluetest"))) + return -3; + else if (config->set_string_value (testsection, + ACE_TEXT ("stvalue"), + ACE_TEXT ("second stvaluetest"))) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("test:set_string_value twice failed\n")), + -3); + + else if (config->set_integer_value (testsection, + ACE_TEXT ("intvalue"), + 77)) + return -4; + // Reset to the value we test for below + else if (config->set_integer_value (testsection, + ACE_TEXT ("intvalue"), + 42)) + return -4; + + u_char data[80]; + + for (int i = 0; i < 80; i++) + data[i] = i + 128; + + if (config->set_binary_value (testsection, + ACE_TEXT ("binvalue"), + data, + 80)) + return -5; + + // Get the values and compare + if (config->get_string_value (testsection, + ACE_TEXT ("stvalue"), + stvalue)) + return -6; + else if (stvalue != ACE_TEXT ("second stvaluetest")) + return -7; + + u_int intvalue; + + if (config->get_integer_value (testsection, + ACE_TEXT ("intvalue"), + intvalue)) + return -8; + else if (intvalue != 42) + return -9; + + u_char *data_out = 0; + size_t length = 0; + + if (config->get_binary_value (testsection, + ACE_TEXT ("binvalue"), + (void*&) data_out, + length)) + return -10; + + // compare em + for (int j = 0; j < 80; j++) + if (data_out[j] != data[j]) + return -11; + + delete [] data_out; + + // Test iteration. + ACE_TString name; + ACE_Configuration::VALUETYPE type; + u_int index = 0; + int found[3] = { 0, 0, 0 }; // One for each expected value + + while (!config->enumerate_values (testsection, + index, + name, + type)) + { + if (name == ACE_TEXT ("stvalue")) + { + if (type != ACE_Configuration::STRING) + return -12; + if (found[0] != 0) + return -12; + found[0] = 1; + } + else if (name == ACE_TEXT ("intvalue")) + { + if (type != ACE_Configuration::INTEGER) + return -13; + if (found[1] != 0) + return -13; + found[1] = 1; + } + else if (name == ACE_TEXT ("binvalue")) + { + if (type != ACE_Configuration::BINARY) + return -14; + if (found[2] != 0) + return -14; + found[2] = 1; + } + index++; + } + + // Make sure we got three values. + if (index != 3 || !found[0] || !found[1] || !found[2]) + return -15; + + { + // Add some subsections. This part is a separate scope to be sure + // the test2, test3, test4 keys are closed before further + // manipulating/deleting the sections further down in the test. + ACE_Configuration_Section_Key test2; + ACE_Configuration_Section_Key test3; + ACE_Configuration_Section_Key test4; + + if (config->open_section (testsection, + ACE_TEXT ("test2"), + 1, + test2)) + return -16; + else if (config->open_section (testsection, + ACE_TEXT ("test3"), + 1, + test3)) + return -17; + else if (config->open_section (testsection, + ACE_TEXT ("test4"), + 1, + test4)) + return -18; + } + + // Test enumerate sections. + index = 0; + found[0] = found[1] = found[2] = 0; + while (!config->enumerate_sections (testsection, + index, + name)) + { + if (name == ACE_TEXT ("test2")) + { + if (found[0] != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("enumerate_sections, dupl test2\n")), + -19); + found[0] = 1; + } + else if (name == ACE_TEXT ("test3")) + { + if (found[1] != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("enumerate_sections, dupl test3\n")), + -19); + found[1] = 1; + } + else if (name == ACE_TEXT ("test4")) + { + if (found[2] != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("enumerate_sections, dupl test4\n")), + -19); + found[2] = 1; + } + index++; + } + + if (index != 3 || !found[0] || !found[1] || !found[2]) + return -19; + + // Remove a subsection + if (config->remove_section (testsection, + ACE_TEXT ("test2"), + 0)) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p (%d)\n"), + ACE_TEXT ("remove_section test2"), + ACE_OS::last_error ()), + -20); + + // Try to remove it again + if (!config->remove_section (testsection, + ACE_TEXT ("test2"), + 0)) + return -21; + + return 0; +} + +static int +test (ACE_Configuration *config) +{ + const ACE_Configuration_Section_Key& root = + config->root_section (); + + { + // Scope this so the testsection key is closed before trying to + // remove the "test" section. + ACE_Configuration_Section_Key testsection; + + if (config->open_section (root, + ACE_TEXT ("test"), + 1, + testsection)) + return -2; + + int ret_val = test (config, testsection); + if (ret_val) + return ret_val; + } + + // Try to remove the testsection root, it should fail since it still + // has subkeys + if (!config->remove_section (root, + ACE_TEXT ("test"), + 0)) + return -22; + + { + // Test find section, and be sure the key is closed before testing the + // remove, below. + ACE_Configuration_Section_Key result; + + if (config->open_section (root, + ACE_TEXT ("test"), + 0, + result)) + return -23; + } + + // Now test the recursive remove. + if (config->remove_section (root, + ACE_TEXT ("test"), + 1)) + return -24; + + // Make sure its not there + ACE_Configuration_Section_Key testsectiongone; + if (!config->open_section (root, + ACE_TEXT ("test"), + 0, + testsectiongone)) + return -25; + + return 0; +} + +static int +test_subkey_path (ACE_Configuration* config) +{ + ACE_Configuration_Section_Key root = + config->root_section (); + + ACE_Configuration_Section_Key testsection; + + if (config->open_section (root, + ACE_TEXT ("Software\\ACE\\test"), + 1, + testsection)) + return -26; + + int ret_val = test (config, testsection); + if (ret_val) + return ret_val; + + if (config->open_section (root, + ACE_TEXT ("Software"), + 0, + testsection)) + return -27; + + if (config->remove_section (testsection, + ACE_TEXT ("ACE"), + 1)) + return -28; + + return 0; +} + +static int +run_tests (void) +{ + int status; + + { + // Test import of a legit INI format from a previously-existing file. + ACE_Configuration_Heap cf; + if ((status = cf.open ()) != 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_Configuration_Heap::open returned %d\n"), + status)); + ACE_Ini_ImpExp import (cf); + // This one should work... + status = import.import_config (ACE_TEXT ("Config_Test_Import_1.ini")); + if (status != 0) { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Config_Test_Import_1.ini failed"))); + } + else { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Config_Test_Import_1.ini imported\n"))); + + // Imported clean; verify content. See ini file for expected content. + // Verify the expected sections are there, but no others. Verify the + // expected keys are there, but no others. + int section1_seen = 0, section2_seen = 0; + int somekey_seen = 0, someotherkey_seen = 0; + int index; + ACE_TString sect_name; + const ACE_Configuration_Section_Key &root = cf.root_section (); + for (index = 0; + (status = cf.enumerate_sections (root, index, sect_name)) == 0; + ++index) { + if (index > 1) // There are only two sections. + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Enumerated %d sections; expected 2\n"), + index + 1)); + else { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Enumerated to section %s\n"), + sect_name.c_str ())); + if (sect_name == ACE_TEXT ("SectionOne")) { + if (section1_seen) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Saw %s multiple times!\n"), + sect_name.c_str ())); + section1_seen = 1; + // Check for values in this section. + ACE_Configuration_Section_Key sect1; + if (cf.open_section (root, sect_name.c_str (), 0, sect1) != 0) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Failed to open section: %s\n"), + sect_name.c_str ())); + else { + int val_index = 0, val_status; + ACE_TString val_name, value; + ACE_Configuration::VALUETYPE val_type; + while ((val_status = + cf.enumerate_values + (sect1, val_index, val_name, val_type)) == 0) { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Enumerated %s, type %d\n"), + val_name.c_str (), + val_type)); + if (val_type != ACE_Configuration::STRING) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Expected %s to be STRING, but %d\n"), + val_name.c_str (), + val_type)); + if (val_name == ACE_TEXT ("SomeKey")) { + if (somekey_seen) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Saw %s more than once\n"), + val_name.c_str ())); + somekey_seen = 1; + } + else + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Unexpected key %s\n"), + val_name.c_str ())); + if ((val_status = cf.get_string_value + (sect1, val_name.c_str (), value)) != 0) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Can't get value of %s\n"), + val_name.c_str ())); + else { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s value: %s\n"), + val_name.c_str (), value.c_str ())); + if (value != ACE_TEXT ("SomeValue")) { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("SomeKey: %s; expected SomeValue\n"))); + } + } + ++val_index; + } + if (val_status == 1) { + if (val_index != 1) // Should have only seen 1 + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Expected 1 value; saw %d\n"), + index)); + } + else + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Error enumerating %s; status %d\n"), + sect_name.c_str (), val_status)); + } + } + else if (sect_name == ACE_TEXT ("SectionTwo")) { + if (section2_seen) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Saw %s multiple times!\n"), + sect_name.c_str ())); + section2_seen = 1; + // Check for values in this section. + ACE_Configuration_Section_Key sect2; + if (cf.open_section (root, sect_name.c_str (), 0, sect2) != 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Failed to open section: %s\n"), + sect_name.c_str ())); + else { + int val_index = 0, val_status; + ACE_TString val_name, value; + ACE_Configuration::VALUETYPE val_type; + while ((val_status = cf.enumerate_values + (sect2, val_index, val_name, val_type)) == 0) { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Enumerated %s, type %d\n"), + val_name.c_str (), + val_type)); + if (val_type != ACE_Configuration::STRING) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Expected %s to be STRING, but %d\n"), + val_name.c_str (), val_type)); + if (val_name == ACE_TEXT ("SomeOtherKey")) { + if (someotherkey_seen) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Saw %s more than once\n"), + val_name.c_str ())); + someotherkey_seen = 1; + } + else + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Unexpected key %s\n"), + val_name.c_str ())); + if ((val_status = cf.get_string_value + (sect2, val_name.c_str (), value)) != 0) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Can't get value of %s\n"), + val_name.c_str ())); + else { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s value: %s\n"), + val_name.c_str (), value.c_str ())); + if (value != ACE_TEXT ("SomeOtherValue")) { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("SomeOtherKey: %s; expected SomeOtherValue\n"))); + } + } + ++val_index; + } + if (val_status == 1) { + if (val_index != 1) // Should have only seen 1 + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Expected 1 value; saw %d\n"), + index)); + } + else + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Error enumerating %s; status %d\n"), + sect_name.c_str (), val_status)); + } + } + else { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Saw unexpected section: %s\n"), + sect_name.c_str ())); + } + } + } + if (status == 1) { // Ran out of sections + if (index != 2) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Saw %d sections; expected 2\n"), + index)); + } + else + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Error enumerating sections; status %d\n"), + status)); + } + } + +#if defined (ACE_WIN32) + { + ACE_Configuration_Win32Registry RegConfig (HKEY_LOCAL_MACHINE); + int result = test_subkey_path (&RegConfig); + if (result) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Win32Registry test HKEY_LOCAL_MACHINE") + ACE_TEXT (" failed (%d)\n"), result), + -1); + } + // test win32 registry implementation. + HKEY root = + ACE_Configuration_Win32Registry::resolve_key (HKEY_LOCAL_MACHINE, + ACE_TEXT ("Software\\ACE\\test")); + if (!root) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("resolve_key is broken\n")), -2); + + // test resolving of forward slashes + HKEY root_fs = + ACE_Configuration_Win32Registry::resolve_key (HKEY_LOCAL_MACHINE, + ACE_TEXT ("Software/ACE/test"), 0); + if (!root_fs) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("resolve_key resolving slashes is broken\n")), + -2); + + ACE_Configuration_Win32Registry RegConfig (root); + { + int result = test (&RegConfig); + if (result) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Win32 registry test root failed (%d)\n"), + result), + -1); + } + +#endif /* ACE_WIN32 */ + // Test Heap version + ACE_Configuration_Heap heap_config; + + if (heap_config.open ()) + return 0; + { + int result = test_subkey_path (&heap_config); + if (result) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Heap Config subkey test failed (%d)\n"), + result), + -1); + } + + { + int result = test (&heap_config); + if (result) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Heap Configuration test failed (%d)\n"), + result), + -1); + } + + // Test persistent heap version + ACE_OS::unlink (ACE_TEXT ("test.reg")); + ACE_Configuration_Heap pers_config; + + if (pers_config.open (ACE_TEXT ("test.reg"))) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Cannot open test.reg\n")), + -1); + + { + int result = test (&pers_config); + if (result) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Persistent Heap Config test failed (%d)\n"), + result), + -1); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Test passed\n"))); + return 0; +} + +static int +build_config_object (ACE_Configuration& cfg) +{ + ACE_Configuration_Section_Key root = cfg.root_section (); + ACE_Configuration_Section_Key NetworkSection; + ACE_Configuration_Section_Key LoggerSection; + ACE_Configuration_Section_Key BinarySection; + + if (cfg.open_section (root, + ACE_TEXT ("network"), + 1, + NetworkSection)) + return -1; + + if (cfg.set_integer_value (NetworkSection, + ACE_TEXT ("TimeToLive"), + 100)) + return -2; + else if (cfg.set_string_value (NetworkSection, + ACE_TEXT ("Delay"), + ACE_TString (ACE_TEXT ("FALSE")))) + return -3; + else if (cfg.set_string_value (NetworkSection, + ACE_TEXT ("DestIPAddress"), + ACE_TString (ACE_TEXT ("localhost")))) + return -4; + else if (cfg.set_integer_value (NetworkSection, + ACE_TEXT ("DestPort"), + 12670)) + return -5; + else if (cfg.set_integer_value (NetworkSection, + ACE_TEXT ("ReconnectInterval"), + 3)) + return -6; + + if (cfg.open_section (root, + ACE_TEXT ("logger"), + 1, + LoggerSection)) + return -7; + + if (cfg.set_string_value (LoggerSection, + ACE_TEXT ("Heading"), + ACE_TString (ACE_TEXT ("ACE - Adaptive Communication Environment")))) + return -8; + else if (cfg.set_integer_value (LoggerSection, + ACE_TEXT ("SeekIndex"), + 14)) + return -9; + else if (cfg.set_integer_value (LoggerSection, + ACE_TEXT ("TraceLevel"), + 6)) + return -10; + else if (cfg.set_string_value (LoggerSection, + ACE_TEXT ("Justification"), + ACE_TString (ACE_TEXT ("left_justified")))) + return -11; + else if (cfg.set_string_value (LoggerSection, + ACE_TEXT ("LogFilePath"), + ACE_TString (ACE_TEXT ("log/")))) + return -12; + else if (cfg.set_string_value (LoggerSection, + ACE_TEXT ("TransactionFilePath"), + ACE_TString (ACE_TEXT ("data/")))) + return -13; + + if (cfg.open_section (root, + ACE_TEXT ("binary"), + 1, + BinarySection)) + return -14; + + u_char data[80]; + + for (int i = 0; i < 80; i++) + data[i] = i + 128; + + if (cfg.set_binary_value (BinarySection, + ACE_TEXT ("data"), + data, + 80)) + return -15; + + ACE_TString string((ACE_TCHAR*) 0);// = '0'; + // Try to set the unnamed, default value. + if (cfg.set_string_value (LoggerSection, + 0,//string.c_str (),//0, //ACE_TEXT ("x"), + ACE_TString (ACE_TEXT ("some string")))) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("could not set value with null name\n")), + -16); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("here\n"))); + //return 0; + //ACE_TString string; + ACE_TString name ((ACE_TCHAR*)0); + if (cfg.get_string_value (LoggerSection, + name.c_str (), //0, //ACE_TEXT ("x"), + string)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("error using ACE_TString::c_str() == %d, len == %d\n"), + name.c_str(), name.length ()), + -17); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("the value for the unnamed var=(%s)\n"), + string.c_str ())); + + return 0; +} + +/* + * Test ACE_Configuration::operator== + */ +int +Config_Test::testEquality () +{ + // create and open 2 ACE_Configuration objects. + ACE_Configuration_Heap heap1; + ACE_Configuration_Heap heap2; + if ((heap1.open ()) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Cannot open heap1\n")), + -1); + + } + else if ((heap2.open ()) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Cannot open heap2\n")), + -1); + } + + // populate them equally + if (build_config_object (heap1) != 0 || + build_config_object (heap2) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("could not build config object\n")), + -1); + + // test equality + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("The objects should equal...\n"))); + if (heap1 == heap2) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("And they do ;-)\n"))); + } + else + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("And they do not :-(\n") + ACE_TEXT ("operator== Failed when objects equal\n")), + -1); + } + + // add a section and value to heap1 + ACE_Configuration_Section_Key root1 = heap1.root_section (); + ACE_Configuration_Section_Key NewSection; + if (heap1.open_section (root1, + ACE_TEXT ("NewSection"), + 1, + NewSection)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error adding section to heap1\n")), + -1); + else if (heap1.set_integer_value (NewSection, + ACE_TEXT ("TestIntValue"), + 100)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error adding value to heap1\n")), + -2); + + // test equality + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("The objects should NOT equal...\n"))); + if (heap1 == heap2) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("They Do :-(\noperator== Failed ") + ACE_TEXT ("when lhs contains data not in rhs\n")), + -1); + else + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("And they do not ;-)\n"))); + + // + // add same section to heap2 + // + ACE_Configuration_Section_Key root2 = heap2.root_section (); + ACE_Configuration_Section_Key NewSection2; + if (heap2.open_section (root2, + ACE_TEXT ("NewSection"), + 1, + NewSection2)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error adding section to heap2\n")), + -1); + else if (heap2.set_integer_value (NewSection2, + ACE_TEXT ("TestIntValue"), + 100)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error adding value to heap2\n")), + -2); + else if (heap2.set_integer_value (NewSection2, + ACE_TEXT ("TestIntValue2"), + 100)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error adding second value to heap2\n")), + -2); + + // test equality + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("The objects should NOT equal...\n"))); + if (heap1 == heap2) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("And They Do :-(\noperator== Failed ") + ACE_TEXT ("when rhs contains value not in lhs\n")), + -1); + else + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("And they do not ;-)\n"))); + + // add new value in heap 1 + if (heap1.set_integer_value (NewSection, + ACE_TEXT ("TestIntValue2"), + 100)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error adding second value to heap1\n")), + -2); + + // test equality + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("The objects should be equal...\n"))); + if (heap1 == heap2) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("And they are ;-)\n"))); + else + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("And they are not :-(\n") + ACE_TEXT ("operator== Failed\n")), + -1); + + // Add a new section to heap2 + ACE_Configuration_Section_Key AnotherNewSection2; + if (heap2.open_section (root2, + ACE_TEXT ("AnotherNewSection"), + 1, + AnotherNewSection2)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error adding second section to heap2\n")), + -1); + else if (heap2.set_integer_value (AnotherNewSection2, + ACE_TEXT ("TestIntValue"), + 100)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error adding value in second section") + ACE_TEXT (" to heap2\n")), + -2); + + // test equality + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("The objects should NOT equal...\n"))); + if (heap1 == heap2) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("And they do :-(\noperator== Failed ") + ACE_TEXT ("when rhs contains data not in lhs\n")), + -1); + else + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("And they do not :-)\n"))); + + // add section back to heap1 + ACE_Configuration_Section_Key AnotherNewSection1; + if (heap1.open_section (root1, + ACE_TEXT ("AnotherNewSection"), + 1, + AnotherNewSection1)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error adding second section to heap1\n")), + -1); + else if (heap1.set_integer_value (AnotherNewSection1, + ACE_TEXT ("TestIntValue"), + 100)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error adding second value to second ") + ACE_TEXT ("section in heap1\n")), + -2); + + // test equality + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("The objects should be equal...\n"))); + if (heap1 == heap2) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("And they are ;-)\n"))); + else + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("And they are not :-(\n") + ACE_TEXT ("operator== Failed\n")), + -1); + + this->equality_tested_ = 1; + return 0; +} + +/* + * Compare INI import data in fromFile to origional data exported (in origional) + * + * This compare is destructive to the origional object. + * I realize that normally you would not do such an obscene thing but + * this funciton has a special purpose and I know my origional is not needed + * after calling this routine. + * This is done because configuration objects that are imported using the INI + * import store all data as strings. My origional has type information and I need to + * know if the import worked. +*/ +static int +iniCompare (ACE_Configuration_Heap& fromFile, ACE_Configuration_Heap& original) +{ + bool rc = true; // start by guessing they are equal + + int sectionIndex = 0; + ACE_TString sectionName; + + const ACE_Configuration_Section_Key& fromFileRoot = fromFile.root_section (); + const ACE_Configuration_Section_Key& originalRoot = original.root_section (); + ACE_Configuration_Section_Key originalSection; + ACE_Configuration_Section_Key fromFileSection; + + // loop through each section in the fromFile object + while ((rc) && + (!fromFile.enumerate_sections (fromFileRoot, + sectionIndex, + sectionName)) ) + { + // find that section in the original object + if (original.open_section (originalRoot, + sectionName.c_str (), + 0, + originalSection) != 0) + // If the original object does not contain the section then we + // are not equal. + rc = false; + else if (fromFile.open_section (fromFileRoot, + sectionName.c_str (), + 0, + fromFileSection) != 0) + // if there is some error opening the section in the fromFile + rc = false; + else + { + // Well the sections match + int valueIndex = 0; + ACE_TString valueName; + ACE_Configuration::VALUETYPE valueType; + ACE_Configuration::VALUETYPE originalType; + + // Enumerate each value in the fromFile section + while ((rc) && + (!fromFile.enumerate_values (fromFileSection, + valueIndex, + valueName, + valueType))) + { + // look for the same value in the original section + if (original.find_value (originalSection, + valueName.c_str (), + originalType) != 0) + // We're not equal if the same value cannot be found + // in the original object. + rc = false; + else + { + ACE_TString fromFileString, originalString; + + + if (fromFile.get_string_value (fromFileSection, + valueName.c_str (), + fromFileString) != 0) + // we're not equal if we cannot get this string + rc = false; + else if (originalType != ACE_Configuration::STRING) // If the original type is not a string + { + // convert original data to a string. + + if (originalType == ACE_Configuration::INTEGER) + { + u_int intValue; + ACE_TCHAR int_value[32]; + + if (original.get_integer_value (originalSection, + valueName.c_str (), + intValue) != 0) + // we're not equal if we cannot get rhs int + rc = false; + + ACE_OS::sprintf (int_value, ACE_LIB_TEXT ("%08x"), intValue); + originalString = int_value; + } + else if (originalType == ACE_Configuration::BINARY) + { + void* binary_data; + size_t binary_length; + + if (original.get_binary_value (originalSection, + valueName.c_str (), + binary_data, + binary_length)) + // we're not equal if we cannot get this string + rc = false; + else + { + ACE_TCHAR bin_value[3]; + + unsigned char* ptr = (unsigned char*)binary_data; + while (binary_length) + { + if (ptr != binary_data) + originalString += ACE_LIB_TEXT (","); + + ACE_OS::sprintf (bin_value, + ACE_LIB_TEXT ("%02x"), + *ptr); + originalString += bin_value; + --binary_length; + ++ptr; + } + delete [] (char *)binary_data; + }// end successful binary read + }// end if originalType was binary + else + // if the type is invalid, then go ahead and fail it. + rc = false; + + }// end if the original type was not a string. + else + { + if (original.get_string_value (originalSection, + valueName.c_str (), + originalString) != 0) + { + // we're not equal if we cannot get rhs string + rc = false; + } + + } + + rc &= fromFileString == originalString; + + if (rc) + // before we move on remove this value from the original. + original.remove_value (originalSection, + valueName.c_str ()); + + }// end else if values match. + + valueIndex++; + + }// end value while loop + + // at this point the original should have no values. look + // for values in the original section + valueIndex = 0; + while ((rc) && + (!original.enumerate_values (originalSection, + valueIndex, + valueName, + originalType))) + valueIndex++; + + // having a value indicates a mismatch + rc = valueIndex == 0; + + }// end else if sections match. + + if (rc) + // before we move on remove the section from the original. + original.remove_section (originalRoot, + sectionName.c_str (), + 0); // do not remove subsections. + + sectionIndex++; + + }// end section while loop + + // Finally, if the original has any sections, then we're not equal + sectionIndex = 0; + while ((rc) && + (!original.enumerate_sections (originalRoot, + sectionIndex, + sectionName))) + sectionIndex++; + + rc = sectionIndex == 0; + + return rc; +} + +// change a network section value +int Config_Test::change_one (ACE_Configuration &cfg, u_int a) +{ + ACE_Configuration_Section_Key root = cfg.root_section (); + ACE_Configuration_Section_Key NetworkSection; + ACE_Configuration_Section_Key LoggerSection; + ACE_Configuration_Section_Key BinarySection; + + if (cfg.open_section (root, + ACE_TEXT ("network"), + 1, + NetworkSection)) + return -1; + + if (cfg.set_integer_value (NetworkSection, + ACE_TEXT ("TimeToLive"), + a)) + return -2; + + return 0; +} + +// Used to test INI Import Export class + +int +Config_Test::testIniFormat () +{ + int rc = 0; + if (!this->equality_tested_) + { + rc = this->testEquality (); + if (rc != 0) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Equality Test Failed\n"))); + return rc; + } + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing INI Format Import/Export\n"))); + ACE_Configuration_Heap fromFile; + + // 1. Creates an ACE_Configuration_Heap object + ACE_Configuration_Heap original; + + rc = original.open (); + if (rc == 0) + { + rc = build_config_object (original); + // 2. Calls build_config_object to populate + if (rc != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error populating original config ") + ACE_TEXT ("object (%d)\n"), + rc), + -1); + // 3. Export + ACE_Ini_ImpExp importExport (original); + + rc = importExport.export_config (ACE_TEXT ("testConfig.ini")); + if (rc != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error Exporting (%d)\n"), + rc), + -1); + } + else + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Could not open original object (%d)\n"), + rc), + -1); + + // At this point we've successfully created, populated and written + // the configuration object + // 5. Creates a new ACE_Configuration_Heap object + rc = fromFile.open (); + if (rc == 0) + { + // 6. Imports + ACE_Ini_ImpExp importExport (fromFile); + + rc = importExport.import_config (ACE_TEXT ("testConfig.ini")); + if (rc != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error Exporting (%d)\n"), + rc), + -1); + + // 7. Compares to original. + // This is a special compare since files imported using the + // INI file import do not contain type information + // + // NOTE: After this call the original object will be invalid!!! + // + if (!iniCompare (fromFile, original)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Object read from file does not ") + ACE_TEXT ("equal original (%d)\n"), + rc), + -1); + }// end if heap could not be opened. + else + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Could not open fromFile object (%d)\n"), + rc), + -1); + + // 8. Calls old "read_config" methods on the new object + + int nTimeToLive; + int bDelay; + int nDestPort; + int nReconnectInterval; + int nTraceLevel; + + ACE_TCHAR pszDestIPAddress[TEST_MAX_STRING]; + ACE_TCHAR pszLogFilePath[TEST_MAX_STRING]; + ACE_TCHAR pszTransactionFilePath[TEST_MAX_STRING]; + ACE_TCHAR pszHeading[TEST_MAX_STRING]; + ACE_TCHAR pszJustification[TEST_MAX_STRING]; + + ACE_Configuration_Section_Key root = fromFile.root_section (); + + // Process [network] section + ACE_Configuration_Section_Key NetworkSection; + if (fromFile.open_section (root, + ACE_TEXT ("network"), + 1, + NetworkSection) == 0) + { + this->get_section_integer (fromFile, + NetworkSection, + ACE_TEXT ("TimeToLive"), + &nTimeToLive, + 1, + 20); + + this->get_section_boolean (fromFile, + NetworkSection, + ACE_TEXT ("Delay"), + &bDelay); + + this->get_section_string (fromFile, + NetworkSection, + ACE_TEXT ("DestIPAddress"), + pszDestIPAddress, + TEST_MAX_STRING); + + this->get_section_integer (fromFile, + NetworkSection, + ACE_TEXT ("DestPort"), + &nDestPort, + 0, + 65535); + + this->get_section_integer (fromFile, + NetworkSection, + ACE_TEXT ("ReconnectInterval"), + &nReconnectInterval, + 0, + 65535); + }// end of "network" section + + // Process [logger] section + ACE_Configuration_Section_Key LoggerSection; + if (fromFile.open_section (root, + ACE_TEXT ("logger"), + 1, + LoggerSection) == 0) + { + this->get_section_string (fromFile, + LoggerSection, + ACE_TEXT ("Heading"), + pszHeading, + TEST_MAX_STRING); + this->get_section_integer (fromFile, + LoggerSection, + ACE_TEXT ("TraceLevel"), + &nTraceLevel, + 1, + 20); + this->get_section_string (fromFile, + LoggerSection, + ACE_TEXT ("Justification"), + pszJustification, + TEST_MAX_STRING); + this->get_section_string (fromFile, + LoggerSection, + ACE_TEXT ("LogFilePath"), + pszLogFilePath, + TEST_MAX_STRING); + this->get_section_string (fromFile, + LoggerSection, + ACE_TEXT ("TransactionFilePath"), + pszTransactionFilePath, + TEST_MAX_STRING); + }// end of "logger" section + + if (!rc) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("INI Format Import/Export Works ;-)\n"))); + return rc; +} + +// Used to test registry Import Export class + +int +Config_Test::testRegFormat () +{ + int rc = 0; + if (!this->equality_tested_) + { + rc = this->testEquality (); + if (rc != 0) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Equality Test Failed\n"))); + return rc; + } + + } + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing Registry Format Import/Export\n"))); + ACE_Configuration_Heap fromFile; + + // 1. Creates an ACE_Configuration_Heap object + ACE_Configuration_Heap original; + + rc = original.open (); + if (rc == 0) + { + // 2. Calls build_config_object to populate + rc = build_config_object (original); + if (rc != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error populating original config ") + ACE_TEXT ("object (%d)\n"), + rc), + -1); + // 3. Export + ACE_Registry_ImpExp importExport (original); + + rc = importExport.export_config (ACE_TEXT ("testConfig.ini")); + if (rc != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Error Exporting (%d)\n"), + rc), + -1); + } + else + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Could not open original object (%d)\n"), + rc), + -1); + + // At this point we've successfully created, populated and written + // the configuration object + // 5. Creates a new ACE_Configuration_Heap object + rc = fromFile.open (); + if (rc == 0) + { + // 6. Imports + ACE_Registry_ImpExp importExport (fromFile); + + rc = importExport.import_config (ACE_TEXT ("testConfig.ini")); + if (rc != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("Error Exporting (%d)\n"), + rc), + -1); + + // 7. Compares to original. + if (fromFile != original) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Object read from file does not ") + ACE_TEXT ("equal original (%d)\n"), + rc), + -1); + + // 7.1 Change a value and test NOT equal case + change_one (original, 101); + if (fromFile == original) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("not pass value change test (%d)\n"), + rc), + -1); + } + + // 7.2 change value back, they should be equal now + change_one (original, 100); + if (fromFile != original) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("not pass value change test (%d)\n"), + rc), + -1); + } + + }// end if heap could not be opened. + else + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Could not open fromFile object (%d)\n"), + rc), + -1); + + if (!rc) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Registry Format Import/Export Works ;-)\n"))); + return rc; +} + + +// Reads a string value from a configuration object. + +void +Config_Test::get_section_string (ACE_Configuration& config, + ACE_Configuration_Section_Key& SectionKey, + const ACE_TCHAR* pszName, + ACE_TCHAR* pszVariable, + int nMaxLength) +{ + ACE_TString StringValue; + + if (config.get_string_value (SectionKey, + pszName, + StringValue) == 0) + { + ACE_OS::strncpy (pszVariable, + StringValue.c_str (), + nMaxLength); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%s = %s\n"), + pszName, + pszVariable)); + } +} + +// Reads an integer value from a configuration object (when it's +// stored as a string) +void +Config_Test::get_section_integer (ACE_Configuration& config, + ACE_Configuration_Section_Key& SectionKey, + const ACE_TCHAR* pszName, + int* nVariable, + int nMinValue, + int nMaxValue) +{ + ACE_TString StringValue; + ACE_TCHAR pszString[30]; + ACE_OS::strcpy (pszString, ACE_TEXT ("0")); + int IntegerValue = 0; + + if (config.get_string_value (SectionKey, + pszName, + StringValue) == 0) + { + ACE_OS::strncpy (pszString, + StringValue.c_str (), + 30); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%s = %s\n"), + pszName, + pszString)); + } + + // convert to integer + IntegerValue = ACE_OS::atoi (pszString); + IntegerValue = (IntegerValue < nMinValue) ? nMinValue : IntegerValue; + IntegerValue = (IntegerValue > nMaxValue) ? nMaxValue : IntegerValue; + *nVariable = IntegerValue; +} + +// Reads a boolean value from a configuration object (when it's stored as a string). + +void +Config_Test::get_section_boolean (ACE_Configuration& config, + ACE_Configuration_Section_Key& SectionKey, + const ACE_TCHAR* pszName, + int* pVariable) +{ + ACE_TString StringValue; + ACE_TCHAR pszString[10]; + ACE_OS::strcpy (pszString, ACE_TEXT ("0")); + + if (config.get_string_value (SectionKey, + pszName, + StringValue) == 0) + { + ACE_OS::strncpy (pszString, + StringValue.c_str (), + 10); + for (ACE_TCHAR* pSrc = pszString; + *pSrc != ACE_TEXT ('\0'); + pSrc++) + // Convert to uppercase + if (ACE_OS::ace_islower (*pSrc)) + *pSrc = ACE_OS::ace_tolower (*pSrc); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%s = %s\n"), + pszName, + pszString)); + + if (ACE_OS::strcmp (pszString, + ACE_TEXT ("TRUE")) == 0) + *pVariable = 1; + else if (ACE_OS::strcmp (pszString, + ACE_TEXT ("FALSE")) == 0) + *pVariable = 0; + } +} + +int +run_main (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Config_Test")); + int errors = 0; + Config_Test manager; + + if ((errors += manager.testEquality ()) != 0) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Failed the equality Test\n"))); + + if ((errors += manager.testRegFormat ()) != 0) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Failed the REG Format Test\n"))); + + if ((errors += manager.testIniFormat ()) != 0) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Failed the INI Format Test\n"))); + + if ((errors += run_tests ()) != 0) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Failed in run_tests\n"))); + + ACE_END_TEST; + return errors == 0 ? 0 : 1; +} |