]> feistymeow.org Git - feisty_meow.git/commitdiff
added tests for processes and one for timely
authorFred T. Hamster <fred@feistymeow.org>
Wed, 18 Feb 2026 19:27:17 +0000 (14:27 -0500)
committerFred T. Hamster <fred@feistymeow.org>
Wed, 18 Feb 2026 19:27:17 +0000 (14:27 -0500)
time_stamp tester is kind of silly, but it's in there again.  it needs to do some more verification.
the safe_callback test is also totally minimal, and wouldn't catch many bugs.  it needs to be threaded and much more active.
state machine test is also in and compiling, but totally doesn't work.  pared a file down to a list of *.h and *.cpp files, and
every line is rejected for some reason.  need to investigate, because if it's telling the truth, then state_machine got
broken at some point.

nucleus/library/makefile
nucleus/library/tests_processes/input_data_state_machine.txt [new file with mode: 0644]
nucleus/library/tests_processes/makefile [new file with mode: 0644]
nucleus/library/tests_processes/test_safe_callback.cpp [new file with mode: 0644]
nucleus/library/tests_processes/test_state_machine.cpp [new file with mode: 0644]
nucleus/library/tests_timely/makefile
nucleus/library/tests_timely/test_time_stamp.cpp [new file with mode: 0644]
scripts/buildor/upgrade_hoople_to_feistymeow.sh

index 5aa3847763c35810b8b6ff7de589ddf074e736af..6b6045fb442dce1461e778c20e0ce0a68f4e0ac3 100644 (file)
@@ -19,6 +19,7 @@ BUILD_BEFORE = algorithms \
   tests_structures \
   tests_filesystem \
   tests_mathematics \
+  tests_processes \
   tests_nodes \
   tests_textual \
   tests_timely \
