1 //--------------------------------------------------------------------------
2 // Copyright (C) 2020-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation. You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 //--------------------------------------------------------------------------
18
19 // memcap_allocator_test.cc author davis mcpherson <davmcphe@cisco.com>
20 // unit tests for MemCapAllocator class
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "../memcap_allocator.h"
27
28 #include <CppUTest/CommandLineTestRunner.h>
29 #include <CppUTest/TestHarness.h>
30
31 const unsigned long ALLOCATION_SIZE = 250;
32 const unsigned long NO_MEM_CAP_LIMIT = 0;
33 const unsigned NO_MEMCAP_LIMIT_ALLOCATIONS = 10000;
34
35 const unsigned long MEM_CAP_5000 = 5000;
36 const unsigned MAX_ALLOCATIONS_5000 = MEM_CAP_5000 / ALLOCATION_SIZE;
37
38 const unsigned long MEM_CAP_10000 = 10000;
39 const unsigned MAX_ALLOCATIONS_10000 = MEM_CAP_10000 / ALLOCATION_SIZE;
40
41 const unsigned long MEM_CAP_20000 = 20000;
42 const unsigned MAX_ALLOCATIONS_20000 = MEM_CAP_20000 / ALLOCATION_SIZE;
43
TEST_GROUP(memcap_allocator)44 TEST_GROUP(memcap_allocator)
45 { };
46
TEST(memcap_allocator,no_memcap_limit_allocator_test)47 TEST(memcap_allocator, no_memcap_limit_allocator_test)
48 {
49 MemCapAllocator* mca = new MemCapAllocator(NO_MEM_CAP_LIMIT, ALLOCATION_SIZE);
50 CHECK(mca);
51 CHECK(mca->get_allocation_size() == ALLOCATION_SIZE);
52 CHECK(mca->get_mem_capacity() == NO_MEM_CAP_LIMIT);
53 CHECK(mca->is_space_available());
54 CHECK(!mca->is_over_capacity());
55 CHECK(mca->get_mem_allocated() == 0);
56 CHECK(mca->get_allocation_requests() == 0);
57 CHECK(mca->get_free_requests() == 0);
58 CHECK(mca->get_no_memory_available() == 0);
59 delete mca;
60 }
61
TEST(memcap_allocator,no_memcap_limit_allocations_test)62 TEST(memcap_allocator, no_memcap_limit_allocations_test)
63 {
64 MemCapAllocator* mca = new MemCapAllocator(NO_MEM_CAP_LIMIT, ALLOCATION_SIZE);
65 CHECK(mca);
66
67 unsigned bytes_allocated;
68 uint8_t** mem_blocks = (uint8_t**)snort_alloc(sizeof(uint8_t*) * NO_MEMCAP_LIMIT_ALLOCATIONS);
69 for ( unsigned i = 0; i < NO_MEMCAP_LIMIT_ALLOCATIONS; i++)
70 {
71 mem_blocks[i] = (uint8_t*)mca->allocate();
72 bytes_allocated = (i + 1) * ALLOCATION_SIZE;
73 CHECK(mem_blocks[i]);
74 CHECK(mca->get_mem_allocated() == bytes_allocated);
75 CHECK(mca->is_space_available());
76 CHECK(!mca->is_over_capacity());
77 }
78
79 CHECK(mca->get_allocation_requests() == NO_MEMCAP_LIMIT_ALLOCATIONS);
80 CHECK(mca->get_free_requests() == 0);
81 CHECK(mca->get_no_memory_available() == 0);
82
83 for ( unsigned i = 0; i < NO_MEMCAP_LIMIT_ALLOCATIONS; i++)
84 {
85 mca->free(mem_blocks[i]);
86 bytes_allocated = (NO_MEMCAP_LIMIT_ALLOCATIONS - (i + 1)) * ALLOCATION_SIZE;
87 CHECK(mca->get_mem_allocated() == bytes_allocated);
88 }
89
90 CHECK(mca->is_space_available());
91 CHECK(!mca->is_over_capacity());
92 CHECK(mca->get_mem_allocated() == 0);
93 CHECK(mca->get_free_requests() == NO_MEMCAP_LIMIT_ALLOCATIONS);
94 CHECK(mca->get_no_memory_available() == 0);
95
96 snort_free(mem_blocks);
97 delete mca;
98 }
99
TEST(memcap_allocator,create_memcap_allocator_test)100 TEST(memcap_allocator, create_memcap_allocator_test)
101 {
102 MemCapAllocator* mca = new MemCapAllocator(MEM_CAP_10000, ALLOCATION_SIZE);
103 CHECK(mca);
104 CHECK(mca->get_allocation_size() == ALLOCATION_SIZE);
105 CHECK(mca->get_mem_capacity() == MEM_CAP_10000);
106 mca->set_mem_capacity(MEM_CAP_20000);
107 CHECK(mca->get_mem_capacity() == MEM_CAP_20000);
108 CHECK(mca->get_mem_allocated() == 0);
109 CHECK(mca->get_allocation_requests() == 0);
110 CHECK(mca->get_free_requests() == 0);
111 CHECK(mca->get_no_memory_available() == 0);
112 delete mca;
113 }
114
TEST(memcap_allocator,allocate_and_free_memory_test)115 TEST(memcap_allocator, allocate_and_free_memory_test)
116 {
117 MemCapAllocator* mca = new MemCapAllocator(MEM_CAP_10000, ALLOCATION_SIZE);
118 CHECK(mca);
119 CHECK(mca->is_space_available());
120 CHECK(!mca->is_over_capacity());
121
122 uint8_t* mem = (uint8_t*)mca->allocate();
123 CHECK(mem);
124 CHECK(mca->get_mem_allocated() == ALLOCATION_SIZE);
125 CHECK(mca->is_space_available());
126 CHECK(!mca->is_over_capacity());
127 CHECK(mca->get_allocation_requests() == 1);
128 CHECK(mca->get_free_requests() == 0);
129 CHECK(mca->get_no_memory_available() == 0);
130
131 mca->free(mem);
132 CHECK(mca->get_mem_allocated() == 0);
133 CHECK(mca->is_space_available());
134 CHECK(!mca->is_over_capacity());
135 CHECK(mca->get_allocation_requests() == 1);
136 CHECK(mca->get_free_requests() == 1);
137 CHECK(mca->get_no_memory_available() == 0);
138
139 delete mca;
140 }
141
TEST(memcap_allocator,max_allocations_test)142 TEST(memcap_allocator, max_allocations_test)
143 {
144 MemCapAllocator* mca = new MemCapAllocator(MEM_CAP_10000, ALLOCATION_SIZE);
145 CHECK(mca);
146
147 unsigned bytes_allocated;
148 uint8_t* mem_blocks[MAX_ALLOCATIONS_10000];
149 for ( unsigned i = 0; i < MAX_ALLOCATIONS_10000; i++)
150 {
151 mem_blocks[i] = (uint8_t*)mca->allocate();
152 bytes_allocated = (i + 1) * ALLOCATION_SIZE;
153 CHECK(mem_blocks[i]);
154 CHECK(mca->get_mem_allocated() == bytes_allocated);
155 if ( i < MAX_ALLOCATIONS_10000 - 1 )
156 {
157 CHECK(mca->is_space_available());
158 }
159 else
160 {
161 CHECK(!mca->is_space_available());
162 }
163 CHECK(!mca->is_over_capacity());
164 }
165 CHECK(mca->get_allocation_requests() == MAX_ALLOCATIONS_10000);
166 CHECK(mca->get_free_requests() == 0);
167 CHECK(mca->get_no_memory_available() == 0);
168
169 uint8_t* mem = (uint8_t*)mca->allocate();
170 CHECK(!mem);
171 CHECK(mca->get_no_memory_available() == 1);
172 mem = (uint8_t*)mca->allocate();
173 CHECK(!mem);
174 mem = (uint8_t*)mca->allocate();
175 CHECK(!mem);
176 CHECK(mca->get_no_memory_available() == 3);
177 mca->free(mem_blocks[0]);
178 mem_blocks[0] = (uint8_t*)mca->allocate();
179 CHECK(mem_blocks[0]);
180 CHECK(mca->get_free_requests() == 1);
181 CHECK(mca->get_no_memory_available() == 3);
182
183 mca->set_mem_capacity(MEM_CAP_20000);
184 mem = (uint8_t*)mca->allocate();
185 CHECK(mem);
186 mca->set_mem_capacity(MEM_CAP_5000);
187 CHECK(mca->is_over_capacity());
188 mca->free(mem);
189 CHECK(mca->get_free_requests() == 2);
190
191 for ( unsigned i = 0; i < MAX_ALLOCATIONS_5000; i++)
192 {
193 CHECK(!mca->is_space_available());
194 mca->free(mem_blocks[i]);
195 bytes_allocated = (MAX_ALLOCATIONS_10000 - (i + 1)) * ALLOCATION_SIZE;
196 CHECK(mca->get_mem_allocated() == bytes_allocated);
197 }
198
199 CHECK(!mca->is_space_available());
200 CHECK(!mca->is_over_capacity());
201
202 for ( unsigned i = MAX_ALLOCATIONS_5000; i < MAX_ALLOCATIONS_10000; i++)
203 {
204 mca->free(mem_blocks[i]);
205 bytes_allocated = (MAX_ALLOCATIONS_10000 - (i + 1)) * ALLOCATION_SIZE;
206 CHECK(mca->get_mem_allocated() == bytes_allocated);
207 CHECK(mca->is_space_available());
208 CHECK(!mca->is_over_capacity());
209 }
210
211 CHECK(mca->get_mem_allocated() == 0);
212 CHECK(mca->get_free_requests() == MAX_ALLOCATIONS_10000 + 2);
213 CHECK(mca->get_no_memory_available() == 3);
214
215 delete mca;
216 }
217
main(int argc,char ** argv)218 int main(int argc, char** argv)
219 {
220 return CommandLineTestRunner::RunAllTests(argc, argv);
221 }
222