1 // SPDX-License-Identifier: LGPL-2.1-or-later
3 * This file is part of the PCEPlib, a PCEP protocol library.
5 * Copyright (C) 2020 Volta Networks https://voltanet.io/
7 * Author : Brady Johnson <brady@voltanet.io>
19 #include <CUnit/CUnit.h>
21 #include "pcep_utils_memory.h"
22 #include "pcep_utils_memory_test.h"
24 void *test_pceplib_malloc(void *mem_type
, size_t size
);
25 void *test_pceplib_calloc(void *mem_type
, size_t size
);
26 void *test_pceplib_realloc(void *mem_type
, void *ptr
, size_t size
);
27 void *test_pceplib_strdup(void *mem_type
, const char *str
);
28 void test_pceplib_free(void *mem_type
, void *ptr
);
29 void verify_memory_type(struct pceplib_memory_type
*mt
, uint32_t num_alloc
,
30 uint32_t alloc_bytes
, uint32_t num_free
,
32 void verify_ext_memory_type(void *mt
, int num_malloc_calls
,
33 int num_calloc_calls
, int num_realloc_calls
,
34 int num_strdup_calls
, int num_free_calls
);
36 struct test_memory_type
{
39 int num_realloc_calls
;
44 void *test_pceplib_malloc(void *mem_type
, size_t size
)
46 ((struct test_memory_type
*)mem_type
)->num_malloc_calls
++;
50 void *test_pceplib_calloc(void *mem_type
, size_t size
)
52 ((struct test_memory_type
*)mem_type
)->num_calloc_calls
++;
53 return calloc(1, size
);
56 void *test_pceplib_realloc(void *mem_type
, void *ptr
, size_t size
)
58 ((struct test_memory_type
*)mem_type
)->num_realloc_calls
++;
59 return realloc(ptr
, size
);
62 void *test_pceplib_strdup(void *mem_type
, const char *str
)
64 ((struct test_memory_type
*)mem_type
)->num_strdup_calls
++;
68 void test_pceplib_free(void *mem_type
, void *ptr
)
70 ((struct test_memory_type
*)mem_type
)->num_free_calls
++;
74 void verify_memory_type(struct pceplib_memory_type
*mt
, uint32_t num_alloc
,
75 uint32_t alloc_bytes
, uint32_t num_free
,
78 CU_ASSERT_EQUAL(num_alloc
, mt
->num_allocates
);
79 CU_ASSERT_EQUAL(alloc_bytes
, mt
->total_bytes_allocated
);
80 CU_ASSERT_EQUAL(num_free
, mt
->num_frees
);
81 CU_ASSERT_EQUAL(free_bytes
, mt
->total_bytes_freed
);
84 void verify_ext_memory_type(void *mt
, int num_malloc_calls
,
85 int num_calloc_calls
, int num_realloc_calls
,
86 int num_strdup_calls
, int num_free_calls
)
88 struct test_memory_type
*mt_ptr
= (struct test_memory_type
*)mt
;
89 CU_ASSERT_EQUAL(num_malloc_calls
, mt_ptr
->num_malloc_calls
);
90 CU_ASSERT_EQUAL(num_calloc_calls
, mt_ptr
->num_calloc_calls
);
91 CU_ASSERT_EQUAL(num_realloc_calls
, mt_ptr
->num_realloc_calls
);
92 CU_ASSERT_EQUAL(num_strdup_calls
, mt_ptr
->num_strdup_calls
);
93 CU_ASSERT_EQUAL(num_free_calls
, mt_ptr
->num_free_calls
);
96 void test_memory_internal_impl()
99 struct pceplib_memory_type
*pceplib_infra_ptr
=
100 (struct pceplib_memory_type
*)PCEPLIB_INFRA
;
101 struct pceplib_memory_type
*pceplib_messages_ptr
=
102 (struct pceplib_memory_type
*)PCEPLIB_MESSAGES
;
103 int alloc_counter
= 1;
104 int free_counter
= 1;
106 /* reset the memory type counters for easier testing */
107 pceplib_infra_ptr
->num_allocates
=
108 pceplib_infra_ptr
->total_bytes_allocated
=
109 pceplib_infra_ptr
->num_frees
=
110 pceplib_infra_ptr
->total_bytes_freed
= 0;
111 pceplib_messages_ptr
->num_allocates
=
112 pceplib_messages_ptr
->total_bytes_allocated
=
113 pceplib_messages_ptr
->num_frees
=
114 pceplib_messages_ptr
->total_bytes_freed
= 0;
116 /* Make sure nothing crashes when all these are set NULL, since the
117 * internal default values should still be used. */
118 pceplib_memory_initialize(NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
121 void *ptr
= pceplib_malloc(PCEPLIB_INFRA
, alloc_size
);
122 CU_ASSERT_PTR_NOT_NULL(ptr
);
123 pceplib_free(PCEPLIB_INFRA
, ptr
);
124 verify_memory_type(pceplib_infra_ptr
, alloc_counter
, alloc_size
,
128 ptr
= pceplib_calloc(PCEPLIB_INFRA
, alloc_size
);
129 CU_ASSERT_PTR_NOT_NULL(ptr
);
130 pceplib_free(PCEPLIB_INFRA
, ptr
);
132 verify_memory_type(pceplib_infra_ptr
, alloc_counter
,
133 alloc_size
* alloc_counter
, free_counter
++, 0);
136 ptr
= pceplib_malloc(PCEPLIB_INFRA
, alloc_size
);
137 CU_ASSERT_PTR_NOT_NULL(ptr
);
138 ptr
= pceplib_realloc(PCEPLIB_INFRA
, ptr
, alloc_size
);
139 CU_ASSERT_PTR_NOT_NULL(ptr
);
140 pceplib_free(PCEPLIB_INFRA
, ptr
);
142 verify_memory_type(pceplib_infra_ptr
, alloc_counter
,
143 alloc_size
* alloc_counter
, free_counter
++, 0);
146 ptr
= pceplib_malloc(PCEPLIB_INFRA
, alloc_size
);
147 /* Make strdup duplicate (alloc_size - 1) bytes */
148 memset(ptr
, 'a', alloc_size
);
149 ((char *)ptr
)[alloc_size
- 1] = '\0';
150 char *str
= pceplib_strdup(PCEPLIB_INFRA
, (char *)ptr
);
151 CU_ASSERT_PTR_NOT_NULL(ptr
);
152 pceplib_free(PCEPLIB_INFRA
, ptr
);
153 pceplib_free(PCEPLIB_INFRA
, str
);
156 verify_memory_type(pceplib_infra_ptr
, alloc_counter
,
157 (alloc_size
* alloc_counter
) - 1, free_counter
, 0);
159 /* Make sure only the pceplib_infra_ptr memory counters are incremented
161 verify_memory_type(pceplib_messages_ptr
, 0, 0, 0, 0);
164 void test_memory_external_impl()
166 int alloc_size
= 100;
167 struct pceplib_memory_type
*pceplib_infra_ptr
=
168 (struct pceplib_memory_type
*)PCEPLIB_INFRA
;
169 struct pceplib_memory_type
*pceplib_messages_ptr
=
170 (struct pceplib_memory_type
*)PCEPLIB_MESSAGES
;
172 /* reset the internal memory type counters to later verify they are NOT
173 * incremented since an external impl was provided */
174 pceplib_infra_ptr
->num_allocates
=
175 pceplib_infra_ptr
->total_bytes_allocated
=
176 pceplib_infra_ptr
->num_frees
=
177 pceplib_infra_ptr
->total_bytes_freed
= 0;
178 pceplib_messages_ptr
->num_allocates
=
179 pceplib_messages_ptr
->total_bytes_allocated
=
180 pceplib_messages_ptr
->num_frees
=
181 pceplib_messages_ptr
->total_bytes_freed
= 0;
183 /* Setup the external memory type */
184 struct test_memory_type infra_mt
, messages_mt
;
185 void *infra_ptr
= &infra_mt
;
186 void *messages_ptr
= &messages_mt
;
187 memset(infra_ptr
, 0, sizeof(struct test_memory_type
));
188 memset(messages_ptr
, 0, sizeof(struct test_memory_type
));
189 int free_counter
= 1;
191 /* Initialize the PCEPlib memory system with an external implementation
193 pceplib_memory_initialize(infra_ptr
, messages_ptr
, test_pceplib_malloc
,
194 test_pceplib_calloc
, test_pceplib_realloc
,
195 test_pceplib_strdup
, test_pceplib_free
);
198 void *ptr
= pceplib_malloc(PCEPLIB_MESSAGES
, alloc_size
);
199 CU_ASSERT_PTR_NOT_NULL(ptr
);
200 pceplib_free(PCEPLIB_MESSAGES
, ptr
);
201 verify_ext_memory_type(messages_ptr
, 1, 0, 0, 0, free_counter
++);
204 ptr
= pceplib_calloc(PCEPLIB_MESSAGES
, alloc_size
);
205 CU_ASSERT_PTR_NOT_NULL(ptr
);
206 pceplib_free(PCEPLIB_MESSAGES
, ptr
);
207 verify_ext_memory_type(messages_ptr
, 1, 1, 0, 0, free_counter
++);
210 ptr
= pceplib_malloc(PCEPLIB_MESSAGES
, alloc_size
);
211 CU_ASSERT_PTR_NOT_NULL(ptr
);
212 ptr
= pceplib_realloc(PCEPLIB_MESSAGES
, ptr
, alloc_size
);
213 CU_ASSERT_PTR_NOT_NULL(ptr
);
214 pceplib_free(PCEPLIB_MESSAGES
, ptr
);
215 verify_ext_memory_type(messages_ptr
, 2, 1, 1, 0, free_counter
++);
218 ptr
= pceplib_malloc(PCEPLIB_MESSAGES
, alloc_size
);
219 /* Make strdup duplicate (alloc_size - 1) bytes */
220 memset(ptr
, 'a', alloc_size
);
221 ((char *)ptr
)[alloc_size
- 1] = '\0';
222 char *str
= pceplib_strdup(PCEPLIB_MESSAGES
, (char *)ptr
);
223 CU_ASSERT_PTR_NOT_NULL(ptr
);
224 pceplib_free(PCEPLIB_MESSAGES
, ptr
);
225 pceplib_free(PCEPLIB_MESSAGES
, str
);
226 verify_ext_memory_type(messages_ptr
, 3, 1, 1, 1, free_counter
+ 1);
228 /* Make sure the internal memory counters are NOT incremented */
229 verify_memory_type(pceplib_infra_ptr
, 0, 0, 0, 0);
230 verify_memory_type(pceplib_messages_ptr
, 0, 0, 0, 0);
232 verify_ext_memory_type(infra_ptr
, 0, 0, 0, 0, 0);