2 * This file is part of the PCEPlib, a PCEP protocol library.
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
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.
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.
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/>.
19 * Author : Brady Johnson <brady@voltanet.io>
27 #include <CUnit/CUnit.h>
29 #include "pcep_utils_memory.h"
30 #include "pcep_utils_memory_test.h"
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
,
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
);
44 struct test_memory_type
{
47 int num_realloc_calls
;
52 void *test_pceplib_malloc(void *mem_type
, size_t size
)
54 ((struct test_memory_type
*)mem_type
)->num_malloc_calls
++;
58 void *test_pceplib_calloc(void *mem_type
, size_t size
)
60 ((struct test_memory_type
*)mem_type
)->num_calloc_calls
++;
61 return calloc(1, size
);
64 void *test_pceplib_realloc(void *mem_type
, void *ptr
, size_t size
)
66 ((struct test_memory_type
*)mem_type
)->num_realloc_calls
++;
67 return realloc(ptr
, size
);
70 void *test_pceplib_strdup(void *mem_type
, const char *str
)
72 ((struct test_memory_type
*)mem_type
)->num_strdup_calls
++;
76 void test_pceplib_free(void *mem_type
, void *ptr
)
78 ((struct test_memory_type
*)mem_type
)->num_free_calls
++;
82 void verify_memory_type(struct pceplib_memory_type
*mt
, uint32_t num_alloc
,
83 uint32_t alloc_bytes
, uint32_t num_free
,
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
);
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
)
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
);
104 void test_memory_internal_impl()
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;
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;
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
);
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
,
136 ptr
= pceplib_calloc(PCEPLIB_INFRA
, alloc_size
);
137 CU_ASSERT_PTR_NOT_NULL(ptr
);
138 pceplib_free(PCEPLIB_INFRA
, ptr
);
140 verify_memory_type(pceplib_infra_ptr
, alloc_counter
,
141 alloc_size
* alloc_counter
, free_counter
++, 0);
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
);
150 verify_memory_type(pceplib_infra_ptr
, alloc_counter
,
151 alloc_size
* alloc_counter
, free_counter
++, 0);
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
);
164 verify_memory_type(pceplib_infra_ptr
, alloc_counter
,
165 (alloc_size
* alloc_counter
) - 1, free_counter
, 0);
167 /* Make sure only the pceplib_infra_ptr memory counters are incremented
169 verify_memory_type(pceplib_messages_ptr
, 0, 0, 0, 0);
172 void test_memory_external_impl()
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
;
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;
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;
199 /* Initialize the PCEPlib memory system with an external implementation
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
);
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
++);
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
++);
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
++);
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);
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);
240 verify_ext_memory_type(infra_ptr
, 0, 0, 0, 0, 0);