]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/test/pcep_utils_memory_test.c
Merge pull request #8225 from idryzhov/bfd-echo-mode
[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 #include <stdlib.h>
25 #include <stdint.h>
26
27 #include <CUnit/CUnit.h>
28
29 #include "pcep_utils_memory.h"
30 #include "pcep_utils_memory_test.h"
31
32 void *test_pceplib_malloc(void *mem_type, size_t size);
33 void *test_pceplib_calloc(void *mem_type, size_t size);
34 void *test_pceplib_realloc(void *mem_type, void *ptr, size_t size);
35 void *test_pceplib_strdup(void *mem_type, const char *str);
36 void test_pceplib_free(void *mem_type, void *ptr);
37 void verify_memory_type(struct pceplib_memory_type *mt, uint32_t num_alloc,
38 uint32_t alloc_bytes, uint32_t num_free,
39 uint32_t free_bytes);
40 void verify_ext_memory_type(void *mt, int num_malloc_calls,
41 int num_calloc_calls, int num_realloc_calls,
42 int num_strdup_calls, int num_free_calls);
43
44 struct test_memory_type {
45 int num_malloc_calls;
46 int num_calloc_calls;
47 int num_realloc_calls;
48 int num_strdup_calls;
49 int num_free_calls;
50 };
51
52 void *test_pceplib_malloc(void *mem_type, size_t size)
53 {
54 ((struct test_memory_type *)mem_type)->num_malloc_calls++;
55 return malloc(size);
56 }
57
58 void *test_pceplib_calloc(void *mem_type, size_t size)
59 {
60 ((struct test_memory_type *)mem_type)->num_calloc_calls++;
61 return calloc(1, size);
62 }
63
64 void *test_pceplib_realloc(void *mem_type, void *ptr, size_t size)
65 {
66 ((struct test_memory_type *)mem_type)->num_realloc_calls++;
67 return realloc(ptr, size);
68 }
69
70 void *test_pceplib_strdup(void *mem_type, const char *str)
71 {
72 ((struct test_memory_type *)mem_type)->num_strdup_calls++;
73 return strdup(str);
74 }
75
76 void test_pceplib_free(void *mem_type, void *ptr)
77 {
78 ((struct test_memory_type *)mem_type)->num_free_calls++;
79 free(ptr);
80 }
81
82 void verify_memory_type(struct pceplib_memory_type *mt, uint32_t num_alloc,
83 uint32_t alloc_bytes, uint32_t num_free,
84 uint32_t free_bytes)
85 {
86 CU_ASSERT_EQUAL(num_alloc, mt->num_allocates);
87 CU_ASSERT_EQUAL(alloc_bytes, mt->total_bytes_allocated);
88 CU_ASSERT_EQUAL(num_free, mt->num_frees);
89 CU_ASSERT_EQUAL(free_bytes, mt->total_bytes_freed);
90 }
91
92 void verify_ext_memory_type(void *mt, int num_malloc_calls,
93 int num_calloc_calls, int num_realloc_calls,
94 int num_strdup_calls, int num_free_calls)
95 {
96 struct test_memory_type *mt_ptr = (struct test_memory_type *)mt;
97 CU_ASSERT_EQUAL(num_malloc_calls, mt_ptr->num_malloc_calls);
98 CU_ASSERT_EQUAL(num_calloc_calls, mt_ptr->num_calloc_calls);
99 CU_ASSERT_EQUAL(num_realloc_calls, mt_ptr->num_realloc_calls);
100 CU_ASSERT_EQUAL(num_strdup_calls, mt_ptr->num_strdup_calls);
101 CU_ASSERT_EQUAL(num_free_calls, mt_ptr->num_free_calls);
102 }
103
104 void test_memory_internal_impl()
105 {
106 int alloc_size = 100;
107 struct pceplib_memory_type *pceplib_infra_ptr =
108 (struct pceplib_memory_type *)PCEPLIB_INFRA;
109 struct pceplib_memory_type *pceplib_messages_ptr =
110 (struct pceplib_memory_type *)PCEPLIB_MESSAGES;
111 int alloc_counter = 1;
112 int free_counter = 1;
113
114 /* reset the memory type counters for easier testing */
115 pceplib_infra_ptr->num_allocates =
116 pceplib_infra_ptr->total_bytes_allocated =
117 pceplib_infra_ptr->num_frees =
118 pceplib_infra_ptr->total_bytes_freed = 0;
119 pceplib_messages_ptr->num_allocates =
120 pceplib_messages_ptr->total_bytes_allocated =
121 pceplib_messages_ptr->num_frees =
122 pceplib_messages_ptr->total_bytes_freed = 0;
123
124 /* Make sure nothing crashes when all these are set NULL, since the
125 * internal default values should still be used. */
126 pceplib_memory_initialize(NULL, NULL, NULL, NULL, NULL, NULL, NULL);
127
128 /* Test malloc() */
129 void *ptr = pceplib_malloc(PCEPLIB_INFRA, alloc_size);
130 CU_ASSERT_PTR_NOT_NULL(ptr);
131 pceplib_free(PCEPLIB_INFRA, ptr);
132 verify_memory_type(pceplib_infra_ptr, alloc_counter, alloc_size,
133 free_counter++, 0);
134
135 /* Test calloc() */
136 ptr = pceplib_calloc(PCEPLIB_INFRA, alloc_size);
137 CU_ASSERT_PTR_NOT_NULL(ptr);
138 pceplib_free(PCEPLIB_INFRA, ptr);
139 alloc_counter++;
140 verify_memory_type(pceplib_infra_ptr, alloc_counter,
141 alloc_size * alloc_counter, free_counter++, 0);
142
143 /* Test realloc() */
144 ptr = pceplib_malloc(PCEPLIB_INFRA, alloc_size);
145 CU_ASSERT_PTR_NOT_NULL(ptr);
146 ptr = pceplib_realloc(PCEPLIB_INFRA, ptr, alloc_size);
147 CU_ASSERT_PTR_NOT_NULL(ptr);
148 pceplib_free(PCEPLIB_INFRA, ptr);
149 alloc_counter += 2;
150 verify_memory_type(pceplib_infra_ptr, alloc_counter,
151 alloc_size * alloc_counter, free_counter++, 0);
152
153 /* Test strdup() */
154 ptr = pceplib_malloc(PCEPLIB_INFRA, alloc_size);
155 /* Make strdup duplicate (alloc_size - 1) bytes */
156 memset(ptr, 'a', alloc_size);
157 ((char *)ptr)[alloc_size - 1] = '\0';
158 char *str = pceplib_strdup(PCEPLIB_INFRA, (char *)ptr);
159 CU_ASSERT_PTR_NOT_NULL(ptr);
160 pceplib_free(PCEPLIB_INFRA, ptr);
161 pceplib_free(PCEPLIB_INFRA, str);
162 alloc_counter += 2;
163 free_counter++;
164 verify_memory_type(pceplib_infra_ptr, alloc_counter,
165 (alloc_size * alloc_counter) - 1, free_counter, 0);
166
167 /* Make sure only the pceplib_infra_ptr memory counters are incremented
168 */
169 verify_memory_type(pceplib_messages_ptr, 0, 0, 0, 0);
170 }
171
172 void test_memory_external_impl()
173 {
174 int alloc_size = 100;
175 struct pceplib_memory_type *pceplib_infra_ptr =
176 (struct pceplib_memory_type *)PCEPLIB_INFRA;
177 struct pceplib_memory_type *pceplib_messages_ptr =
178 (struct pceplib_memory_type *)PCEPLIB_MESSAGES;
179
180 /* reset the internal memory type counters to later verify they are NOT
181 * incremented since an external impl was provided */
182 pceplib_infra_ptr->num_allocates =
183 pceplib_infra_ptr->total_bytes_allocated =
184 pceplib_infra_ptr->num_frees =
185 pceplib_infra_ptr->total_bytes_freed = 0;
186 pceplib_messages_ptr->num_allocates =
187 pceplib_messages_ptr->total_bytes_allocated =
188 pceplib_messages_ptr->num_frees =
189 pceplib_messages_ptr->total_bytes_freed = 0;
190
191 /* Setup the external memory type */
192 struct test_memory_type infra_mt, messages_mt;
193 void *infra_ptr = &infra_mt;
194 void *messages_ptr = &messages_mt;
195 memset(infra_ptr, 0, sizeof(struct test_memory_type));
196 memset(messages_ptr, 0, sizeof(struct test_memory_type));
197 int free_counter = 1;
198
199 /* Initialize the PCEPlib memory system with an external implementation
200 */
201 pceplib_memory_initialize(infra_ptr, messages_ptr, test_pceplib_malloc,
202 test_pceplib_calloc, test_pceplib_realloc,
203 test_pceplib_strdup, test_pceplib_free);
204
205 /* Test malloc() */
206 void *ptr = pceplib_malloc(PCEPLIB_MESSAGES, alloc_size);
207 CU_ASSERT_PTR_NOT_NULL(ptr);
208 pceplib_free(PCEPLIB_MESSAGES, ptr);
209 verify_ext_memory_type(messages_ptr, 1, 0, 0, 0, free_counter++);
210
211 /* Test calloc() */
212 ptr = pceplib_calloc(PCEPLIB_MESSAGES, alloc_size);
213 CU_ASSERT_PTR_NOT_NULL(ptr);
214 pceplib_free(PCEPLIB_MESSAGES, ptr);
215 verify_ext_memory_type(messages_ptr, 1, 1, 0, 0, free_counter++);
216
217 /* Test realloc() */
218 ptr = pceplib_malloc(PCEPLIB_MESSAGES, alloc_size);
219 CU_ASSERT_PTR_NOT_NULL(ptr);
220 ptr = pceplib_realloc(PCEPLIB_MESSAGES, ptr, alloc_size);
221 CU_ASSERT_PTR_NOT_NULL(ptr);
222 pceplib_free(PCEPLIB_MESSAGES, ptr);
223 verify_ext_memory_type(messages_ptr, 2, 1, 1, 0, free_counter++);
224
225 /* Test strdup() */
226 ptr = pceplib_malloc(PCEPLIB_MESSAGES, alloc_size);
227 /* Make strdup duplicate (alloc_size - 1) bytes */
228 memset(ptr, 'a', alloc_size);
229 ((char *)ptr)[alloc_size - 1] = '\0';
230 char *str = pceplib_strdup(PCEPLIB_MESSAGES, (char *)ptr);
231 CU_ASSERT_PTR_NOT_NULL(ptr);
232 pceplib_free(PCEPLIB_MESSAGES, ptr);
233 pceplib_free(PCEPLIB_MESSAGES, str);
234 verify_ext_memory_type(messages_ptr, 3, 1, 1, 1, free_counter + 1);
235
236 /* Make sure the internal memory counters are NOT incremented */
237 verify_memory_type(pceplib_infra_ptr, 0, 0, 0, 0);
238 verify_memory_type(pceplib_messages_ptr, 0, 0, 0, 0);
239
240 verify_ext_memory_type(infra_ptr, 0, 0, 0, 0, 0);
241 }