diff --git a/nucleus/library/tests_processes/input_data_state_machine.txt b/nucleus/library/tests_processes/input_data_state_machine.txt
new file mode 100644 (file)
index 0000000..08608c5
--- /dev/null
@@ -0,0 +1,21 @@
+array.h
+astring.cpp
+astring.h
+base_string.h
+byte_array.h
+common_outcomes.cpp
+common_outcomes.h
+contracts.h
+definitions.h
+enhance_cpp.h
+environment.cpp
+environment.h
+functions.h
+guards.cpp
+guards.h
+makefile
+mutex.cpp
+mutex.h
+outcome.h
+utf_conversion.cpp
+utf_conversion.h
diff --git a/nucleus/library/tests_processes/makefile b/nucleus/library/tests_processes/makefile
new file mode 100644 (file)
index 0000000..f872ba2
--- /dev/null
@@ -0,0 +1,15 @@
+CONSOLE_MODE = t
+
+include cpp/variables.def
+
+PROJECT = test_processes
+TYPE = test
+SOURCE = 
+TARGETS = test_safe_callback.exe test_state_machine.exe 
+LOCAL_LIBS_USED = unit_test application configuration filesystem loggers \
+  nodes processes structures textual timely structures basis 
+#filesystem  mathematics 
+RUN_TARGETS = $(ACTUAL_TARGETS)
+
+include cpp/rules.def
+
diff --git a/nucleus/library/tests_processes/test_safe_callback.cpp b/nucleus/library/tests_processes/test_safe_callback.cpp
new file mode 100644 (file)
index 0000000..5b8232f
--- /dev/null
@@ -0,0 +1,80 @@
+/*****************************************************************************\
+*                                                                             *
+*  Name   : test_safe_callback                                                *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*  Purpose:                                                                   *
+*                                                                             *
+*    Tests the safe callback object slightly.  Mainly this is to ensure that  *
+*  no memory leaks are being caused by the object and that minimal support is *
+*  provided by the object.                                                    *
+*                                                                             *
+*******************************************************************************
+* 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                               *
+\*****************************************************************************/
+
+#include <application/hoople_main.h>
+#include <basis/astring.h>
+#include <basis/guards.h>
+#include <configuration/application_configuration.h>
+#include <loggers/critical_events.h>
+#include <loggers/program_wide_logger.h>
+//#include <loggers/file_logger.h>
+#include <processes/safe_callback.h>
+#include <structures/static_memory_gremlin.h>
+#include <unit_test/unit_base.h>
+
+using namespace application;
+using namespace basis;
+using namespace configuration;
+//using namespace mathematics;
+//using namespace filesystem;
+using namespace loggers;
+using namespace processes;
+//using namespace structures;
+//using namespace textual;
+using namespace timely;
+using namespace unit_test;
+
+#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(s))
+
+//////////////
+
+const astring LOGFILE_NAME = application_configuration::make_logfile_name
+    ("t_safe_callback.log");
+  // where our debugging output goes by default.
+
+///#define LOG(to_print) log.log(timestamp(true) + astring(to_print))
+  // our macro for logging with a timestamp.
+
+//hmmm: this tester doesn't really do very much at all.
+//  how about a more aggressive test, which has a bunch of threads using
+//  safe callback?
+
+class cb_tester : public safe_callback
+{
+public:
+  cb_tester() : safe_callback() {}
+  ~cb_tester() { end_availability(); }
+
+  virtual void real_callback(callback_data_block &) 
+      { /* do nothing. */ }
+};
+
+//hmmm: move this to using a class based approach, based on unit_test and application_shell.
+
+int main(int formal(argc), char *formal(argv)[])
+{
+///  file_logger log(LOGFILE_NAME);
+
+  cb_tester testing;
+
+  critical_events::alert_message("safe_callback:: works for all functions tested.");
+  return 0;
+}
+
diff --git a/nucleus/library/tests_processes/test_state_machine.cpp b/nucleus/library/tests_processes/test_state_machine.cpp
new file mode 100644 (file)
index 0000000..27a60ed
--- /dev/null
@@ -0,0 +1,195 @@
+/*****************************************************************************\
+*                                                                             *
+*  Name   : test_state_machine                                                *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*  Purpose:                                                                   *
+*                                                                             *
+*    Sets up a simple state machine for a pattern matcher.                    *
+*                                                                             *
+*******************************************************************************
+* 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                               *
+\*****************************************************************************/
+
+// This simple state machine recognizes all strings that are of the form
+// *.[cho], which means any string with either .o, .c, or .h on the end.
+
+#include <application/application_shell.h>
+#include <application/hoople_main.h>
+#include <basis/astring.h>
+#include <basis/byte_array.h>
+#include <basis/functions.h>
+#include <basis/guards.h>
+#include <configuration/application_configuration.h>
+#include <filesystem/byte_filer.h>
+#include <loggers/console_logger.h>
+#include <loggers/critical_events.h>
+#include <loggers/program_wide_logger.h>
+#include <processes/state_machine.h>
+#include <structures/static_memory_gremlin.h>
+#include <unit_test/unit_base.h>
+
+#include <string.h>
+
+using namespace application;
+using namespace basis;
+using namespace configuration;
+//using namespace mathematics;
+using namespace filesystem;
+using namespace loggers;
+using namespace processes;
+//using namespace structures;
+//using namespace textual;
+using namespace timely;
+using namespace unit_test;
+
+#undef LOG
+#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(s))
+
+//////////////
+
+enum recognizer_states { GET_ANY = 1, GOT_DOT, GOT_CHO, RECOGNIZED, REJECTED };
+
+//#undef LOG
+//#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
+
+class test_state_machine : public application_shell
+{
+public:
+  test_state_machine();
+  DEFINE_CLASS_NAME("test_state_machine");
+  int execute();
+  void setup_state_machine(transition_map &recog);
+  void print_instructions();
+};
+
+astring state_text(recognizer_states to_show)
+{
+  switch (to_show) {
+    case GET_ANY: return "get_any";
+    case GOT_DOT: return "got_dot";
+    case GOT_CHO: return "got_cho";
+    case RECOGNIZED: return "recognized";
+    case REJECTED: return "rejected";
+    default: return "unknown!";
+  }
+}
+
+#define TEST(action) \
+  if (!action) \
+    deadly_error(class_name(), "setup", a_sprintf("failed on %s", #action))
+
+void test_state_machine::setup_state_machine(transition_map &recog)
+{
+  TEST(recog.add_state(GET_ANY));
+  TEST(recog.add_state(GOT_DOT));
+  TEST(recog.add_state(GOT_CHO));
+  TEST(recog.add_state(RECOGNIZED));
+  TEST(recog.add_state(REJECTED));
+
+  TEST(recog.set_start(GET_ANY));
+
+// bogus for test!
+//TEST(recog.add_range_transition(GET_ANY, 29378, 0, 0));
+
+  TEST(recog.add_range_transition(GET_ANY, REJECTED, 0, 0));
+  TEST(recog.add_range_transition(GET_ANY, GET_ANY, 1, '.'-1));
+  TEST(recog.add_range_transition(GET_ANY, GOT_DOT, '.', '.'));
+  TEST(recog.add_range_transition(GET_ANY, GET_ANY, '.'+1, 255));
+
+  // we wouldn't need so many cases if the update function made the
+  // jump out of GOT_DOT when an unsatisfactory pulse is seen?
+  TEST(recog.add_range_transition(GOT_DOT, REJECTED, '\0', '\0'));
+  TEST(recog.add_range_transition(GOT_DOT, GET_ANY, 1, '.'-1));
+  TEST(recog.add_range_transition(GOT_DOT, GOT_DOT, '.', '.'));
+  TEST(recog.add_range_transition(GOT_DOT, GET_ANY, '.'+1, 'c'-1));
+  TEST(recog.add_range_transition(GOT_DOT, GOT_CHO, 'c', 'c'));
+  TEST(recog.add_range_transition(GOT_DOT, GET_ANY, 'c'+1, 'h'-1));
+  TEST(recog.add_range_transition(GOT_DOT, GOT_CHO, 'h', 'h'));
+  TEST(recog.add_range_transition(GOT_DOT, GET_ANY, 'h'+1, 'o'-1));
+  TEST(recog.add_range_transition(GOT_DOT, GOT_CHO, 'o', 'o'));
+  TEST(recog.add_range_transition(GOT_DOT, GET_ANY, 'o'+1, 255));
+/// if update was doing it; TEST(recog.add_simple_transition(GOT_DOT, GET_ANY));
+
+  TEST(recog.add_range_transition(GOT_CHO, RECOGNIZED, '\0', '\0'));
+  TEST(recog.add_range_transition(GOT_CHO, GET_ANY, 1, '.'-1));
+  TEST(recog.add_range_transition(GOT_CHO, GOT_DOT, '.', '.'));
+  TEST(recog.add_range_transition(GOT_CHO, GET_ANY, '.'+1, 255));
+
+  int hosed;
+  if (recog.validate(hosed) != transition_map::OKAY)
+    deadly_error(class_name(), "check_machine",
+        astring(astring::SPRINTF, "invalid state_machine due to state %d", hosed).s());
+}
+
+test_state_machine::test_state_machine()
+: application_shell()
+{}
+
+void test_state_machine::print_instructions()
+{
+  critical_events::alert_message("\
+This program demonstrates the state machine class by constructing a machine\n\
+that recognizes the regular expression *.[cho], which is all strings ending\n\
+in a period followed by c, h, or o.  The first parameter is the name of a\n\
+file to load strings from.\n");
+}
+
+int test_state_machine::execute()
+{
+  FUNCDEF("execute");
+  transition_map recog;
+  setup_state_machine(recog);
+
+  if (application::_global_argc < 2) {
+    print_instructions();
+    return 1;
+  }
+  astring filename = astring(application::_global_argv[1]);
+///  int indy = filename.find(' ');
+  if (!filename) {
+    print_instructions();
+    return 1;
+  }
+  ///filename.zap(indy, filename.end());
+
+  byte_filer fil(filename.s(), "r");
+
+//LOG(astring("filename is ") + filename.raw());
+
+  while (!fil.eof()) {
+    state_machine m;
+    recog.reset(m);
+
+    byte_array typed_string(901);
+//need a getline function for byte filer...
+    fil.getline(typed_string, 900);
+
+    int len = int(strlen((char *)typed_string.access()));
+    if (!len) continue;  // skip blank lines...
+
+    int position = 0;
+    while ( (m.current() != RECOGNIZED) && (m.current() != REJECTED) ) {
+      recog.pulse(m, typed_string[position++]);
+    }
+
+    if (m.current() == RECOGNIZED) {
+      LOG((char *)typed_string.access());
+    } else if (m.current() == REJECTED) {
+      LOG("rejected...");
+    } else {
+      LOG("unknown final state!");
+    }
+  }
+  return 0;
+}
+
+//////////////
+
+HOOPLE_MAIN(test_state_machine, )
+
index db6d5f65ded5f1a0e0fcf29d2998561a95928861..178ac2b162c250479b8fcc7cb533a734f7f2fa41 100644 (file)
@@ -2,7 +2,7 @@ include cpp/variables.def
 
 PROJECT = tests_timely
 TYPE = test
-TARGETS = test_earth_time.exe test_stopwatch.exe test_timer_driver.exe
+TARGETS = test_earth_time.exe test_stopwatch.exe test_timer_driver.exe test_time_stamp.exe
 DEFINITIONS += USE_FEISTY_MEOW_DLLS
 LOCAL_LIBS_USED = unit_test application processes loggers configuration mathematics nodes \
   structures textual timely filesystem structures basis 
diff --git a/nucleus/library/tests_timely/test_time_stamp.cpp b/nucleus/library/tests_timely/test_time_stamp.cpp
new file mode 100644 (file)
index 0000000..66efe02
--- /dev/null
@@ -0,0 +1,93 @@
+/*****************************************************************************\
+*                                                                             *
+*  Name   : test_time_stamp                                                   *
+*  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                               *
+\*****************************************************************************/
+
+#include <application/application_shell.h>
+#include <application/hoople_main.h>
+#include <basis/astring.h>
+#include <basis/guards.h>
+#include <loggers/program_wide_logger.h>
+#include <structures/static_memory_gremlin.h>
+#include <timely/time_control.h>
+#include <timely/time_stamp.h>
+#include <unit_test/unit_base.h>
+
+using namespace application;
+using namespace basis;
+using namespace loggers;
+using namespace structures;
+using namespace textual;
+using namespace timely;
+using namespace unit_test;
+
+#undef LOG
+#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
+
+//////////////
+
+//#define DEBUG_TIME_STAMP
+
+//const int RUN_DURATION = 5 * MINUTE_ms;
+const int RUN_DURATION = 3 * SECOND_ms;
+  // how long the test will run.
+
+const int SLEEP_DURATION = 42;
+  // the period of sleep between checks on the time stamp.
+
+const int REPORT_INTERVAL = 500;  // every half second.
+  // how often we show the current time stamp.
+
+//////////////
+
+class time_stamp_tester : virtual public unit_base, virtual public application_shell
+{
+public:
+  time_stamp_tester() : application_shell() {}
+
+  DEFINE_CLASS_NAME("time_stamp_tester");
+
+  int execute() {
+    time_stamp start;
+    log(a_sprintf("initial time stamp: %0.0f", start.value()));
+
+    time_stamp curr;
+    time_stamp get_out(RUN_DURATION);
+    time_stamp report_time(REPORT_INTERVAL);
+    int iterations = RUN_DURATION / SLEEP_DURATION;
+    while (iterations-- > 0) {
+      if (time_stamp() < curr)
+        deadly_error(class_name(), "compare test", "failure; now is less "
+            "than earlier!");
+
+//hmmm: how about some more verifications, like the sleep time we asked for is reflected (or nearly) in the time stamp difference?
+
+      time_control::sleep_ms(SLEEP_DURATION);
+      curr = time_stamp();
+      if (time_stamp() >= report_time) {
+        log(a_sprintf("current time stamp: %0.0f", time_stamp().value()));
+        report_time.reset(REPORT_INTERVAL);
+      }
+    }
+
+    time_stamp end;
+    log(a_sprintf(" ending time stamp: %0.0f", end.value()));
+
+    critical_events::alert_message("time_stamp:: works for those functions tested.");
+    return 0;
+  }
+};
+
+//////////////
+
+HOOPLE_MAIN(time_stamp_tester, )
+
index 0ed1692a350e7c00e8ba1bdaa8388827d8971020..12d31222c3051c20fac2cce4043a65059fe658eb 100644 (file)
@@ -163,6 +163,7 @@ standards and usages."
     | sed -e 's/^#include <mechanisms\/throughput_counter.h> *$/#include <sockets\/throughput_counter.h>/g' \
     | sed -e 's/^#include <application\/rendezvous.h> *$/#include <processes\/rendezvous.h>/g' \
     | sed -e 's/\([^A-Za-z0-9_]\)NIL\([^A-Za-z0-9_]\)/\1NULL_POINTER\2/g' \
+    | sed -e 's/^#include <mechanisms\/state_machine.h> *$/#include <processes\/state_machine.h>/g' \
     | sed -e 's/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/[\/]*/\/\/\/\/\/\/\/\/\/\/\/\/\/\//g' \
     >"$tempfile"