From fe4c169f7932da2ea4ede8ab74c933d9a79f121f Mon Sep 17 00:00:00 2001 From: Fred Hamster Date: Wed, 4 Feb 2026 21:43:53 -0500 Subject: [PATCH] bringing back in some tests these have been pending for a while. not at all ready yet though. --- .../library/tests_application/aa-readme.txt | 4 + nucleus/library/tests_application/makefile | 37 +++ .../tests_application/test_break_signal.cpp | 69 ++++++ .../tests_application/test_command_line.cpp | 125 ++++++++++ .../tests_application/test_dirtree_fcopy.cpp | 147 +++++++++++ .../test_ini_configurator.cpp | 178 +++++++++++++ .../tests_application/test_ini_parser.cpp | 112 +++++++++ .../test_path_configuration.cpp | 38 +++ .../test_registry_configurator.cpp | 233 ++++++++++++++++++ .../tests_application/test_system_values.cpp | 65 +++++ .../tests_application/test_timer_driver.cpp | 189 ++++++++++++++ 11 files changed, 1197 insertions(+) create mode 100644 nucleus/library/tests_application/aa-readme.txt create mode 100644 nucleus/library/tests_application/makefile create mode 100644 nucleus/library/tests_application/test_break_signal.cpp create mode 100644 nucleus/library/tests_application/test_command_line.cpp create mode 100644 nucleus/library/tests_application/test_dirtree_fcopy.cpp create mode 100644 nucleus/library/tests_application/test_ini_configurator.cpp create mode 100644 nucleus/library/tests_application/test_ini_parser.cpp create mode 100644 nucleus/library/tests_application/test_path_configuration.cpp create mode 100644 nucleus/library/tests_application/test_registry_configurator.cpp create mode 100644 nucleus/library/tests_application/test_system_values.cpp create mode 100644 nucleus/library/tests_application/test_timer_driver.cpp diff --git a/nucleus/library/tests_application/aa-readme.txt b/nucleus/library/tests_application/aa-readme.txt new file mode 100644 index 00000000..1f44dd9b --- /dev/null +++ b/nucleus/library/tests_application/aa-readme.txt @@ -0,0 +1,4 @@ + +this is in transit, being brought back from cold storage. + + diff --git a/nucleus/library/tests_application/makefile b/nucleus/library/tests_application/makefile new file mode 100644 index 00000000..f899f5db --- /dev/null +++ b/nucleus/library/tests_application/makefile @@ -0,0 +1,37 @@ +CONSOLE_MODE = t + +include cpp/variables.def + +PROJECT = tests_application +TYPE = test +TARGETS = test_command_line.exe \ +#test_break_signal.exe test_byte_filer.exe +# test_directory.exe test_directory_tree.exe test_dirtree_fcopy.exe test_filename.exe \ +# test_huge_file.exe test_ini_configurator.exe test_ini_parser.exe test_logger.exe \ +# test_path_configuration.exe test_registry_configurator.exe test_redirection.exe \ +# test_rendezvous.exe test_system_values.exe test_timer_driver.exe +#ifeq "$(findstring EMBEDDED_BUILD, $(DEFINITIONS))" "" +# TARGETS += test_shared_memory.exe +#endif +##LOCAL_LIBS_USED = basis i_library +DEFINITIONS += USE_FEISTY_MEOW_DLLS +LOCAL_LIBS_USED = unit_test application +#configuration filesystem loggers \ +# mathematics nodes processes structures textual timely structures basis \ +#loggers + +#VCPP_USE_GUI=t +#USE_HOOPLE_DLLS=t + +#RUN_TARGETS = $(ACTUAL_TARGETS) +# run every test except test_rendezvous, which waits for a key. +RUN_TARGETS = test_command_line.exe \ + +#test_break_signal.exe test_byte_filer.exe +# test_directory.exe test_directory_tree.exe test_filename.exe \ +# test_huge_file.exe test_ini_configurator.exe test_ini_parser.exe test_logger.exe \ +# test_path_configuration.exe test_registry_configurator.exe \ +# test_system_values.exe test_timer_driver.exe + +include cpp/rules.def + diff --git a/nucleus/library/tests_application/test_break_signal.cpp b/nucleus/library/tests_application/test_break_signal.cpp new file mode 100644 index 00000000..e835b3c2 --- /dev/null +++ b/nucleus/library/tests_application/test_break_signal.cpp @@ -0,0 +1,69 @@ +/*****************************************************************************\ +* * +* Name : test_break_signal * +* Author : Chris Koeritz * +* * +******************************************************************************* +* Copyright (c) 2004-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger(), s) + +static bool _leave_now = false; + +class test_break_signal : public application_shell +{ +public: + test_break_signal() : application_shell(class_name()) {} + IMPLEMENT_CLASS_NAME("test_break_signal"); + virtual int execute(); +}; + +void handle_break(int formal(signal)) +{ + #undef static_class_name + #define static_class_name() "test_break_signal" + FUNCDEF("handle_break"); + LOG("we have hit the signal handler for break!"); + _leave_now = true; + #undef static_class_name +} + +int test_break_signal::execute() +{ + FUNCDEF("execute"); + signal(SIGINT, handle_break); + LOG("starting loop--hit ctrl-C to exit or wait for timeout."); + time_stamp leave_time(20 * SECOND_ms); + while (!_leave_now && (time_stamp() < leave_time) ) { + portable::sleep_ms(20); + } + + // we jump to here when catching the signal. + istring to_print("break_signal:: works for those functions tested."); + guards::alert_message(to_print.s()); + fflush(NIL); + return 0; +} + +HOOPLE_MAIN(test_break_signal, ) + +#undef static_class_name + diff --git a/nucleus/library/tests_application/test_command_line.cpp b/nucleus/library/tests_application/test_command_line.cpp new file mode 100644 index 00000000..42f2b1f3 --- /dev/null +++ b/nucleus/library/tests_application/test_command_line.cpp @@ -0,0 +1,125 @@ +/*****************************************************************************\ +* * +* Name : test_command_line * +* Author : Chris Koeritz * +* * +* Purpose: * +* * +* Tests the command_line class by showing our parameters. * +* * +******************************************************************************* +* Copyright (c) 1992-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class test_command_line : public application_shell +{ +public: + test_command_line() : application_shell(class_name()) {} + IMPLEMENT_CLASS_NAME("test_command_line"); + int execute(); +}; + +int test_command_line::execute() +{ + program_wide_logger().log("these are the commands we got passed..."); + string_array cmds = command_line::get_command_line(); + for (int i = 0; i < cmds.length(); i++) { + program_wide_logger().log(isprintf("%02d: cmd=%s", i, cmds[i].s())); + } + + // test 1 is a simple probe on the actual arguments to this program. + { + command_line cl1(__argc, __argv); + filename prog(cl1.program_name()); + log(istring("got a program name of: [") + prog.dirname() + istring("] ") + + prog.basename()); + log("got parms of:"); + for (int i = 0; i < cl1.entries(); i++) { + command_parameter got = cl1.get(i); + log(istring(istring::SPRINTF, "%d: type=%s text=%s", i, + (got.type()==command_parameter::VALUE)? "VALUE" + : (got.type()==command_parameter::CHAR_FLAG)? "CHAR_FLAG" + : (got.type()==command_parameter::STRING_FLAG)? "STRING_FLAG" + : "UNKNOWN", + got.text().s())); + } + } + + // test 2 ensures that our new special flag ending support (standard unix + // flag of --) is performing. + { + istring cmd_line = "tossedout spumeco -g -q --fleem -r -- spugnats.txt crumbole.h"; + command_line cl2(cmd_line); + + command_parameter spumeco = cl2.get(0); +//log(isprintf("parm 0: type=%d text=%s", spumeco.type(), spumeco.text().s())); + if (spumeco.type() != command_parameter::VALUE) + deadly_error(class_name(), "test 2", "spumeco is wrong type"); + if (spumeco.text() != "spumeco") + deadly_error(class_name(), "test 2", "spumeco is erroneous"); + + command_parameter gflag = cl2.get(1); + if (gflag.type() != command_parameter::CHAR_FLAG) + deadly_error(class_name(), "test 2", "G flag had wrong type"); + if (gflag.text() != "g") + deadly_error(class_name(), "test 2", "G flag had wrong value"); + + command_parameter qflag = cl2.get(2); + if (qflag.type() != command_parameter::CHAR_FLAG) + deadly_error(class_name(), "test 2", "Q flag had wrong type"); + if (qflag.text() != "q") + deadly_error(class_name(), "test 2", "Q flag had wrong value"); + + command_parameter fleemflag = cl2.get(3); + if (fleemflag.type() != command_parameter::STRING_FLAG) + deadly_error(class_name(), "test 2", "fleem flag had wrong type"); + if (fleemflag.text() != "fleem") + deadly_error(class_name(), "test 2", "fleem flag had wrong value"); + + command_parameter rflag = cl2.get(4); + if (rflag.type() != command_parameter::CHAR_FLAG) + deadly_error(class_name(), "test 2", "R flag had wrong type"); + if (rflag.text() != "r") + deadly_error(class_name(), "test 2", "R flag had wrong value"); + + command_parameter spugval = cl2.get(5); + if (spugval.type() != command_parameter::VALUE) + deadly_error(class_name(), "test 2", "spugval had wrong type"); + if (spugval.text() != "spugnats.txt") + deadly_error(class_name(), "test 2", "spugval had wrong value"); + + command_parameter crumval = cl2.get(6); + if (crumval.type() != command_parameter::VALUE) + deadly_error(class_name(), "test 2", "crumval had wrong type"); + if (crumval.text() != "crumbole.h") + deadly_error(class_name(), "test 2", "crumval had wrong value"); + + command_parameter bogus = cl2.get(7); + if (bogus.type() != command_parameter::BOGUS_ITEM) + deadly_error(class_name(), "test 2", "bogus parameter had wrong type"); + } + +//more tests! + + guards::alert_message("command_line:: works for those functions tested."); + return 0; +} + +HOOPLE_MAIN(test_command_line, ) + diff --git a/nucleus/library/tests_application/test_dirtree_fcopy.cpp b/nucleus/library/tests_application/test_dirtree_fcopy.cpp new file mode 100644 index 00000000..4e5e40a5 --- /dev/null +++ b/nucleus/library/tests_application/test_dirtree_fcopy.cpp @@ -0,0 +1,147 @@ +/*****************************************************************************\ +* * +* Name : test_fcopy_file_transfer * +* Author : Chris Koeritz * +* * +* Purpose: * +* * +* Tests the directory_tree object as a file copy prompter. * +* * +******************************************************************************* +* Copyright (c) 2005-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger(), s) + +class test_fcopy : public application_shell +{ +public: + test_fcopy() : application_shell(static_class_name()) {} + IMPLEMENT_CLASS_NAME("test_dirtree_fcopy"); + int execute(); +}; + +int test_fcopy::execute() +{ + FUNCDEF("execute"); + + if (__argc < 3) + non_continuable_error(class_name(), "command line", "this program needs two " + "parameters:\na directory for the source and one for the target."); + + istring source_dir = __argv[1]; + istring target_dir = __argv[2]; + + // read the source location. + log(istring("Scanning source tree at \"") + source_dir + "\""); + directory_tree source(source_dir, "*"); + if (!source.good()) + non_continuable_error(class_name(), "directory_tree construction", + "the source directory could not be read"); + + // read the stuff that exists at the target. + log(istring("Scanning target tree at \"") + target_dir + "\""); + directory_tree target(target_dir, "*"); + if (!target.good()) + non_continuable_error(class_name(), "directory_tree construction", + "the target directory could not be read"); + + LOG("calculating checksums for source."); + if (!source.calculate()) + non_continuable_error(class_name(), "directory_tree calculation", + "the source tree could not be calculated"); + + LOG("calculating checksums for target."); + if (!target.calculate()) + non_continuable_error(class_name(), "directory_tree calculation", + "the target tree could not be calculated"); + + istring source_start; + istring target_start; + if (__argc > 3) + source_start = __argv[3]; + if (__argc > 4) + target_start = __argv[4]; + + LOG("comparing the two trees."); + filename_list diffs; + directory_tree::compare_trees(source, source_start, target, target_start, + diffs); +//LOG("missing files:"); +//LOG(diffs.text_form()); + + byte_array packed_form; + diffs.pack(packed_form); + filename_list regen; + if (!regen.unpack(packed_form)) + non_continuable_error(class_name(), "filename_list packing", + "could not unpack the list of differences"); + +//LOG("after packing and restoring:"); +//LOG(regen.text_form()); + + if (regen.elements() != diffs.elements()) + non_continuable_error(class_name(), "filename_list packing", + "there were a different number of elements in unpacked form"); + for (int i = 0; i < diffs.elements(); i++) { + if (!regen.member(*diffs[i])) { + istring name = diffs[i]->raw(); + non_continuable_error(class_name(), "filename_list packing", + istring("name from original set was missing in regenerated: ") + + name); + } + } + + for (int i = 0; i < diffs.elements(); i++) { + file_info *curr = diffs[i]; + filename source_file = source.path() + filename::default_separator() + + curr->raw(); + filename target_file = target.path() + filename::default_separator() + + curr->secondary(); +//LOG(istring("cp source: ") + source_file.raw()); +//LOG(istring("-> target: ") + target_file.raw()); + filename targ_dir = target_file.dirname(); + if (!targ_dir.is_directory()) { + bool worked = directory::recursive_create(targ_dir); + if (!worked) + non_continuable_error(class_name(), "recursive mkdir", + istring("failed to create the target directory ") + targ_dir); + } + + outcome ret = heavy_file_operations::copy_file(source_file, target_file); + if (ret != heavy_file_operations::OKAY) + non_continuable_error(class_name(), "copying file", istring("there was an error ") + + heavy_file_operations::outcome_name(ret) + + " when copying the file."); + } + +//do the copy by going across the entire set of files and making sure +//they get copied to target. +// +//reread the target location. +// +//compare with source tree read before. + + guards::alert_message("directory_tree file transfer:: works for those functions tested."); + return 0; +} + +HOOPLE_MAIN(test_fcopy, ) + diff --git a/nucleus/library/tests_application/test_ini_configurator.cpp b/nucleus/library/tests_application/test_ini_configurator.cpp new file mode 100644 index 00000000..477fe915 --- /dev/null +++ b/nucleus/library/tests_application/test_ini_configurator.cpp @@ -0,0 +1,178 @@ +/*****************************************************************************\ +* * +* Name : test_ini_configurator * +* Author : Chris Koeritz * +* * +******************************************************************************* +* Copyright (c) 1998-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +const int test_iterations = 10; + +//#define DEBUG_INI_CONFIGURATOR_TEST + // uncomment for debugging version. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG_INI_CONFIGURATOR_TEST + #include +#endif + +HOOPLE_STARTUP_CODE; + +using namespace geometric; + +typedef float_plus frunkle; + +#define WHERE __WHERE__.s() + +const char *INI_SECTION = "t_ini_configurator"; + +int main(int formal(argc), char *formal(argv)[]) +{ + ini_configurator ini("t_ini_configurator.ini", ini_configurator::AUTO_STORE); + +console_logger out; +out.log(istring("ini file resides in: ") + ini.name()); + +out.log(istring("exe directory is currently: ") + path_configuration::application_directory()); + + for (int i = 0; i < test_iterations; i++) { // outer loop bracket. + // beginning of test sets. + { + // first test set. + const char *TEST_NAME = "first test: rectangle"; + // this tests whether rectangle storage works. + screen_rectangle default_rectangle(10, 289, 388, 191); + ini.delete_entry(INI_SECTION, "window_size"); + screen_rectangle win_size; + istring tmp = ini.load(INI_SECTION, "window_size", + default_rectangle.text_form()); + win_size.from_text(tmp); + if (win_size != default_rectangle) + deadly_error(INI_SECTION, TEST_NAME, + "rectangle not equal to default"); + screen_rectangle new_size(23, 49, 129, 93); + ini.store(INI_SECTION, "window_size", new_size.text_form()); + screen_rectangle current_size; + tmp = ini.load(INI_SECTION, "window_size", + default_rectangle.text_form()); + current_size.from_text(tmp); + if (current_size != new_size) + deadly_error(INI_SECTION, TEST_NAME, + "rectangle not equal to second size stored"); + } + { + // second test set. + const char *TEST_NAME = "second test: string"; + istring junk("this is a junky string to be stored as bytes...."); + byte_array to_store(junk.length() + 1, (byte *)junk.observe()); + istring as_bytes; + byte_format::bytes_to_string(to_store, as_bytes); + ini.store("test_of_byte_store", "test1", as_bytes); + istring blort = "blort_fest!"; + istring rettle = ini.load("test_of_byte_store", "test1", blort); + byte_array found_byte; + byte_format::string_to_bytes(rettle, found_byte); + istring found_junk((const char *)found_byte.observe()); + if (rettle == blort) + deadly_error(INI_SECTION, TEST_NAME, + "ini_configurator load failed: default was used"); + else if (found_junk != junk) + deadly_error(INI_SECTION, TEST_NAME, + "ini_configurator load failed: result differed from original"); + } + { + // third test set. + const char *TEST_NAME = "third test: frunkle"; + frunkle def_frunkle(3.14159265358); + istring def_text(istring::SPRINTF, "%f", def_frunkle.value()); + ini.store(INI_SECTION, TEST_NAME, def_text); + istring found_string = ini.load(INI_SECTION, TEST_NAME, "9949494.3"); + frunkle found_frunkle = found_string.convert(0.0); + if (found_frunkle == frunkle(9949494.3)) + deadly_error(INI_SECTION, TEST_NAME, + "ini_configurator load failed: default was used"); + if (found_frunkle != def_frunkle) + deadly_error(INI_SECTION, TEST_NAME, + "ini_configurator load failed: saved value differed"); + } + { + // fourth test set. + const char *TEST_NAME = "fourth test: frunkle"; + frunkle def_frunkle(1487335673.1415926535834985987); + istring def_text(istring::SPRINTF, "%f", def_frunkle.value()); + ini.store("test", "frunkle_test", def_text); + istring found_string = ini.load("test", "frunkle_test", "9949494.3"); + frunkle found_frunkle = found_string.convert(0.0); + if (found_frunkle == frunkle(9949494.3)) + deadly_error(INI_SECTION, TEST_NAME, + "ini_configurator load failed: wrong default was used"); + if (found_frunkle != def_frunkle) + deadly_error(INI_SECTION, TEST_NAME, + "ini_configurator load failed: saved value differed"); + } + { + // fifth test set. + const char *TEST_NAME = "fifth test: bytes"; + istring urp("urp"); + istring junk("this is a junky string to be stored as bytes...."); + byte_array default_bytes(urp.length() + 1, (byte *)urp.observe()); + istring defbytes_string; + byte_format::bytes_to_string(default_bytes, defbytes_string); + byte_array found; + istring tmp = ini.load("test_of_byte_store", "test1", defbytes_string); + byte_format::string_to_bytes(tmp, found); + istring string_found = (char *)found.observe(); + if (string_found == urp) + deadly_error(INI_SECTION, TEST_NAME, + "ini_configurator load_bytes failed: default was used"); + if (string_found.length() != junk.length()) + deadly_error(INI_SECTION, TEST_NAME, + "ini_configurator load_bytes failed: array lengths differ"); + if (string_found != junk) + deadly_error(INI_SECTION, TEST_NAME, + "ini_configurator load_bytes failed: arrays differ"); + } + { + // sixth test set. + const char *TEST_NAME = "sixth test: blank string"; + ini.delete_entry("test_of_blank_string", "test1"); + istring blank(""); + istring fund = ini.load("test_of_blank_string", "test1", blank); + if (fund != blank) + deadly_error(INI_SECTION, TEST_NAME, "ini_configurator load string " + "with blank default failed: didn't return blank"); + ini.delete_entry("test_of_blank_string", "test1"); + istring non_blank("blinkblankblunk"); + fund = ini.load("test_of_blank_string", "test1", non_blank); + if (fund != non_blank) + deadly_error(INI_SECTION, TEST_NAME, "ini_configurator load string " + "with non-blank default failed: didn't return default"); + fund = ini.load("test_of_blank_string", "test1", blank); + if (fund != non_blank) + deadly_error(INI_SECTION, TEST_NAME, "ini_configurator load string " + "with blank default failed: returned wrong string"); + } + } + + istring to_print("ini_configurator:: works for those functions tested."); + guards::alert_message(to_print.s()); + return 0; +} + diff --git a/nucleus/library/tests_application/test_ini_parser.cpp b/nucleus/library/tests_application/test_ini_parser.cpp new file mode 100644 index 00000000..1caa22cf --- /dev/null +++ b/nucleus/library/tests_application/test_ini_parser.cpp @@ -0,0 +1,112 @@ +/*****************************************************************************\ +* * +* Name : test_ini_parser * +* Author : Chris Koeritz * +* * +******************************************************************************* +* Copyright (c) 1991-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const istring INI_FILE_1 = "\ +[bork]\n\ +norple=1\n\ +train=12.5\n\ +singhy=9 \r\n\ +\n\ +[twerf]\r\n\ +noodles=fungus\n\ +dora=34\n\ +"; + +//#define READ_FILE_TEST + // uncomment to read in a file and parse it. + +class test_ini_parser : public application_shell +{ +public: + test_ini_parser() : application_shell(class_name()) {} + IMPLEMENT_CLASS_NAME("test_ini_parser"); + virtual int execute(); +}; + +int test_ini_parser::execute() +{ + program_wide_logger().eol(log_base::NO_ENDING); + + ini_parser par(INI_FILE_1); + +//istring dump; +//par.restate(dump); +//log(istring("table has:\n") + dump); + + string_table twerf; + if (!par.get_section("twerf", twerf)) + deadly_error(class_name(), "get_section 1", "twerf section was not found"); +//log(istring("twerf section is: ") + twerf.text_form()); + if (!twerf.find("noodles")) + deadly_error(class_name(), "get_section 1", "item #1 was not found"); + if (*twerf.find("noodles") != "fungus") + deadly_error(class_name(), "get_section 1", "item #1 found is incorrect"); + if (!twerf.find("dora")) + deadly_error(class_name(), "get_section 1", "item #2 was not found"); + if (*twerf.find("dora") != "34") + deadly_error(class_name(), "get_section 1", "item #2 found is incorrect"); + + string_table bork; + if (!par.get_section("bork", bork)) + deadly_error(class_name(), "get_section 2", "bork section was not found"); + if (!bork.find("norple")) + deadly_error(class_name(), "get_section 2", "item #1 was not found"); + if (*bork.find("norple") != "1") + deadly_error(class_name(), "get_section 2", "item #1 found is incorrect"); + if (!bork.find("train")) + deadly_error(class_name(), "get_section 2", "item #2 was not found"); + if (*bork.find("train") != "12.5") + deadly_error(class_name(), "get_section 2", "item #2 found is incorrect"); + if (!bork.find("singhy")) + deadly_error(class_name(), "get_section 2", "item #3 was not found"); + if (*bork.find("singhy") != "9") + deadly_error(class_name(), "get_section 2", "item #3 found is incorrect"); + + istring new_ini; + par.restate(new_ini); + + program_wide_logger().eol(log_base::CRLF_AT_END); + log(""); + +#ifdef READ_FILE_TEST + byte_filer input("c:/home/fungal.lld", "rb"); + int len = input.length(); + log(isprintf("fungal len is %d", len)); + istring jojo; + input.read(jojo, len); + //log("whole file is:"); + //log(jojo); + + ini_parser klug(jojo); + istring dump2; + klug.restate(dump2); + log(dump2); +#endif + + guards::alert_message("ini_parser:: works for those functions tested.\n"); + return 0; +} + +HOOPLE_MAIN(test_ini_parser, ) + diff --git a/nucleus/library/tests_application/test_path_configuration.cpp b/nucleus/library/tests_application/test_path_configuration.cpp new file mode 100644 index 00000000..1382c05e --- /dev/null +++ b/nucleus/library/tests_application/test_path_configuration.cpp @@ -0,0 +1,38 @@ +/*****************************************************************************\ +* * +* Name : test_path_configuration * +* Author : Chris Koeritz * +* * +******************************************************************************* +* Copyright (c) 2002-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +#include +#include +#include +#include +#include + +HOOPLE_STARTUP_CODE; + +int main(int argc, char *argv[]) +{ + console_logger out; + + istring jammed; + for (int i = 0; i < argc; i++) + jammed += istring(argv[i]) + " "; + out.log(istring("command line=") + jammed); + + istring app_dir = path_configuration::application_directory(); + out.log(istring("app dir is: ") + app_dir); + + guards::alert_message("path_configuration:: works for those functions tested."); + return 0; +} + diff --git a/nucleus/library/tests_application/test_registry_configurator.cpp b/nucleus/library/tests_application/test_registry_configurator.cpp new file mode 100644 index 00000000..45f2989d --- /dev/null +++ b/nucleus/library/tests_application/test_registry_configurator.cpp @@ -0,0 +1,233 @@ +/*****************************************************************************\ +* * +* Name : test_registry_configurator * +* Author : Chris Koeritz * +* * +******************************************************************************* +* Copyright (c) 1998-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +const int test_iterations = 10; + +//#define DEBUG_REGISTRY_CONFIGURATOR_TEST + // uncomment for debugging version. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +HOOPLE_STARTUP_CODE; + +using namespace geometric; + +typedef float_plus frunkle; + +#define WHERE __WHERE__.s() + +const registry_configurator::registry_hives THE_HIVE + = registry_configurator::hkey_current_user; + +const istring REGISTRY_SECTION = "boobo/tahini/nunkshus"; + +#define LOG(s) program_wide_logger().log(s) + +int main(int formal(argc), char *formal(argv)[]) +{ +#ifdef __WIN32__ + // this test is only needed for win32 OSes. + registry_configurator ini(THE_HIVE, registry_configurator::AUTO_STORE); + +console_logger out; + + for (int i = 0; i < test_iterations; i++) { // outer loop bracket. + // beginning of test sets. + + { + const char *TEST_NAME = "zeroth test: cleaning section"; + ini.delete_section(REGISTRY_SECTION); + if (ini.section_exists(REGISTRY_SECTION)) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "section still exists after deleting!"); + } + + { + // first test set. + const char *TEST_NAME = "first test: rectangle"; + // this tests whether rectangle storage works. + screen_rectangle default_rectangle(10, 289, 388, 191); + ini.delete_entry(REGISTRY_SECTION, "window_size"); + screen_rectangle win_size; + istring tmp = ini.load(REGISTRY_SECTION, "window_size", + default_rectangle.text_form()); + win_size.from_text(tmp); + if (win_size != default_rectangle) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "rectangle not equal to default"); + screen_rectangle new_size(23, 49, 129, 93); + ini.store(REGISTRY_SECTION, "window_size", new_size.text_form()); + screen_rectangle current_size; + tmp = ini.load(REGISTRY_SECTION, "window_size", + default_rectangle.text_form()); + current_size.from_text(tmp); + if (current_size != new_size) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "rectangle not equal to second size stored"); + } + { + // second test set. + const char *TEST_NAME = "second test: string"; + istring junk("this is a junky string to be stored as bytes...."); + byte_array to_store(junk.length() + 1, (byte *)junk.observe()); + istring as_bytes; + byte_format::bytes_to_string(to_store, as_bytes); + ini.store(REGISTRY_SECTION + "/test_of_byte_store", "test1", as_bytes); + istring blort = "blort_fest!"; + istring rettle = ini.load(REGISTRY_SECTION + "/test_of_byte_store", + "test1", blort); + byte_array found_byte; + byte_format::string_to_bytes(rettle, found_byte); + istring found_junk((const char *)found_byte.observe()); + if (rettle == blort) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "registry_configurator load failed: default was used"); + else if (found_junk != junk) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "registry_configurator load failed: result differed from original"); + } + { + // third test set. + const char *TEST_NAME = "third test: frunkle"; + frunkle def_frunkle(3.14159265358); + istring def_text(istring::SPRINTF, "%f", def_frunkle.value()); + ini.store(REGISTRY_SECTION, TEST_NAME, def_text); + istring found_string = ini.load(REGISTRY_SECTION, TEST_NAME, "9949494.3"); + frunkle found_frunkle = found_string.convert(0.0); + if (found_frunkle == frunkle(9949494.3)) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "registry_configurator load failed: default was used"); + if (found_frunkle != def_frunkle) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "registry_configurator load failed: saved value differed"); + } + { + // fourth test set. + const char *TEST_NAME = "fourth test: frunkle"; + frunkle def_frunkle(1487335673.1415926535834985987); + istring def_text(istring::SPRINTF, "%f", def_frunkle.value()); + ini.store(REGISTRY_SECTION + "/test", "frunkle_test", def_text); + istring found_string = ini.load(REGISTRY_SECTION + "/test", + "frunkle_test", "9949494.3"); + frunkle found_frunkle = found_string.convert(0.0); + if (found_frunkle == frunkle(9949494.3)) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "registry_configurator load failed: wrong default was used"); + if (found_frunkle != def_frunkle) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "registry_configurator load failed: saved value differed"); + } + { + // fifth test set. + const char *TEST_NAME = "fifth test: bytes"; + istring urp("urp"); + istring junk("this is a junky string to be stored as bytes...."); + byte_array default_bytes(urp.length() + 1, (byte *)urp.observe()); + istring defbytes_string; + byte_format::bytes_to_string(default_bytes, defbytes_string); + byte_array found; + istring tmp = ini.load(REGISTRY_SECTION + "/test_of_byte_store", "test1", defbytes_string); + byte_format::string_to_bytes(tmp, found); + istring string_found = (char *)found.observe(); + if (string_found == urp) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "registry_configurator load_bytes failed: default was used"); + if (string_found.length() != junk.length()) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "registry_configurator load_bytes failed: array lengths differ"); + if (string_found != junk) + deadly_error(REGISTRY_SECTION, TEST_NAME, + "registry_configurator load_bytes failed: arrays differ"); + } + { + // sixth test set. + const char *TEST_NAME = "sixth test: blank string"; + ini.delete_entry(REGISTRY_SECTION + "/test_of_blank_string", "test1"); + istring blank(""); + istring fund = ini.load(REGISTRY_SECTION + "/test_of_blank_string", "test1", blank); + if (fund != blank) + deadly_error(REGISTRY_SECTION, TEST_NAME, "registry_configurator load string " + "with blank default failed: didn't return blank"); + ini.delete_entry(REGISTRY_SECTION + "/test_of_blank_string", "test1"); + istring non_blank("blinkblankblunk"); + fund = ini.load(REGISTRY_SECTION + "/test_of_blank_string", "test1", non_blank); + if (fund != non_blank) + deadly_error(REGISTRY_SECTION, TEST_NAME, "registry_configurator load string " + "with non-blank default failed: didn't return default"); + fund = ini.load(REGISTRY_SECTION + "/test_of_blank_string", "test1", blank); + if (fund != non_blank) + deadly_error(REGISTRY_SECTION, TEST_NAME, "registry_configurator load string " + "with blank default failed: returned wrong string"); + } + { + // 7th set, test get_section. + registry_configurator ini(registry_configurator::HKCU, + registry_configurator::AUTO_STORE); + const char *TEST_NAME = "seventh test: get_section"; + string_table sect; + bool worked = ini.get_section("Environment", sect); + if (!worked) + deadly_error(REGISTRY_SECTION, TEST_NAME, "failed to get sample section (environment)"); +//to see if it worked... +// LOG(istring("got section:\n") + sect.text_form()); + } + { + // 8th set, test put_section. + const char *TEST_NAME = "eighth test: put_section"; + string_table sect; + sect.add("dooby", "mastiff"); + sect.add("flammix", "pontiff"); + sect.add("gruntlix", "sagawilla"); + sect.add("toast", "megaspoony"); + bool worked = ini.put_section(REGISTRY_SECTION + "\\turnips", sect); + if (!worked) + deadly_error(REGISTRY_SECTION, TEST_NAME, "failed to put sample section"); + string_table sect8; + worked = ini.get_section(REGISTRY_SECTION + "\\turnips", sect8); + // since it should read in the order written, these should come back + // directly comparable. + if (sect != sect8) + deadly_error(REGISTRY_SECTION, TEST_NAME, "registry contents didn't compare as expected"); + worked = ini.delete_section(REGISTRY_SECTION + "\\turnips"); + if (!worked) + deadly_error(REGISTRY_SECTION, TEST_NAME, "failed to delete new section"); + worked = ini.get_section(REGISTRY_SECTION + "\\turnips", sect8); + if (worked) + deadly_error(REGISTRY_SECTION, TEST_NAME, "new section could be read still!"); + } + } + + // clean up after the test. + ini.delete_section(REGISTRY_SECTION); + +#endif // win32. + + istring to_print("registry_configurator:: works for those functions tested."); + guards::alert_message(to_print.s()); + return 0; +} + diff --git a/nucleus/library/tests_application/test_system_values.cpp b/nucleus/library/tests_application/test_system_values.cpp new file mode 100644 index 00000000..3afd8abd --- /dev/null +++ b/nucleus/library/tests_application/test_system_values.cpp @@ -0,0 +1,65 @@ +/*****************************************************************************\ +* * +* Name : test_system_values * +* Author : Chris Koeritz * +* * +******************************************************************************* +* Copyright (c) 2005-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger(), s) + +class test_system_values : public application_shell +{ +public: + test_system_values() + : application_shell(class_name()), + events(system_values::EVENT_VALUES()), + filters(system_values::FILTER_VALUES()), + outcomes(system_values::OUTCOME_VALUES()) + {} + + IMPLEMENT_CLASS_NAME("test_system_values"); + virtual int execute(); + +private: + system_values events; + system_values filters; + system_values outcomes; +}; + +int test_system_values::execute() +{ + FUNCDEF("execute"); + + log("Outcome Values"); + log("=============="); + log(outcomes.text_form()); + + log("Filter Values"); + log("============="); + log(filters.text_form()); + + log("Event Values"); + log("============"); + log(events.text_form()); + + return 0; +} + +HOOPLE_MAIN(test_system_values, ) + diff --git a/nucleus/library/tests_application/test_timer_driver.cpp b/nucleus/library/tests_application/test_timer_driver.cpp new file mode 100644 index 00000000..ba7fff19 --- /dev/null +++ b/nucleus/library/tests_application/test_timer_driver.cpp @@ -0,0 +1,189 @@ +/*****************************************************************************\ +* * +* Name : t_timer_driver * +* Author : Chris Koeritz * +* * +* Purpose: * +* * +* Tests the timer driver class from the operating system library. * +* * +******************************************************************************* +* Copyright (c) 2005-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOG(s) STAMPED_EMERGENCY_LOG(program_wide_logger(), s) + +const int TEST_DURATION = 3 * MINUTE_ms; + +const int MAX_THREADS = 120; + +//////////////////////////////////////////////////////////////////////////// + +class timer_driver_tester : public application_shell +{ +public: + timer_driver_tester() + : application_shell(static_class_name()), _in_progress(false) {} + IMPLEMENT_CLASS_NAME("timer_driver_tester"); + virtual ~timer_driver_tester() {} + + int execute(); + + thread_cabinet &threads() { return _threads; } + + bool in_progress() const { return _in_progress; } + // returns true if activity is currently occurring on the main thread. + // we don't expect this activity to be interrupted by timer events. + +private: + bool _in_progress; + // simple flag to check when a timer hits. if this is true, then a timer + // hit while we were doing actual functional operations, rather than + // just waiting in a sleep. + thread_cabinet _threads; // storage for our time_stamp testing threads. +}; + +//////////////////////////////////////////////////////////////////////////// + +class timer_test_thread : public ithread +{ +public: + timer_test_thread(application_shell &parent) + : ithread(parent.randomizer().inclusive(20, 480)), _parent(parent) + { start(NIL); } + + IMPLEMENT_CLASS_NAME("timer_test_thread"); + void perform_activity(void *) { + FUNCDEF("perform_activity"); + if (time_stamp() < _started) + deadly_error(class_name(), func, "start time is before current time."); + if (time_stamp() < _last) + deadly_error(class_name(), func, "last check is before current time."); + _last.reset(); // set the last time to right now. + time_stamp ted; + time_stamp jed; + if (ted > jed) + deadly_error(class_name(), func, "jed is less than test."); + } + +private: + application_shell &_parent; + time_stamp _started; + time_stamp _last; +}; + +//////////////////////////////////////////////////////////////////////////// + +class my_timer_handler : public timed_object +{ +public: + my_timer_handler(timer_driver_tester &parent, int id) : _id(id), _parent(parent) {} + virtual ~my_timer_handler() {} + IMPLEMENT_CLASS_NAME("my_timer_handler"); + + virtual void handle_timer_callback() { + FUNCDEF("handle_timer_callback"); + if (_parent.in_progress()) + LOG("saw in progress flag set to true! we interrupted real " + "ops, not just sleep!"); + LOG(isprintf("timer%d hit.", _id)); + timer_test_thread *new_thread = new timer_test_thread(_parent); + unique_int id = _parent.threads().add_thread(new_thread, false, NIL); + // the test thread auto-starts, so we don't let the cabinet start it. + if (!id) + deadly_error(class_name(), func, "failed to start a new thread."); + + if (_parent.threads().threads() > MAX_THREADS) { + int gone_index = _parent.randomizer().inclusive(0, _parent.threads().threads() - 1); + unique_int gone_thread = _parent.threads().thread_ids()[gone_index]; + _parent.threads().cancel_thread(gone_thread); + portable::sleep_ms(100); // allow thread to start up. + } + _parent.threads().clean_debris(); // toss any dead threads. + + LOG(isprintf("%d threads checking time_stamp.", _parent.threads().threads())); + } + +private: + int _id; + timer_driver_tester &_parent; +}; + +//////////////////////////////////////////////////////////////////////////// + +#define CREATE_TIMER(name, id, dur) \ + my_timer_handler name(*this, id); \ + program_wide_timer().set_timer(dur, &name); \ + LOG(istring("timer ") + #name + " hitting every " \ + + #dur + " ms") + +#define ZAP_TIMER(name) \ + program_wide_timer().zap_timer(&name) + +int timer_driver_tester::execute() +{ + SET_DEFAULT_COMBO_LOGGER; + + CREATE_TIMER(timer1, 1, 500); +// CREATE_TIMER(timer1, 1, 10); + CREATE_TIMER(timer2, 2, SECOND_ms); + CREATE_TIMER(timer3, 3, 3 * SECOND_ms); + CREATE_TIMER(timer4, 4, 8 * SECOND_ms); + CREATE_TIMER(timer5, 5, 12 * SECOND_ms); + + LOG("pausing for a while..."); + time_stamp when_done(TEST_DURATION); + while (time_stamp() < when_done) { + _in_progress = true; + // do some various calculations in here and see if we're interrupted + // during them. it's one thing to be interrupted in the middle of a + // sleep, but it's much different to be interrupted in mid operation. + int scrob = 1; + for (int i = 1; i < 50; i++) { + scrob *= i; + } + _in_progress = false; +#ifdef __UNIX__ + portable::sleep_ms(100); +#else + bool okay = event_extensions::poll(); + if (!okay) break; +#endif + } + + guards::alert_message("timer_driver:: works for all functions tested (if messages seem appropriate)."); + + ZAP_TIMER(timer1); + ZAP_TIMER(timer2); + ZAP_TIMER(timer3); + ZAP_TIMER(timer4); + ZAP_TIMER(timer5); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////// + +HOOPLE_MAIN(timer_driver_tester, ) + -- 2.34.1