feisty meow concerns codebase  2.140
test_callstack_tracker.cpp
Go to the documentation of this file.
1 /*
2 *
3 * Name : test_callstack_tracker
4 * Author : Chris Koeritz
5 *
6 * Purpose:
7 *
8 * Puts the callstack tracking code through its paces, a bit.
9 *
10 ****
11 * Copyright (c) 1992-$now By Author. This program is free software; you can
12 * redistribute it and/or modify it under the terms of the GNU General Public
13 * License as published by the Free Software Foundation; either version 2 of
14 * the License or (at your option) any later version. This is online at:
15 * http://www.fsf.org/copyleft/gpl.html
16 * Please send any updates to: fred@gruntose.com
17 */
18 
19 #include <basis/functions.h>
20 #include <basis/guards.h>
21 #include <basis/astring.h>
22 
26 #include <loggers/console_logger.h>
29 #include <filesystem/filename.h>
32 #include <unit_test/unit_base.h>
33 
34 using namespace application;
35 using namespace basis;
36 using namespace filesystem;
37 using namespace loggers;
38 using namespace structures;
39 using namespace unit_test;
40 
41 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
42 
44 
45 class test_callstack_tracker : virtual public unit_base, virtual public application_shell
46 {
47 public:
48  test_callstack_tracker() : application_shell() {}
49  DEFINE_CLASS_NAME("test_callstack_tracker");
50  // our test suite...
51  int run_filestack_simple();
52  int run_filestack_middling();
53  int run_filestack_complex();
54  int execute();
55 
56 private:
57  int sub_call_1();
58  int sub_call_2();
59  int sub_call_3();
60  int sub_call_4();
61 
62  int recursive_factorial(int num);
63 };
64 
66 
67 int test_callstack_tracker::run_filestack_simple()
68 {
69  FUNCDEF("run_filestack_simple")
70  #ifdef ENABLE_CALLSTACK_TRACKING
71  // just shows this method's own stack.
72  GET_AND_TEST_STACK_TRACE("trace of simple stack:", 1);
73  #endif
74  return 0;
75 }
76 
78 
79 int test_callstack_tracker::sub_call_1()
80 {
81  FUNCDEF("sub_call_1")
82  return sub_call_2();
83 }
84 
85 int test_callstack_tracker::sub_call_2()
86 {
87  FUNCDEF("sub_call_2");
88  return sub_call_3();
89 }
90 
91 int test_callstack_tracker::sub_call_3()
92 {
93  FUNCDEF("sub_call_3")
94  return sub_call_4();
95 }
96 
97 int test_callstack_tracker::sub_call_4()
98 {
99  FUNCDEF("sub_call_4");
100  #ifdef ENABLE_CALLSTACK_TRACKING
101  // just shows this method's own stack.
102  GET_AND_TEST_STACK_TRACE("trace of middling stack:", 1);
103  #endif
104  return 0;
105 }
106 
107 int test_callstack_tracker::run_filestack_middling()
108 {
109  FUNCDEF("run_filestack_middling");
110  int retval = 0;
111  #ifdef ENABLE_CALLSTACK_TRACKING
112  // show a couple calls in using our sub_calls.
113  retval = sub_call_1();
114  #endif
115  return retval;
116 }
117 
118 int test_callstack_tracker::run_filestack_complex()
119 {
120  FUNCDEF("run_filestack_complex")
121  int fact_sought = 12;
122  int factotum = recursive_factorial(12);
123  LOG(a_sprintf("factorial of %d was computed as %d", fact_sought, factotum));
124  if (factotum < 0) {
125  // uh-oh, there was an actual failure of some sort.
126  return 1;
127  }
128  return 0;
129 }
130 
132 
133 int test_callstack_tracker::recursive_factorial(int num)
134 {
135  FUNCDEF("recursive_factorial")
136  if (num < 0) {
137  return -1; // signifies that things have gone badly.
138  }
139  if (num <= 1) {
140  #ifdef ENABLE_CALLSTACK_TRACKING
141  // now show the callstack, since we should be at the deepest level of nesting for this factorial implementation.
142  GET_AND_TEST_STACK_TRACE("trace of recursive_factorial:", -1);
143  #endif
144  return 1;
145  } else {
146  return num * recursive_factorial(num - 1);
147  }
148 }
149 
151 
152 int test_callstack_tracker::execute()
153 {
154  FUNCDEF("execute");
155 
156 //hmmm: do we really want the test to fail out for any subtest failure? maybe so?
157  int ret = run_filestack_simple();
158  if (ret) return ret;
159  ret = run_filestack_middling();
160  if (ret) return ret;
161  ret = run_filestack_complex();
162  if (ret) return ret;
163 
164  critical_events::alert_message(astring(class_name()) + ": works for those functions tested.");
165 
166  return final_report();
167 }
168 
169 HOOPLE_MAIN(test_callstack_tracker, )
170 
#define GET_AND_TEST_STACK_TRACE(header, failure_return)
The application_shell is a base object for console programs.
a_sprintf is a specialization of astring that provides printf style support.
Definition: astring.h:440
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
Definition: enhance_cpp.h:42
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition: enhance_cpp.h:54
Provides macros that implement the 'main' program of an application.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Definition: hoople_main.h:61
Implements an application lock to ensure only one is running at once.
The guards collection helps in testing preconditions and reporting errors.
Definition: array.h:30
A platform independent way to obtain the timestamp of a file.
Definition: byte_filer.cpp:37
A logger that sends to the console screen using the standard output device.
A dynamic container class that holds any kind of object via pointers.
Definition: amorph.h:55
Useful support functions for unit testing, especially within hoople.
Definition: unit_base.cpp:35
#define LOG(s)