feisty meow concerns codebase 2.140
test_memory_limiter.cpp
Go to the documentation of this file.
1/*****************************************************************************\
2* *
3* Name : test_memory_limiter *
4* Author : Chris Koeritz *
5* *
6* Purpose: *
7* *
8* Tests that the memory_limiter is keeping track of the memory users *
9* accurately. *
10* *
11*******************************************************************************
12* Copyright (c) 2000-$now By Author. This program is free software; you can *
13* redistribute it and/or modify it under the terms of the GNU General Public *
14* License as published by the Free Software Foundation; either version 2 of *
15* the License or (at your option) any later version. This is online at: *
16* http://www.fsf.org/copyleft/gpl.html *
17* Please send any updates to: fred@gruntose.com *
18\*****************************************************************************/
19
20//#define DEBUG_MEMORY_LIMITER
21 // uncomment for debugging version.
22
24#include <basis/guards.h>
25#include <basis/astring.h>
27#include <mathematics/chaos.h>
29#include <structures/set.h>
31#include <timely/time_stamp.h>
32#include <unit_test/unit_base.h>
33
34#ifdef DEBUG_MEMORY_LIMITER
35 #include <stdio.h>
36#endif
37
38using namespace application;
39using namespace basis;
40using namespace filesystem;
41using namespace loggers;
42using namespace mathematics;
43using namespace structures;
44using namespace textual;
45using namespace timely;
46using namespace unit_test;
47
48#define LOG(to_print) EMERGENCY_LOG(program_wide_logger().get(), astring(to_print))
49
52
53const int RUN_TIME = .8 * SECOND_ms;
54
56
57class test_memory_limiter : virtual public unit_base, virtual public application_shell
58{
59public:
60 test_memory_limiter() {}
61 DEFINE_CLASS_NAME("test_memory_limiter");
62 virtual int execute();
63};
64
66
67struct mem_record {
68 int parent;
69 int allocated;
70
71 mem_record(int parent_in = 0, int allocated_in = 0)
72 : parent(parent_in), allocated(allocated_in) {}
73};
74
75struct memorial : array<mem_record> {};
76
78
79int test_memory_limiter::execute()
80{
81 FUNCDEF("execute");
82 time_stamp when_to_leave(RUN_TIME);
83 time_stamp start;
84 memorial wtc;
86 int allocations = 0;
87 int deletions = 0;
88 basis::un_int total_allocated = 0;
89 basis::un_int total_deleted = 0;
90 while (time_stamp() < when_to_leave) {
91 int to_do = randomizer().inclusive(1, 100);
92 if (to_do < 50) {
93 // add a new record.
94 int alloc = randomizer().inclusive(1, 1 * MEGABYTE);
95//isolate min max alloc
96 int parent = randomizer().inclusive(1, 120);
97//isolate min max parents
98
99 if (!to_test.okay_allocation(parent, alloc))
100 continue; // no space right now.
101 wtc += mem_record(parent, alloc);
102 allocations++;
103 total_allocated += alloc;
104 } else if (to_do < 88) {
105 // remove an existing record.
106 if (!wtc.length()) continue; // nothing to remove.
107 int indy = randomizer().inclusive(0, wtc.length() - 1);
108 mem_record to_gone = wtc[indy];
109 wtc.zap(indy, indy);
110 ASSERT_TRUE(to_test.record_deletion(to_gone.parent, to_gone.allocated),
111 "first case failed to record deletion!");
112 deletions++;
113 total_deleted += to_gone.allocated;
114 } else {
115//do something funky, like allocate part of one into another...
116 }
117 }
118
119 // now clear everything left in our list.
120 for (int i = 0; i < wtc.length(); i++) {
121 mem_record to_gone = wtc[i];
122 ASSERT_TRUE(to_test.record_deletion(to_gone.parent, to_gone.allocated),
123 "second case failed to record deletion!");
124 deletions++;
125 total_deleted += to_gone.allocated;
126 }
127
128 // now check that the memory limiter has returned to camber.
129
130 ASSERT_FALSE(to_test.overall_usage(), "final checks: there is still memory in use!");
131
132 ASSERT_EQUAL(to_test.overall_space_left(), MAXIMUM_MEM_OVERALL,
133 "final checks: the free space is not correct!");
134
135 int_set remaining = to_test.individuals_listed();
136 ASSERT_FALSE(remaining.elements(), "final checks: there were still uncleared individuals!");
137
138 time_stamp end;
139
140 LOG("stats for this run:");
141 LOG(astring(astring::SPRINTF, "\trun time %f ms",
142 end.value() - start.value()));
143 LOG(astring(astring::SPRINTF, "\tallocations %d, total memory allocated %d",
144 allocations, total_allocated));
145 LOG(astring(astring::SPRINTF, "\tdeletions %d, total memory deleted %d",
146 deletions, total_deleted));
147
148 return final_report();
149}
150
152
153HOOPLE_MAIN(test_memory_limiter, );
154
The application_shell is a base object for console programs.
virtual int execute()=0
< retrieves the command line from the /proc hierarchy on linux.
Represents a sequential, ordered, contiguous collection of objects.
Definition array.h:54
Provides a dynamically resizable ASCII character string.
Definition astring.h:35
A simple object that wraps a templated set of ints.
Definition set.h:156
Tracks memory currently in use by memory manager objects.
int elements() const
Returns the number of elements in this set.
Definition set.h:47
Represents a point in time relative to the operating system startup time.
Definition time_stamp.h:38
time_representation value() const
returns the time_stamp in terms of the lower level type.
Definition time_stamp.h:61
#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
const int MEGABYTE
Number of bytes in a megabyte.
const int SECOND_ms
Number of milliseconds in a second.
unsigned int un_int
Abbreviated name for unsigned integers.
Definition definitions.h:62
const int KILOBYTE
Number of bytes in a kilobyte.
A platform independent way to obtain the timestamp of a file.
A logger that sends to the console screen using the standard output device.
An extension to floating point primitives providing approximate equality.
Definition averager.h:21
A dynamic container class that holds any kind of object via pointers.
Definition amorph.h:55
#include <time.h>
Useful support functions for unit testing, especially within hoople.
Definition unit_base.cpp:35
#define randomizer()
const int RUN_TIME
const int MAXIMUM_MEM_PER_OWNER
const int MAXIMUM_MEM_OVERALL
#define LOG(to_print)
#define ASSERT_EQUAL(a, b, test_name)
Definition unit_base.h:38
#define ASSERT_TRUE(a, test_name)
Definition unit_base.h:46
#define ASSERT_FALSE(a, test_name)
Definition unit_base.h:50