]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/test/pcep_utils_memory_test.c
Merge pull request #8174 from mjstapp/backup_nht
[mirror_frr.git] / pceplib / test / pcep_utils_memory_test.c
1 /*
2 * This file is part of the PCEPlib, a PCEP protocol library.
3 *
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 *
19 * Author : Brady Johnson <brady@voltanet.io>
20 *
21 */
22
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <stdlib.h>
29 #include <stdint.h>
30
31 #include <CUnit/CUnit.h>
32
33 #include "pcep_utils_memory.h"
34 #include "pcep_utils_memory_test.h"
35
36 void *test_pceplib_malloc(void *mem_type, size_t size);
37 void *test_pceplib_calloc(void *mem_type, size_t size);
38 void *test_pceplib_realloc(void *mem_type, void *ptr, size_t size);
39 void *test_pceplib_strdup(void *mem_type, const char *str);
40 void test_pceplib_free(void *mem_type, void *ptr);
41 void verify_memory_type(struct pceplib_memory_type *mt, uint32_t num_alloc,
42 uint32_t alloc_bytes, uint32_t num_free,
43 uint32_t free_bytes);
44 void verify_ext_memory_type(void *mt, int num_malloc_calls,
45 int num_calloc_calls, int num_realloc_calls,
46 int num_strdup_calls, int num_free_calls);
47
48 struct test_memory_type {
49 int num_malloc_calls;
50 int num_calloc_calls;
51 int num_realloc_calls;
52 int num_strdup_calls;
53 int num_free_calls;
54 };
55
56 void *test_pceplib_malloc(void *mem_type, size_t size)
57 {
58 ((struct test_memory_type *)mem_type)->num_malloc_calls++;
59 return malloc(size);
60 }
61
62 void *test_pceplib_calloc(void *mem_type, size_t size)
63 {
64 ((struct test_memory_type *)mem_type)->num_calloc_calls++;
65 return calloc(1, size);
66 }
67
68 void *test_pceplib_realloc(void *mem_type, void *ptr, size_t size)
69 {
70 ((struct test_memory_type *)mem_type)->num_realloc_calls++;
71 return realloc(ptr, size);
72 }
73
74 void *test_pceplib_strdup(void *mem_type, const char *str)
75 {
76 ((struct test_memory_type *)mem_type)->num_strdup_calls++;
77 return strdup(str);
78 }
79
80 void test_pceplib_free(void *mem_type, void *ptr)
81 {
82 ((struct test_memory_type *)mem_type)->num_free_calls++;
83 free(ptr);
84 }
85
86 void verify_memory_type(struct pceplib_memory_type *mt, uint32_t num_alloc,
87 uint32_t alloc_bytes, uint32_t num_free,
88 uint32_t free_bytes)
89 {
90 CU_ASSERT_EQUAL(num_alloc, mt->num_allocates);
91 CU_ASSERT_EQUAL(alloc_bytes, mt->total_bytes_allocated);
92 CU_ASSERT_EQUAL(num_free, mt->num_frees);
93 CU_ASSERT_EQUAL(free_bytes, mt->total_bytes_freed);
94 }
95
96 void verify_ext_memory_type(void *mt, int num_malloc_calls,
97 int num_calloc_calls, int num_realloc_calls,
98 int num_strdup_calls, int num_free_calls)
99 {
100 struct test_memory_type *mt_ptr = (struct test_memory_type *)mt;
101 CU_ASSERT_EQUAL(num_malloc_calls, mt_ptr->num_malloc_calls);
102 CU_ASSERT_EQUAL(num_calloc_calls, mt_ptr->num_calloc_calls);
103 CU_ASSERT_EQUAL(num_realloc_calls, mt_ptr->num_realloc_calls);
104 CU_ASSERT_EQUAL(num_strdup_calls, mt_ptr->num_strdup_calls);
105 CU_ASSERT_EQUAL(num_free_calls, mt_ptr->num_free_calls);
106 }
107
108 void test_memory_internal_impl()
109 {
110 int alloc_size = 100;
111 struct pceplib_memory_type *pceplib_infra_ptr =
112 (struct pceplib_memory_type *)PCEPLIB_INFRA;
113 struct pceplib_memory_type *pceplib_messages_ptr =
114 (struct pceplib_memory_type *)PCEPLIB_MESSAGES;
115 int alloc_counter = 1;
116 int free_counter = 1;
117
118 /* reset the memory type counters for easier testing */
119 pceplib_infra_ptr->num_allocates =
120 pceplib_infra_ptr->total_bytes_allocated =
121 pceplib_infra_ptr->num_frees =
122 pceplib_infra_ptr->total_bytes_freed = 0;
123 pceplib_messages_ptr->num_allocates =
124 pceplib_messages_ptr->total_bytes_allocated =
125 pceplib_messages_ptr->num_frees =
126 pceplib_messages_ptr->total_bytes_freed = 0;
127
128 /* Make sure nothing crashes when all these are set NULL, since the
129 * internal default values should still be used. */
130 pceplib_memory_initialize(NULL, NULL, NULL, NULL, NULL, NULL, NULL);
131
132 /* Test malloc() */
133 void *ptr = pceplib_malloc(PCEPLIB_INFRA, alloc_size);
134 CU_ASSERT_PTR_NOT_NULL(ptr);
135 pceplib_free(PCEPLIB_INFRA, ptr);
136 verify_memory_type(pceplib_infra_ptr, alloc_counter, alloc_size,
137 free_counter++, 0);
138
139 /* Test calloc() */
140 ptr = pceplib_calloc(PCEPLIB_INFRA, alloc_size);
141 CU_ASSERT_PTR_NOT_NULL(ptr);
142 pceplib_free(PCEPLIB_INFRA, ptr);
143 alloc_counter++;
144 verify_memory_type(pceplib_infra_ptr, alloc_counter,
145 alloc_size * alloc_counter, free_counter++, 0);
146
147 /* Test realloc() */
148 ptr = pceplib_malloc(PCEPLIB_INFRA, alloc_size);
149 CU_ASSERT_PTR_NOT_NULL(ptr);
150 ptr = pceplib_realloc(PCEPLIB_INFRA, ptr, alloc_size);
151 CU_ASSERT_PTR_NOT_NULL(ptr);
152 pceplib_free(PCEPLIB_INFRA, ptr);
153 alloc_counter += 2;
154 verify_memory_type(pceplib_infra_ptr, alloc_counter,
155 alloc_size * alloc_counter, free_counter++, 0);
156
157 /* Test strdup() */
158 ptr = pceplib_malloc(PCEPLIB_INFRA, alloc_size);
159 /* Make strdup duplicate (alloc_size - 1) bytes */
160 memset(ptr, 'a', alloc_size);
161 ((char *)ptr)[alloc_size - 1] = '\0';
162 char *str = pceplib_strdup(PCEPLIB_INFRA, (char *)ptr);
163 CU_ASSERT_PTR_NOT_NULL(ptr);
164 pceplib_free(PCEPLIB_INFRA, ptr);
165 pceplib_free(PCEPLIB_INFRA, str);
166 alloc_counter += 2;
167 free_counter++;
168 verify_memory_type(pceplib_infra_ptr, alloc_counter,
169 (alloc_size * alloc_counter) - 1, free_counter, 0);
170
171 /* Make sure only the pceplib_infra_ptr memory counters are incremented
172 */
173 verify_memory_type(pceplib_messages_ptr, 0, 0, 0, 0);
174 }
175
176 void test_memory_external_impl()
177 {
178 int alloc_size = 100;
179 struct pceplib_memory_type *pceplib_infra_ptr =
180 (struct pceplib_memory_type *)PCEPLIB_INFRA;
181 struct pceplib_memory_type *pceplib_messages_ptr =
182 (struct pceplib_memory_type *)PCEPLIB_MESSAGES;
183
184 /* reset the internal memory type counters to later verify they are NOT
185 * incremented since an external impl was provided */
186 pceplib_infra_ptr->num_allocates =
187 pceplib_infra_ptr->total_bytes_allocated =
188 pceplib_infra_ptr->num_frees =
189 pceplib_infra_ptr->total_bytes_freed = 0;
190 pceplib_messages_ptr->num_allocates =
191 pceplib_messages_ptr->total_bytes_allocated =
192 pceplib_messages_ptr->num_frees =
193 pceplib_messages_ptr->total_bytes_freed = 0;
194
195 /* Setup the external memory type */
196 struct test_memory_type infra_mt, messages_mt;
197 void *infra_ptr = &infra_mt;
198 void *messages_ptr = &messages_mt;
199 memset(infra_ptr, 0, sizeof(struct test_memory_type));
200 memset(messages_ptr, 0, sizeof(struct test_memory_type));
201 int free_counter = 1;
202
203 /* Initialize the PCEPlib memory system with an external implementation
204 */
205 pceplib_memory_initialize(infra_ptr, messages_ptr, test_pceplib_malloc,
206 test_pceplib_calloc, test_pceplib_realloc,
207 test_pceplib_strdup, test_pceplib_free);
208
209 /* Test malloc() */
210 void *ptr = pceplib_malloc(PCEPLIB_MESSAGES, alloc_size);
211 CU_ASSERT_PTR_NOT_NULL(ptr);
212 pceplib_free(PCEPLIB_MESSAGES, ptr);
213 verify_ext_memory_type(messages_ptr, 1, 0, 0, 0, free_counter++);
214
215 /* Test calloc() */
216 ptr = pceplib_calloc(PCEPLIB_MESSAGES, alloc_size);
217 CU_ASSERT_PTR_NOT_NULL(ptr);
218 pceplib_free(PCEPLIB_MESSAGES, ptr);
219 verify_ext_memory_type(messages_ptr, 1, 1, 0, 0, free_counter++);
220
221 /* Test realloc() */
222 ptr = pceplib_malloc(PCEPLIB_MESSAGES, alloc_size);
223 CU_ASSERT_PTR_NOT_NULL(ptr);
224 ptr = pceplib_realloc(PCEPLIB_MESSAGES, ptr, alloc_size);
225 CU_ASSERT_PTR_NOT_NULL(ptr);
226 pceplib_free(PCEPLIB_MESSAGES, ptr);
227 verify_ext_memory_type(messages_ptr, 2, 1, 1, 0, free_counter++);
228
229 /* Test strdup() */
230 ptr = pceplib_malloc(PCEPLIB_MESSAGES, alloc_size);
231 /* Make strdup duplicate (alloc_size - 1) bytes */
232 memset(ptr, 'a', alloc_size);
233 ((char *)ptr)[alloc_size - 1] = '\0';
234 char *str = pceplib_strdup(PCEPLIB_MESSAGES, (char *)ptr);
235 CU_ASSERT_PTR_NOT_NULL(ptr);
236 pceplib_free(PCEPLIB_MESSAGES, ptr);
237 pceplib_free(PCEPLIB_MESSAGES, str);
238 verify_ext_memory_type(messages_ptr, 3, 1, 1, 1, free_counter + 1);
239
240 /* Make sure the internal memory counters are NOT incremented */
241 verify_memory_type(pceplib_infra_ptr, 0, 0, 0, 0);
242 verify_memory_type(pceplib_messages_ptr, 0, 0, 0, 0);
243
244 verify_ext_memory_type(infra_ptr, 0, 0, 0, 0, 0);
245 }